2004-12-18 19:58:32 +01:00
|
|
|
/** $MirBSD: src/bin/ksh/jobs.c,v 2.3 2004/12/18 18:58:30 tg Exp $ */
|
2004-09-21 13:57:17 +02:00
|
|
|
/* $OpenBSD: jobs.c,v 1.21 2003/11/10 21:26:39 millert Exp $ */
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Process and job control
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Reworked/Rewritten version of Eric Gisin's/Ron Natalie's code by
|
|
|
|
* Larry Bouzane (larry@cs.mun.ca) and hacked again by
|
|
|
|
* Michael Rendell (michael@cs.mun.ca)
|
|
|
|
*
|
|
|
|
* The interface to the rest of the shell should probably be changed
|
|
|
|
* to allow use of vfork() when available but that would be way too much
|
|
|
|
* work :)
|
|
|
|
*
|
|
|
|
* Notes regarding the copious ifdefs:
|
|
|
|
* - JOB_SIGS is independent of JOBS - it is defined if there are modern
|
2003-12-22 21:22:51 +01:00
|
|
|
* signal and wait routines available. This is preferred, even when
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
* JOBS is not defined, since the shell will not otherwise notice when
|
|
|
|
* background jobs die until the shell waits for a foreground process
|
|
|
|
* to die.
|
|
|
|
* - TTY_PGRP defined iff JOBS is defined - defined if there are tty
|
|
|
|
* process groups
|
|
|
|
* - NEED_PGRP_SYNC defined iff JOBS is defined - see comment below
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "sh.h"
|
|
|
|
#include "ksh_stat.h"
|
|
|
|
#include "ksh_wait.h"
|
|
|
|
#include "ksh_times.h"
|
|
|
|
#include "tty.h"
|
|
|
|
|
2004-12-18 19:58:32 +01:00
|
|
|
__RCSID("$MirBSD: src/bin/ksh/jobs.c,v 2.3 2004/12/18 18:58:30 tg Exp $");
|
2004-10-28 13:03:24 +02:00
|
|
|
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
/* Start of system configuration stuff */
|
|
|
|
|
|
|
|
/* We keep CHILD_MAX zombie processes around (exact value isn't critical) */
|
|
|
|
#ifndef CHILD_MAX
|
|
|
|
# if defined(HAVE_SYSCONF) && defined(_SC_CHILD_MAX)
|
|
|
|
# define CHILD_MAX sysconf(_SC_CHILD_MAX)
|
|
|
|
# else /* _SC_CHILD_MAX */
|
|
|
|
# ifdef _POSIX_CHILD_MAX
|
|
|
|
# define CHILD_MAX ((_POSIX_CHILD_MAX) * 2)
|
|
|
|
# else /* _POSIX_CHILD_MAX */
|
|
|
|
# define CHILD_MAX 20
|
|
|
|
# endif /* _POSIX_CHILD_MAX */
|
|
|
|
# endif /* _SC_CHILD_MAX */
|
|
|
|
#endif /* !CHILD_MAX */
|
|
|
|
|
|
|
|
#ifdef JOBS
|
|
|
|
# if defined(HAVE_TCSETPGRP) || defined(TIOCSPGRP)
|
|
|
|
# define TTY_PGRP
|
|
|
|
# endif
|
|
|
|
# ifdef BSD_PGRP
|
|
|
|
# define setpgid setpgrp
|
|
|
|
# define getpgID() getpgrp(0)
|
|
|
|
# else
|
|
|
|
# define getpgID() getpgrp()
|
|
|
|
# endif
|
|
|
|
# if defined(TTY_PGRP) && !defined(HAVE_TCSETPGRP)
|
2004-10-28 13:11:19 +02:00
|
|
|
int tcsetpgrp(int fd, pid_t grp);
|
|
|
|
int tcgetpgrp(int fd);
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
|
|
|
|
int
|
2004-10-28 13:53:44 +02:00
|
|
|
tcsetpgrp(int fd, pid_t grp)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
return ioctl(fd, TIOCSPGRP, &grp);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2004-10-28 13:53:44 +02:00
|
|
|
tcgetpgrp(int fd)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
int r, grp;
|
|
|
|
|
|
|
|
if ((r = ioctl(fd, TIOCGPGRP, &grp)) < 0)
|
|
|
|
return r;
|
|
|
|
return grp;
|
|
|
|
}
|
|
|
|
# endif /* !HAVE_TCSETPGRP && TIOCSPGRP */
|
|
|
|
#else /* JOBS */
|
|
|
|
/* These so we can use ifdef xxx instead of if defined(JOBS) && defined(xxx) */
|
|
|
|
# undef TTY_PGRP
|
|
|
|
# undef NEED_PGRP_SYNC
|
|
|
|
#endif /* JOBS */
|
|
|
|
|
|
|
|
/* End of system configuration stuff */
|
|
|
|
|
|
|
|
|
|
|
|
/* Order important! */
|
|
|
|
#define PRUNNING 0
|
|
|
|
#define PEXITED 1
|
|
|
|
#define PSIGNALLED 2
|
|
|
|
#define PSTOPPED 3
|
|
|
|
|
|
|
|
typedef struct proc Proc;
|
|
|
|
struct proc {
|
|
|
|
Proc *next; /* next process in pipeline (if any) */
|
|
|
|
int state;
|
|
|
|
WAIT_T status; /* wait status */
|
|
|
|
pid_t pid; /* process id */
|
|
|
|
char command[48]; /* process command string */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Notify/print flag - j_print() argument */
|
|
|
|
#define JP_NONE 0 /* don't print anything */
|
|
|
|
#define JP_SHORT 1 /* print signals processes were killed by */
|
|
|
|
#define JP_MEDIUM 2 /* print [job-num] -/+ command */
|
|
|
|
#define JP_LONG 3 /* print [job-num] -/+ pid command */
|
|
|
|
#define JP_PGRP 4 /* print pgrp */
|
|
|
|
|
|
|
|
/* put_job() flags */
|
|
|
|
#define PJ_ON_FRONT 0 /* at very front */
|
|
|
|
#define PJ_PAST_STOPPED 1 /* just past any stopped jobs */
|
|
|
|
|
|
|
|
/* Job.flags values */
|
|
|
|
#define JF_STARTED 0x001 /* set when all processes in job are started */
|
|
|
|
#define JF_WAITING 0x002 /* set if j_waitj() is waiting on job */
|
|
|
|
#define JF_W_ASYNCNOTIFY 0x004 /* set if waiting and async notification ok */
|
|
|
|
#define JF_XXCOM 0x008 /* set for `command` jobs */
|
|
|
|
#define JF_FG 0x010 /* running in foreground (also has tty pgrp) */
|
|
|
|
#define JF_SAVEDTTY 0x020 /* j->ttystate is valid */
|
|
|
|
#define JF_CHANGED 0x040 /* process has changed state */
|
|
|
|
#define JF_KNOWN 0x080 /* $! referenced */
|
|
|
|
#define JF_ZOMBIE 0x100 /* known, unwaited process */
|
2003-12-22 21:22:51 +01:00
|
|
|
#define JF_REMOVE 0x200 /* flagged for removal (j_jobs()/j_noityf()) */
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
#define JF_USETTYMODE 0x400 /* tty mode saved if process exits normally */
|
|
|
|
#define JF_SAVEDTTYPGRP 0x800 /* j->saved_ttypgrp is valid */
|
|
|
|
|
|
|
|
typedef struct job Job;
|
|
|
|
struct job {
|
|
|
|
Job *next; /* next job in list */
|
|
|
|
int job; /* job number: %n */
|
|
|
|
int flags; /* see JF_* */
|
|
|
|
int state; /* job state */
|
|
|
|
int status; /* exit status of last process */
|
|
|
|
pid_t pgrp; /* process group of job */
|
|
|
|
pid_t ppid; /* pid of process that forked job */
|
|
|
|
INT32 age; /* number of jobs started */
|
|
|
|
clock_t systime; /* system time used by job */
|
|
|
|
clock_t usrtime; /* user time used by job */
|
|
|
|
Proc *proc_list; /* process list */
|
|
|
|
Proc *last_proc; /* last process in list */
|
|
|
|
Coproc_id coproc_id; /* 0 or id of coprocess output pipe */
|
|
|
|
#ifdef TTY_PGRP
|
|
|
|
TTY_state ttystate; /* saved tty state for stopped jobs */
|
|
|
|
pid_t saved_ttypgrp; /* saved tty process group for stopped jobs */
|
|
|
|
#endif /* TTY_PGRP */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Flags for j_waitj() */
|
|
|
|
#define JW_NONE 0x00
|
|
|
|
#define JW_INTERRUPT 0x01 /* ^C will stop the wait */
|
|
|
|
#define JW_ASYNCNOTIFY 0x02 /* asynchronous notification during wait ok */
|
|
|
|
#define JW_STOPPEDWAIT 0x04 /* wait even if job stopped */
|
|
|
|
|
|
|
|
/* Error codes for j_lookup() */
|
|
|
|
#define JL_OK 0
|
|
|
|
#define JL_NOSUCH 1 /* no such job */
|
|
|
|
#define JL_AMBIG 2 /* %foo or %?foo is ambiguous */
|
|
|
|
#define JL_INVALID 3 /* non-pid, non-% job id */
|
|
|
|
|
|
|
|
static const char *const lookup_msgs[] = {
|
|
|
|
null,
|
|
|
|
"no such job",
|
|
|
|
"ambiguous",
|
|
|
|
"argument must be %job or process id",
|
|
|
|
(char *) 0
|
|
|
|
};
|
|
|
|
clock_t j_systime, j_usrtime; /* user and system time of last j_waitjed job */
|
|
|
|
|
|
|
|
static Job *job_list; /* job list */
|
|
|
|
static Job *last_job;
|
|
|
|
static Job *async_job;
|
|
|
|
static pid_t async_pid;
|
|
|
|
|
|
|
|
static int nzombie; /* # of zombies owned by this process */
|
|
|
|
static INT32 njobs; /* # of jobs started */
|
|
|
|
static int child_max; /* CHILD_MAX */
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
/* held_sigchld is set if sigchld occurs before a job is completely started */
|
|
|
|
static int held_sigchld;
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
|
|
|
|
#ifdef JOBS
|
|
|
|
static struct shf *shl_j;
|
|
|
|
#endif /* JOBS */
|
|
|
|
|
|
|
|
#ifdef NEED_PGRP_SYNC
|
|
|
|
/* On some systems, the kernel doesn't count zombie processes when checking
|
|
|
|
* if a process group is valid, which can cause problems in creating the
|
|
|
|
* pipeline "cmd1 | cmd2": if cmd1 can die (and go into the zombie state)
|
|
|
|
* before cmd2 is started, the kernel doesn't allow the setpgid() for cmd2
|
|
|
|
* to succeed. Solution is to create a pipe between the parent and the first
|
|
|
|
* process; the first process doesn't do anything until the pipe is closed
|
|
|
|
* and the parent doesn't close the pipe until all the processes are started.
|
|
|
|
*/
|
|
|
|
static int j_sync_pipe[2];
|
|
|
|
static int j_sync_open;
|
|
|
|
#endif /* NEED_PGRP_SYNC */
|
|
|
|
|
|
|
|
#ifdef TTY_PGRP
|
|
|
|
static int ttypgrp_ok; /* set if can use tty pgrps */
|
|
|
|
static pid_t restore_ttypgrp = -1;
|
|
|
|
static pid_t our_pgrp;
|
|
|
|
static int const tt_sigs[] = { SIGTSTP, SIGTTIN, SIGTTOU };
|
|
|
|
#endif /* TTY_PGRP */
|
|
|
|
|
2004-10-28 13:11:19 +02:00
|
|
|
static void j_set_async(Job *j);
|
|
|
|
static void j_startjob(Job *j);
|
|
|
|
static int j_waitj(Job *j, int flags, const char *where);
|
|
|
|
static RETSIGTYPE j_sigchld(int sig);
|
|
|
|
static void j_print(Job *j, int how, struct shf *shf);
|
|
|
|
static Job *j_lookup(const char *cp, int *ecodep);
|
|
|
|
static Job *new_job(void);
|
|
|
|
static Proc *new_proc(void);
|
|
|
|
static void check_job(Job *j);
|
|
|
|
static void put_job(Job *j, int where);
|
|
|
|
static void remove_job(Job *j, const char *where);
|
|
|
|
static int kill_job(Job *j, int sig);
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
|
|
|
|
/* initialize job control */
|
|
|
|
void
|
2004-10-28 13:53:44 +02:00
|
|
|
j_init(int mflagset)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
child_max = CHILD_MAX; /* so syscon() isn't always being called */
|
|
|
|
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigemptyset(&sm_default);
|
|
|
|
sigprocmask(SIG_SETMASK, &sm_default, (sigset_t *) 0);
|
|
|
|
|
|
|
|
sigemptyset(&sm_sigchld);
|
|
|
|
sigaddset(&sm_sigchld, SIGCHLD);
|
|
|
|
|
|
|
|
setsig(&sigtraps[SIGCHLD], j_sigchld,
|
|
|
|
SS_RESTORE_ORIG|SS_FORCE|SS_SHTRAP);
|
|
|
|
#else /* JOB_SIGS */
|
|
|
|
/* Make sure SIGCHLD isn't ignored - can do odd things under SYSV */
|
|
|
|
setsig(&sigtraps[SIGCHLD], SIG_DFL, SS_RESTORE_ORIG|SS_FORCE);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
|
|
|
|
#ifdef JOBS
|
|
|
|
if (!mflagset && Flag(FTALKING))
|
|
|
|
Flag(FMONITOR) = 1;
|
|
|
|
|
|
|
|
/* shl_j is used to do asynchronous notification (used in
|
|
|
|
* an interrupt handler, so need a distinct shf)
|
|
|
|
*/
|
|
|
|
shl_j = shf_fdopen(2, SHF_WR, (struct shf *) 0);
|
|
|
|
|
|
|
|
# ifdef TTY_PGRP
|
|
|
|
if (Flag(FMONITOR) || Flag(FTALKING)) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* the TF_SHELL_USES test is a kludge that lets us know if
|
|
|
|
* if the signals have been changed by the shell.
|
|
|
|
*/
|
|
|
|
for (i = NELEM(tt_sigs); --i >= 0; ) {
|
|
|
|
sigtraps[tt_sigs[i]].flags |= TF_SHELL_USES;
|
|
|
|
/* j_change() sets this to SS_RESTORE_DFL if FMONITOR */
|
|
|
|
setsig(&sigtraps[tt_sigs[i]], SIG_IGN,
|
|
|
|
SS_RESTORE_IGN|SS_FORCE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# endif /* TTY_PGRP */
|
|
|
|
|
|
|
|
/* j_change() calls tty_init() */
|
|
|
|
if (Flag(FMONITOR))
|
|
|
|
j_change();
|
|
|
|
else
|
|
|
|
#endif /* JOBS */
|
|
|
|
if (Flag(FTALKING))
|
|
|
|
tty_init(TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* job cleanup before shell exit */
|
|
|
|
void
|
2004-10-28 13:53:44 +02:00
|
|
|
j_exit(void)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
/* kill stopped, and possibly running, jobs */
|
|
|
|
Job *j;
|
|
|
|
int killed = 0;
|
|
|
|
|
|
|
|
for (j = job_list; j != (Job *) 0; j = j->next) {
|
|
|
|
if (j->ppid == procpid
|
|
|
|
&& (j->state == PSTOPPED
|
|
|
|
|| (j->state == PRUNNING
|
|
|
|
&& ((j->flags & JF_FG)
|
|
|
|
|| (Flag(FLOGIN) && !Flag(FNOHUP)
|
|
|
|
&& procpid == kshpid)))))
|
|
|
|
{
|
|
|
|
killed = 1;
|
|
|
|
if (j->pgrp == 0)
|
|
|
|
kill_job(j, SIGHUP);
|
|
|
|
else
|
|
|
|
killpg(j->pgrp, SIGHUP);
|
|
|
|
#ifdef JOBS
|
|
|
|
if (j->state == PSTOPPED) {
|
|
|
|
if (j->pgrp == 0)
|
|
|
|
kill_job(j, SIGCONT);
|
|
|
|
else
|
|
|
|
killpg(j->pgrp, SIGCONT);
|
|
|
|
}
|
|
|
|
#endif /* JOBS */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (killed)
|
|
|
|
sleep(1);
|
|
|
|
j_notify();
|
|
|
|
|
|
|
|
#ifdef JOBS
|
|
|
|
# ifdef TTY_PGRP
|
|
|
|
if (kshpid == procpid && restore_ttypgrp >= 0) {
|
|
|
|
/* Need to restore the tty pgrp to what it was when the
|
|
|
|
* shell started up, so that the process that started us
|
|
|
|
* will be able to access the tty when we are done.
|
|
|
|
* Also need to restore our process group in case we are
|
|
|
|
* about to do an exec so that both our parent and the
|
|
|
|
* process we are to become will be able to access the tty.
|
|
|
|
*/
|
|
|
|
tcsetpgrp(tty_fd, restore_ttypgrp);
|
|
|
|
setpgid(0, restore_ttypgrp);
|
|
|
|
}
|
|
|
|
# endif /* TTY_PGRP */
|
|
|
|
if (Flag(FMONITOR)) {
|
|
|
|
Flag(FMONITOR) = 0;
|
|
|
|
j_change();
|
|
|
|
}
|
|
|
|
#endif /* JOBS */
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef JOBS
|
|
|
|
/* turn job control on or off according to Flag(FMONITOR) */
|
|
|
|
void
|
2004-10-28 13:53:44 +02:00
|
|
|
j_change(void)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (Flag(FMONITOR)) {
|
|
|
|
/* Don't call get_tty() 'til we own the tty process group */
|
|
|
|
tty_init(FALSE);
|
|
|
|
|
|
|
|
# ifdef TTY_PGRP
|
|
|
|
/* no controlling tty, no SIGT* */
|
|
|
|
ttypgrp_ok = tty_fd >= 0 && tty_devtty;
|
|
|
|
|
|
|
|
if (ttypgrp_ok && (our_pgrp = getpgID()) < 0) {
|
|
|
|
warningf(FALSE, "j_init: getpgrp() failed: %s",
|
|
|
|
strerror(errno));
|
|
|
|
ttypgrp_ok = 0;
|
|
|
|
}
|
|
|
|
if (ttypgrp_ok) {
|
|
|
|
setsig(&sigtraps[SIGTTIN], SIG_DFL,
|
|
|
|
SS_RESTORE_ORIG|SS_FORCE);
|
|
|
|
/* wait to be given tty (POSIX.1, B.2, job control) */
|
|
|
|
while (1) {
|
|
|
|
pid_t ttypgrp;
|
|
|
|
|
|
|
|
if ((ttypgrp = tcgetpgrp(tty_fd)) < 0) {
|
|
|
|
warningf(FALSE,
|
|
|
|
"j_init: tcgetpgrp() failed: %s",
|
|
|
|
strerror(errno));
|
|
|
|
ttypgrp_ok = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (ttypgrp == our_pgrp)
|
|
|
|
break;
|
|
|
|
kill(0, SIGTTIN);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (i = NELEM(tt_sigs); --i >= 0; )
|
|
|
|
setsig(&sigtraps[tt_sigs[i]], SIG_IGN,
|
|
|
|
SS_RESTORE_DFL|SS_FORCE);
|
|
|
|
if (ttypgrp_ok && our_pgrp != kshpid) {
|
|
|
|
if (setpgid(0, kshpid) < 0) {
|
|
|
|
warningf(FALSE,
|
|
|
|
"j_init: setpgid() failed: %s",
|
|
|
|
strerror(errno));
|
|
|
|
ttypgrp_ok = 0;
|
|
|
|
} else {
|
|
|
|
if (tcsetpgrp(tty_fd, kshpid) < 0) {
|
|
|
|
warningf(FALSE,
|
|
|
|
"j_init: tcsetpgrp() failed: %s",
|
|
|
|
strerror(errno));
|
|
|
|
ttypgrp_ok = 0;
|
|
|
|
} else
|
|
|
|
restore_ttypgrp = our_pgrp;
|
|
|
|
our_pgrp = kshpid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# if defined(NTTYDISC) && defined(TIOCSETD) && !defined(HAVE_TERMIOS_H) && !defined(HAVE_TERMIO_H)
|
|
|
|
if (ttypgrp_ok) {
|
|
|
|
int ldisc = NTTYDISC;
|
|
|
|
|
|
|
|
if (ioctl(tty_fd, TIOCSETD, &ldisc) < 0)
|
|
|
|
warningf(FALSE,
|
|
|
|
"j_init: can't set new line discipline: %s",
|
|
|
|
strerror(errno));
|
|
|
|
}
|
|
|
|
# endif /* NTTYDISC && TIOCSETD */
|
|
|
|
if (!ttypgrp_ok)
|
|
|
|
warningf(FALSE, "warning: won't have full job control");
|
|
|
|
# endif /* TTY_PGRP */
|
|
|
|
if (tty_fd >= 0)
|
|
|
|
get_tty(tty_fd, &tty_state);
|
|
|
|
} else {
|
|
|
|
# ifdef TTY_PGRP
|
|
|
|
ttypgrp_ok = 0;
|
|
|
|
if (Flag(FTALKING))
|
|
|
|
for (i = NELEM(tt_sigs); --i >= 0; )
|
|
|
|
setsig(&sigtraps[tt_sigs[i]], SIG_IGN,
|
|
|
|
SS_RESTORE_IGN|SS_FORCE);
|
|
|
|
else
|
|
|
|
for (i = NELEM(tt_sigs); --i >= 0; ) {
|
|
|
|
if (sigtraps[tt_sigs[i]].flags & (TF_ORIG_IGN
|
|
|
|
|TF_ORIG_DFL))
|
|
|
|
setsig(&sigtraps[tt_sigs[i]],
|
|
|
|
(sigtraps[tt_sigs[i]].flags & TF_ORIG_IGN) ? SIG_IGN : SIG_DFL,
|
|
|
|
SS_RESTORE_ORIG|SS_FORCE);
|
|
|
|
}
|
|
|
|
# endif /* TTY_PGRP */
|
|
|
|
if (!Flag(FTALKING))
|
|
|
|
tty_close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* JOBS */
|
|
|
|
|
|
|
|
/* execute tree in child subprocess */
|
|
|
|
int
|
2004-10-28 13:53:44 +02:00
|
|
|
exchild(struct op *t, int flags, int close_fd)
|
|
|
|
|
|
|
|
|
|
|
|
/* used if XPCLOSE or XCCLOSE */
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
static Proc *last_proc; /* for pipelines */
|
|
|
|
|
|
|
|
int i;
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigset_t omask;
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
Proc *p;
|
|
|
|
Job *j;
|
|
|
|
int rv = 0;
|
|
|
|
int forksleep;
|
|
|
|
int ischild;
|
|
|
|
|
|
|
|
if (flags & XEXEC)
|
|
|
|
/* Clear XFORK|XPCLOSE|XCCLOSE|XCOPROC|XPIPEO|XPIPEI|XXCOM|XBGND
|
|
|
|
* (also done in another execute() below)
|
|
|
|
*/
|
|
|
|
return execute(t, flags & (XEXEC | XERROK));
|
|
|
|
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
/* no SIGCHLD's while messing with job and process lists */
|
|
|
|
sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
|
|
|
|
p = new_proc();
|
|
|
|
p->next = (Proc *) 0;
|
|
|
|
p->state = PRUNNING;
|
|
|
|
WSTATUS(p->status) = 0;
|
|
|
|
p->pid = 0;
|
|
|
|
|
|
|
|
/* link process into jobs list */
|
|
|
|
if (flags&XPIPEI) { /* continuing with a pipe */
|
|
|
|
if (!last_job)
|
|
|
|
internal_errorf(1, "exchild: XPIPEI and no last_job - pid %d", (int) procpid);
|
|
|
|
j = last_job;
|
|
|
|
last_proc->next = p;
|
|
|
|
last_proc = p;
|
|
|
|
} else {
|
|
|
|
#ifdef NEED_PGRP_SYNC
|
|
|
|
if (j_sync_open) { /* should never happen */
|
|
|
|
j_sync_open = 0;
|
|
|
|
closepipe(j_sync_pipe);
|
|
|
|
}
|
|
|
|
/* don't do the sync pipe business if there is no pipeline */
|
|
|
|
if (flags & XPIPEO) {
|
|
|
|
openpipe(j_sync_pipe);
|
|
|
|
j_sync_open = 1;
|
|
|
|
}
|
|
|
|
#endif /* NEED_PGRP_SYNC */
|
|
|
|
j = new_job(); /* fills in j->job */
|
|
|
|
/* we don't consider XXCOM's foreground since they don't get
|
|
|
|
* tty process group and we don't save or restore tty modes.
|
|
|
|
*/
|
|
|
|
j->flags = (flags & XXCOM) ? JF_XXCOM
|
|
|
|
: ((flags & XBGND) ? 0 : (JF_FG|JF_USETTYMODE));
|
|
|
|
j->usrtime = j->systime = 0;
|
|
|
|
j->state = PRUNNING;
|
|
|
|
j->pgrp = 0;
|
|
|
|
j->ppid = procpid;
|
|
|
|
j->age = ++njobs;
|
|
|
|
j->proc_list = p;
|
|
|
|
j->coproc_id = 0;
|
|
|
|
last_job = j;
|
|
|
|
last_proc = p;
|
|
|
|
put_job(j, PJ_PAST_STOPPED);
|
|
|
|
}
|
|
|
|
|
|
|
|
snptreef(p->command, sizeof(p->command), "%T", t);
|
|
|
|
|
|
|
|
/* create child process */
|
|
|
|
forksleep = 1;
|
|
|
|
while ((i = fork()) < 0 && errno == EAGAIN && forksleep < 32) {
|
|
|
|
if (intrsig) /* allow user to ^C out... */
|
|
|
|
break;
|
|
|
|
sleep(forksleep);
|
|
|
|
forksleep <<= 1;
|
|
|
|
}
|
|
|
|
if (i < 0) {
|
|
|
|
kill_job(j, SIGKILL);
|
|
|
|
remove_job(j, "fork failed");
|
|
|
|
#ifdef NEED_PGRP_SYNC
|
|
|
|
if (j_sync_open) {
|
|
|
|
closepipe(j_sync_pipe);
|
|
|
|
j_sync_open = 0;
|
|
|
|
}
|
|
|
|
#endif /* NEED_PGRP_SYNC */
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
errorf("cannot fork - try again");
|
|
|
|
}
|
|
|
|
ischild = i == 0;
|
|
|
|
if (ischild)
|
|
|
|
p->pid = procpid = getpid();
|
|
|
|
else
|
|
|
|
p->pid = i;
|
|
|
|
|
|
|
|
#ifdef JOBS
|
|
|
|
/* job control set up */
|
|
|
|
if (Flag(FMONITOR) && !(flags&XXCOM)) {
|
|
|
|
int dotty = 0;
|
|
|
|
# ifdef NEED_PGRP_SYNC
|
|
|
|
int first_child_sync = 0;
|
|
|
|
# endif /* NEED_PGRP_SYNC */
|
|
|
|
|
|
|
|
# ifdef NEED_PGRP_SYNC
|
|
|
|
if (j_sync_open) {
|
|
|
|
/*
|
|
|
|
* The Parent closes 0, keeps 1 open 'til the whole
|
|
|
|
* pipeline is started. The First child closes 1,
|
|
|
|
* keeps 0 open (reads from it). The remaining
|
|
|
|
* children just have to close 1 (parent has already
|
|
|
|
* closeed 0).
|
|
|
|
*/
|
|
|
|
if (j->pgrp == 0) { /* First process */
|
|
|
|
close(j_sync_pipe[ischild]);
|
|
|
|
j_sync_pipe[ischild] = -1;
|
|
|
|
first_child_sync = ischild;
|
|
|
|
} else if (ischild) {
|
|
|
|
j_sync_open = 0;
|
|
|
|
closepipe(j_sync_pipe);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# endif /* NEED_PGRP_SYNC */
|
|
|
|
if (j->pgrp == 0) { /* First process */
|
|
|
|
j->pgrp = p->pid;
|
|
|
|
dotty = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set pgrp in both parent and child to deal with race
|
|
|
|
* condition
|
|
|
|
*/
|
|
|
|
setpgid(p->pid, j->pgrp);
|
|
|
|
# ifdef TTY_PGRP
|
|
|
|
/* YYY: should this be
|
|
|
|
if (ttypgrp_ok && ischild && !(flags&XBGND))
|
|
|
|
tcsetpgrp(tty_fd, j->pgrp);
|
|
|
|
instead? (see also YYY below)
|
|
|
|
*/
|
|
|
|
if (ttypgrp_ok && dotty && !(flags & XBGND))
|
|
|
|
tcsetpgrp(tty_fd, j->pgrp);
|
|
|
|
# endif /* TTY_PGRP */
|
|
|
|
# ifdef NEED_PGRP_SYNC
|
|
|
|
if (first_child_sync) {
|
|
|
|
char c;
|
|
|
|
while (read(j_sync_pipe[0], &c, 1) == -1
|
|
|
|
&& errno == EINTR)
|
|
|
|
;
|
|
|
|
close(j_sync_pipe[0]);
|
|
|
|
j_sync_open = 0;
|
|
|
|
}
|
|
|
|
# endif /* NEED_PGRP_SYNC */
|
|
|
|
}
|
|
|
|
#endif /* JOBS */
|
|
|
|
|
|
|
|
/* used to close pipe input fd */
|
|
|
|
if (close_fd >= 0 && (((flags & XPCLOSE) && !ischild)
|
|
|
|
|| ((flags & XCCLOSE) && ischild)))
|
|
|
|
close(close_fd);
|
|
|
|
if (ischild) { /* child */
|
|
|
|
/* Do this before restoring signal */
|
|
|
|
if (flags & XCOPROC)
|
|
|
|
coproc_cleanup(FALSE);
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
cleanup_parents_env();
|
|
|
|
#ifdef TTY_PGRP
|
|
|
|
/* If FMONITOR or FTALKING is set, these signals are ignored,
|
|
|
|
* if neither FMONITOR nor FTALKING are set, the signals have
|
|
|
|
* their inherited values.
|
|
|
|
*/
|
|
|
|
if (Flag(FMONITOR) && !(flags & XXCOM)) {
|
|
|
|
for (i = NELEM(tt_sigs); --i >= 0; )
|
|
|
|
setsig(&sigtraps[tt_sigs[i]], SIG_DFL,
|
|
|
|
SS_RESTORE_DFL|SS_FORCE);
|
|
|
|
}
|
|
|
|
#endif /* TTY_PGRP */
|
|
|
|
#ifdef HAVE_NICE
|
|
|
|
if (Flag(FBGNICE) && (flags & XBGND))
|
|
|
|
nice(4);
|
|
|
|
#endif /* HAVE_NICE */
|
|
|
|
if ((flags & XBGND) && !Flag(FMONITOR)) {
|
|
|
|
setsig(&sigtraps[SIGINT], SIG_IGN,
|
|
|
|
SS_RESTORE_IGN|SS_FORCE);
|
|
|
|
setsig(&sigtraps[SIGQUIT], SIG_IGN,
|
|
|
|
SS_RESTORE_IGN|SS_FORCE);
|
|
|
|
if (!(flags & (XPIPEI | XCOPROC))) {
|
|
|
|
int fd = open("/dev/null", 0);
|
2003-12-22 21:22:51 +01:00
|
|
|
if (fd != 0) {
|
|
|
|
(void) ksh_dup2(fd, 0, TRUE);
|
|
|
|
close(fd);
|
|
|
|
}
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
}
|
|
|
|
}
|
2004-04-17 02:47:20 +02:00
|
|
|
remove_job(j, "child"); /* in case of 'jobs' command */
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
nzombie = 0;
|
|
|
|
#ifdef JOBS
|
|
|
|
ttypgrp_ok = 0;
|
|
|
|
Flag(FMONITOR) = 0;
|
|
|
|
#endif /* JOBS */
|
|
|
|
Flag(FTALKING) = 0;
|
|
|
|
tty_close();
|
|
|
|
cleartraps();
|
|
|
|
execute(t, (flags & XERROK) | XEXEC); /* no return */
|
|
|
|
internal_errorf(0, "exchild: execute() returned");
|
|
|
|
unwind(LLEAVE);
|
|
|
|
/* NOTREACHED */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* shell (parent) stuff */
|
|
|
|
/* Ensure next child gets a (slightly) different $RANDOM sequence */
|
|
|
|
change_random();
|
|
|
|
if (!(flags & XPIPEO)) { /* last process in a job */
|
|
|
|
#ifdef TTY_PGRP
|
|
|
|
/* YYY: Is this needed? (see also YYY above)
|
|
|
|
if (Flag(FMONITOR) && !(flags&(XXCOM|XBGND)))
|
|
|
|
tcsetpgrp(tty_fd, j->pgrp);
|
|
|
|
*/
|
|
|
|
#endif /* TTY_PGRP */
|
|
|
|
j_startjob(j);
|
|
|
|
if (flags & XCOPROC) {
|
|
|
|
j->coproc_id = coproc.id;
|
|
|
|
coproc.njobs++; /* n jobs using co-process output */
|
|
|
|
coproc.job = (void *) j; /* j using co-process input */
|
|
|
|
}
|
|
|
|
if (flags & XBGND) {
|
|
|
|
j_set_async(j);
|
|
|
|
if (Flag(FTALKING)) {
|
|
|
|
shf_fprintf(shl_out, "[%d]", j->job);
|
|
|
|
for (p = j->proc_list; p; p = p->next)
|
|
|
|
shf_fprintf(shl_out, " %d", p->pid);
|
|
|
|
shf_putchar('\n', shl_out);
|
|
|
|
shf_flush(shl_out);
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
rv = j_waitj(j, JW_NONE, "jw:last proc");
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* start the last job: only used for `command` jobs */
|
|
|
|
void
|
2004-10-28 13:53:44 +02:00
|
|
|
startlast(void)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigset_t omask;
|
|
|
|
|
|
|
|
sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
|
|
|
|
if (last_job) { /* no need to report error - waitlast() will do it */
|
|
|
|
/* ensure it isn't removed by check_job() */
|
|
|
|
last_job->flags |= JF_WAITING;
|
|
|
|
j_startjob(last_job);
|
|
|
|
}
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* wait for last job: only used for `command` jobs */
|
|
|
|
int
|
2004-10-28 13:53:44 +02:00
|
|
|
waitlast(void)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
Job *j;
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigset_t omask;
|
|
|
|
|
|
|
|
sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
|
|
|
|
j = last_job;
|
|
|
|
if (!j || !(j->flags & JF_STARTED)) {
|
|
|
|
if (!j)
|
|
|
|
warningf(TRUE, "waitlast: no last job");
|
|
|
|
else
|
|
|
|
internal_errorf(0, "waitlast: not started");
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
return 125; /* not so arbitrary, non-zero value */
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = j_waitj(j, JW_NONE, "jw:waitlast");
|
|
|
|
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* wait for child, interruptable. */
|
|
|
|
int
|
2004-10-28 13:53:44 +02:00
|
|
|
waitfor(const char *cp, int *sigp)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
Job *j;
|
|
|
|
int ecode;
|
|
|
|
int flags = JW_INTERRUPT|JW_ASYNCNOTIFY;
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigset_t omask;
|
|
|
|
|
|
|
|
sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
|
|
|
|
*sigp = 0;
|
|
|
|
|
|
|
|
if (cp == (char *) 0) {
|
|
|
|
/* wait for an unspecified job - always returns 0, so
|
|
|
|
* don't have to worry about exited/signaled jobs
|
|
|
|
*/
|
|
|
|
for (j = job_list; j; j = j->next)
|
|
|
|
/* at&t ksh will wait for stopped jobs - we don't */
|
|
|
|
if (j->ppid == procpid && j->state == PRUNNING)
|
|
|
|
break;
|
|
|
|
if (!j) {
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else if ((j = j_lookup(cp, &ecode))) {
|
|
|
|
/* don't report normal job completion */
|
|
|
|
flags &= ~JW_ASYNCNOTIFY;
|
|
|
|
if (j->ppid != procpid) {
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
if (ecode != JL_NOSUCH)
|
|
|
|
bi_errorf("%s: %s", cp, lookup_msgs[ecode]);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* at&t ksh will wait for stopped jobs - we don't */
|
|
|
|
rv = j_waitj(j, flags, "jw:waitfor");
|
|
|
|
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
|
|
|
|
if (rv < 0) /* we were interrupted */
|
|
|
|
*sigp = 128 + -rv;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* kill (built-in) a job */
|
|
|
|
int
|
2004-10-28 13:53:44 +02:00
|
|
|
j_kill(const char *cp, int sig)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
Job *j;
|
|
|
|
int rv = 0;
|
|
|
|
int ecode;
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigset_t omask;
|
|
|
|
|
|
|
|
sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
|
|
|
|
if ((j = j_lookup(cp, &ecode)) == (Job *) 0) {
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
bi_errorf("%s: %s", cp, lookup_msgs[ecode]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (j->pgrp == 0) { /* started when !Flag(FMONITOR) */
|
|
|
|
if (kill_job(j, sig) < 0) {
|
|
|
|
bi_errorf("%s: %s", cp, strerror(errno));
|
|
|
|
rv = 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
#ifdef JOBS
|
|
|
|
if (j->state == PSTOPPED && (sig == SIGTERM || sig == SIGHUP))
|
|
|
|
(void) killpg(j->pgrp, SIGCONT);
|
|
|
|
#endif /* JOBS */
|
|
|
|
if (killpg(j->pgrp, sig) < 0) {
|
|
|
|
bi_errorf("%s: %s", cp, strerror(errno));
|
|
|
|
rv = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef JOBS
|
|
|
|
/* fg and bg built-ins: called only if Flag(FMONITOR) set */
|
|
|
|
int
|
2004-10-28 13:53:44 +02:00
|
|
|
j_resume(const char *cp, int bg)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
Job *j;
|
|
|
|
Proc *p;
|
|
|
|
int ecode;
|
|
|
|
int running;
|
|
|
|
int rv = 0;
|
|
|
|
sigset_t omask;
|
|
|
|
|
|
|
|
sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
|
|
|
|
|
|
|
|
if ((j = j_lookup(cp, &ecode)) == (Job *) 0) {
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
bi_errorf("%s: %s", cp, lookup_msgs[ecode]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (j->pgrp == 0) {
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
bi_errorf("job not job-controlled");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bg)
|
|
|
|
shprintf("[%d] ", j->job);
|
|
|
|
|
|
|
|
running = 0;
|
|
|
|
for (p = j->proc_list; p != (Proc *) 0; p = p->next) {
|
|
|
|
if (p->state == PSTOPPED) {
|
|
|
|
p->state = PRUNNING;
|
|
|
|
WSTATUS(p->status) = 0;
|
|
|
|
running = 1;
|
|
|
|
}
|
|
|
|
shprintf("%s%s", p->command, p->next ? "| " : null);
|
|
|
|
}
|
|
|
|
shprintf(newline);
|
|
|
|
shf_flush(shl_stdout);
|
|
|
|
if (running)
|
|
|
|
j->state = PRUNNING;
|
|
|
|
|
|
|
|
put_job(j, PJ_PAST_STOPPED);
|
|
|
|
if (bg)
|
|
|
|
j_set_async(j);
|
|
|
|
else {
|
|
|
|
# ifdef TTY_PGRP
|
|
|
|
/* attach tty to job */
|
|
|
|
if (j->state == PRUNNING) {
|
|
|
|
if (ttypgrp_ok && (j->flags & JF_SAVEDTTY)) {
|
|
|
|
set_tty(tty_fd, &j->ttystate, TF_NONE);
|
|
|
|
}
|
|
|
|
/* See comment in j_waitj regarding saved_ttypgrp. */
|
|
|
|
if (ttypgrp_ok && tcsetpgrp(tty_fd, (j->flags & JF_SAVEDTTYPGRP) ? j->saved_ttypgrp : j->pgrp) < 0) {
|
|
|
|
if (j->flags & JF_SAVEDTTY) {
|
|
|
|
set_tty(tty_fd, &tty_state, TF_NONE);
|
|
|
|
}
|
|
|
|
sigprocmask(SIG_SETMASK, &omask,
|
|
|
|
(sigset_t *) 0);
|
|
|
|
bi_errorf("1st tcsetpgrp(%d, %d) failed: %s",
|
|
|
|
tty_fd, (int) ((j->flags & JF_SAVEDTTYPGRP) ? j->saved_ttypgrp : j->pgrp), strerror(errno));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# endif /* TTY_PGRP */
|
|
|
|
j->flags |= JF_FG;
|
|
|
|
j->flags &= ~JF_KNOWN;
|
|
|
|
if (j == async_job)
|
|
|
|
async_job = (Job *) 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (j->state == PRUNNING && killpg(j->pgrp, SIGCONT) < 0) {
|
|
|
|
int err = errno;
|
|
|
|
|
|
|
|
if (!bg) {
|
|
|
|
j->flags &= ~JF_FG;
|
|
|
|
# ifdef TTY_PGRP
|
|
|
|
if (ttypgrp_ok && (j->flags & JF_SAVEDTTY)) {
|
|
|
|
set_tty(tty_fd, &tty_state, TF_NONE);
|
|
|
|
}
|
|
|
|
if (ttypgrp_ok && tcsetpgrp(tty_fd, our_pgrp) < 0) {
|
|
|
|
warningf(TRUE,
|
|
|
|
"fg: 2nd tcsetpgrp(%d, %d) failed: %s",
|
|
|
|
tty_fd, (int) our_pgrp,
|
|
|
|
strerror(errno));
|
|
|
|
}
|
|
|
|
# endif /* TTY_PGRP */
|
|
|
|
}
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
bi_errorf("cannot continue job %s: %s",
|
|
|
|
cp, strerror(err));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (!bg) {
|
|
|
|
# ifdef TTY_PGRP
|
|
|
|
if (ttypgrp_ok) {
|
|
|
|
j->flags &= ~(JF_SAVEDTTY | JF_SAVEDTTYPGRP);
|
|
|
|
}
|
|
|
|
# endif /* TTY_PGRP */
|
|
|
|
rv = j_waitj(j, JW_NONE, "jw:resume");
|
|
|
|
}
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
#endif /* JOBS */
|
|
|
|
|
|
|
|
/* are there any running or stopped jobs ? */
|
|
|
|
int
|
2004-10-28 13:53:44 +02:00
|
|
|
j_stopped_running(void)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
Job *j;
|
|
|
|
int which = 0;
|
|
|
|
|
|
|
|
for (j = job_list; j != (Job *) 0; j = j->next) {
|
|
|
|
#ifdef JOBS
|
|
|
|
if (j->ppid == procpid && j->state == PSTOPPED)
|
|
|
|
which |= 1;
|
|
|
|
#endif /* JOBS */
|
|
|
|
if (Flag(FLOGIN) && !Flag(FNOHUP) && procpid == kshpid
|
|
|
|
&& j->ppid == procpid && j->state == PRUNNING)
|
|
|
|
which |= 2;
|
|
|
|
}
|
|
|
|
if (which) {
|
|
|
|
shellf("You have %s%s%s jobs\n",
|
|
|
|
which & 1 ? "stopped" : "",
|
|
|
|
which == 3 ? " and " : "",
|
|
|
|
which & 2 ? "running" : "");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* list jobs for jobs built-in */
|
|
|
|
int
|
2004-10-28 13:53:44 +02:00
|
|
|
j_jobs(const char *cp, int slp, int nflag)
|
|
|
|
|
|
|
|
/* 0: short, 1: long, 2: pgrp */
|
|
|
|
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
Job *j, *tmp;
|
|
|
|
int how;
|
|
|
|
int zflag = 0;
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigset_t omask;
|
|
|
|
|
|
|
|
sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
|
|
|
|
if (nflag < 0) { /* kludge: print zombies */
|
|
|
|
nflag = 0;
|
|
|
|
zflag = 1;
|
|
|
|
}
|
|
|
|
if (cp) {
|
|
|
|
int ecode;
|
|
|
|
|
|
|
|
if ((j = j_lookup(cp, &ecode)) == (Job *) 0) {
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
bi_errorf("%s: %s", cp, lookup_msgs[ecode]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
j = job_list;
|
|
|
|
how = slp == 0 ? JP_MEDIUM : (slp == 1 ? JP_LONG : JP_PGRP);
|
|
|
|
for (; j; j = j->next) {
|
|
|
|
if ((!(j->flags & JF_ZOMBIE) || zflag)
|
|
|
|
&& (!nflag || (j->flags & JF_CHANGED)))
|
|
|
|
{
|
|
|
|
j_print(j, how, shl_stdout);
|
|
|
|
if (j->state == PEXITED || j->state == PSIGNALLED)
|
|
|
|
j->flags |= JF_REMOVE;
|
|
|
|
}
|
|
|
|
if (cp)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* Remove jobs after printing so there won't be multiple + or - jobs */
|
|
|
|
for (j = job_list; j; j = tmp) {
|
|
|
|
tmp = j->next;
|
|
|
|
if (j->flags & JF_REMOVE)
|
|
|
|
remove_job(j, "jobs");
|
|
|
|
}
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* list jobs for top-level notification */
|
|
|
|
void
|
2004-10-28 13:53:44 +02:00
|
|
|
j_notify(void)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
Job *j, *tmp;
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigset_t omask;
|
|
|
|
|
|
|
|
sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
for (j = job_list; j; j = j->next) {
|
|
|
|
#ifdef JOBS
|
|
|
|
if (Flag(FMONITOR) && (j->flags & JF_CHANGED))
|
|
|
|
j_print(j, JP_MEDIUM, shl_out);
|
|
|
|
#endif /* JOBS */
|
|
|
|
/* Remove job after doing reports so there aren't
|
|
|
|
* multiple +/- jobs.
|
|
|
|
*/
|
|
|
|
if (j->state == PEXITED || j->state == PSIGNALLED)
|
|
|
|
j->flags |= JF_REMOVE;
|
|
|
|
}
|
|
|
|
for (j = job_list; j; j = tmp) {
|
|
|
|
tmp = j->next;
|
|
|
|
if (j->flags & JF_REMOVE)
|
|
|
|
remove_job(j, "notify");
|
|
|
|
}
|
|
|
|
shf_flush(shl_out);
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return pid of last process in last asynchronous job */
|
|
|
|
pid_t
|
2004-10-28 13:53:44 +02:00
|
|
|
j_async(void)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigset_t omask;
|
|
|
|
|
|
|
|
sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
|
|
|
|
if (async_job)
|
|
|
|
async_job->flags |= JF_KNOWN;
|
|
|
|
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
|
|
|
|
return async_pid;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make j the last async process
|
|
|
|
*
|
|
|
|
* If jobs are compiled in then this routine expects sigchld to be blocked.
|
|
|
|
*/
|
|
|
|
static void
|
2004-10-28 13:53:44 +02:00
|
|
|
j_set_async(Job *j)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
Job *jl, *oldest;
|
|
|
|
|
|
|
|
if (async_job && (async_job->flags & (JF_KNOWN|JF_ZOMBIE)) == JF_ZOMBIE)
|
|
|
|
remove_job(async_job, "async");
|
|
|
|
if (!(j->flags & JF_STARTED)) {
|
|
|
|
internal_errorf(0, "j_async: job not started");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
async_job = j;
|
|
|
|
async_pid = j->last_proc->pid;
|
|
|
|
while (nzombie > child_max) {
|
|
|
|
oldest = (Job *) 0;
|
|
|
|
for (jl = job_list; jl; jl = jl->next)
|
|
|
|
if (jl != async_job && (jl->flags & JF_ZOMBIE)
|
|
|
|
&& (!oldest || jl->age < oldest->age))
|
|
|
|
oldest = jl;
|
|
|
|
if (!oldest) {
|
|
|
|
/* XXX debugging */
|
|
|
|
if (!(async_job->flags & JF_ZOMBIE) || nzombie != 1) {
|
|
|
|
internal_errorf(0, "j_async: bad nzombie (%d)", nzombie);
|
|
|
|
nzombie = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
remove_job(oldest, "zombie");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Start a job: set STARTED, check for held signals and set j->last_proc
|
|
|
|
*
|
|
|
|
* If jobs are compiled in then this routine expects sigchld to be blocked.
|
|
|
|
*/
|
|
|
|
static void
|
2004-10-28 13:53:44 +02:00
|
|
|
j_startjob(Job *j)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
Proc *p;
|
|
|
|
|
|
|
|
j->flags |= JF_STARTED;
|
|
|
|
for (p = j->proc_list; p->next; p = p->next)
|
|
|
|
;
|
|
|
|
j->last_proc = p;
|
|
|
|
|
|
|
|
#ifdef NEED_PGRP_SYNC
|
|
|
|
if (j_sync_open) {
|
|
|
|
j_sync_open = 0;
|
|
|
|
closepipe(j_sync_pipe);
|
|
|
|
}
|
|
|
|
#endif /* NEED_PGRP_SYNC */
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
if (held_sigchld) {
|
|
|
|
held_sigchld = 0;
|
|
|
|
/* Don't call j_sigchld() as it may remove job... */
|
|
|
|
kill(procpid, SIGCHLD);
|
|
|
|
}
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* wait for job to complete or change state
|
|
|
|
*
|
|
|
|
* If jobs are compiled in then this routine expects sigchld to be blocked.
|
|
|
|
*/
|
|
|
|
static int
|
2004-10-28 13:53:44 +02:00
|
|
|
j_waitj(Job *j, int flags, const char *where)
|
|
|
|
|
|
|
|
/* see JW_* */
|
|
|
|
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* No auto-notify on the job we are waiting on.
|
|
|
|
*/
|
|
|
|
j->flags |= JF_WAITING;
|
|
|
|
if (flags & JW_ASYNCNOTIFY)
|
|
|
|
j->flags |= JF_W_ASYNCNOTIFY;
|
|
|
|
|
|
|
|
if (!Flag(FMONITOR))
|
|
|
|
flags |= JW_STOPPEDWAIT;
|
|
|
|
|
|
|
|
while ((volatile int) j->state == PRUNNING
|
|
|
|
|| ((flags & JW_STOPPEDWAIT)
|
|
|
|
&& (volatile int) j->state == PSTOPPED))
|
|
|
|
{
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
sigsuspend(&sm_default);
|
|
|
|
#else /* JOB_SIGS */
|
|
|
|
j_sigchld(SIGCHLD);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
if (fatal_trap) {
|
|
|
|
int oldf = j->flags & (JF_WAITING|JF_W_ASYNCNOTIFY);
|
|
|
|
j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
|
|
|
|
runtraps(TF_FATAL);
|
|
|
|
j->flags |= oldf; /* not reached... */
|
|
|
|
}
|
|
|
|
if ((flags & JW_INTERRUPT) && (rv = trap_pending())) {
|
|
|
|
j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
|
|
|
|
return -rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
|
|
|
|
|
|
|
|
if (j->flags & JF_FG) {
|
|
|
|
WAIT_T status;
|
|
|
|
|
|
|
|
j->flags &= ~JF_FG;
|
|
|
|
#ifdef TTY_PGRP
|
|
|
|
if (Flag(FMONITOR) && ttypgrp_ok && j->pgrp) {
|
|
|
|
/*
|
|
|
|
* Save the tty's current pgrp so it can be restored
|
|
|
|
* when the job is foregrounded. This is to
|
|
|
|
* deal with things like the GNU su which does
|
|
|
|
* a fork/exec instead of an exec (the fork means
|
|
|
|
* the execed shell gets a different pid from its
|
|
|
|
* pgrp, so naturally it sets its pgrp and gets hosed
|
|
|
|
* when it gets foregrounded by the parent shell, which
|
|
|
|
* has restored the tty's pgrp to that of the su
|
|
|
|
* process).
|
|
|
|
*/
|
|
|
|
if (j->state == PSTOPPED
|
|
|
|
&& (j->saved_ttypgrp = tcgetpgrp(tty_fd)) >= 0)
|
|
|
|
j->flags |= JF_SAVEDTTYPGRP;
|
|
|
|
if (tcsetpgrp(tty_fd, our_pgrp) < 0) {
|
|
|
|
warningf(TRUE,
|
|
|
|
"j_waitj: tcsetpgrp(%d, %d) failed: %s",
|
|
|
|
tty_fd, (int) our_pgrp,
|
|
|
|
strerror(errno));
|
|
|
|
}
|
|
|
|
if (j->state == PSTOPPED) {
|
|
|
|
j->flags |= JF_SAVEDTTY;
|
|
|
|
get_tty(tty_fd, &j->ttystate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* TTY_PGRP */
|
|
|
|
if (tty_fd >= 0) {
|
|
|
|
/* Only restore tty settings if job was originally
|
|
|
|
* started in the foreground. Problems can be
|
2004-04-17 02:47:20 +02:00
|
|
|
* caused by things like 'more foobar &' which will
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
* typically get and save the shell's vi/emacs tty
|
|
|
|
* settings before setting up the tty for itself;
|
2004-04-17 02:47:20 +02:00
|
|
|
* when more exits, it restores the 'original'
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
* settings, and things go down hill from there...
|
|
|
|
*/
|
|
|
|
if (j->state == PEXITED && j->status == 0
|
|
|
|
&& (j->flags & JF_USETTYMODE))
|
|
|
|
{
|
|
|
|
get_tty(tty_fd, &tty_state);
|
|
|
|
} else {
|
|
|
|
set_tty(tty_fd, &tty_state,
|
|
|
|
(j->state == PEXITED) ? 0 : TF_MIPSKLUDGE);
|
|
|
|
/* Don't use tty mode if job is stopped and
|
|
|
|
* later restarted and exits. Consider
|
|
|
|
* the sequence:
|
|
|
|
* vi foo (stopped)
|
|
|
|
* ...
|
|
|
|
* stty something
|
|
|
|
* ...
|
|
|
|
* fg (vi; ZZ)
|
|
|
|
* mode should be that of the stty, not what
|
|
|
|
* was before the vi started.
|
|
|
|
*/
|
|
|
|
if (j->state == PSTOPPED)
|
|
|
|
j->flags &= ~JF_USETTYMODE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#ifdef JOBS
|
|
|
|
/* If it looks like user hit ^C to kill a job, pretend we got
|
|
|
|
* one too to break out of for loops, etc. (at&t ksh does this
|
|
|
|
* even when not monitoring, but this doesn't make sense since
|
|
|
|
* a tty generated ^C goes to the whole process group)
|
|
|
|
*/
|
|
|
|
status = j->last_proc->status;
|
|
|
|
if (Flag(FMONITOR) && j->state == PSIGNALLED
|
|
|
|
&& WIFSIGNALED(status)
|
|
|
|
&& (sigtraps[WTERMSIG(status)].flags & TF_TTY_INTR))
|
|
|
|
trapsig(WTERMSIG(status));
|
|
|
|
#endif /* JOBS */
|
|
|
|
}
|
|
|
|
|
|
|
|
j_usrtime = j->usrtime;
|
|
|
|
j_systime = j->systime;
|
|
|
|
rv = j->status;
|
|
|
|
|
|
|
|
if (!(flags & JW_ASYNCNOTIFY)
|
|
|
|
&& (!Flag(FMONITOR) || j->state != PSTOPPED))
|
|
|
|
{
|
|
|
|
j_print(j, JP_SHORT, shl_out);
|
|
|
|
shf_flush(shl_out);
|
|
|
|
}
|
|
|
|
if (j->state != PSTOPPED
|
|
|
|
&& (!Flag(FMONITOR) || !(flags & JW_ASYNCNOTIFY)))
|
|
|
|
remove_job(j, where);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* SIGCHLD handler to reap children and update job states
|
|
|
|
*
|
|
|
|
* If jobs are compiled in then this routine expects sigchld to be blocked.
|
|
|
|
*/
|
|
|
|
static RETSIGTYPE
|
2004-10-28 13:03:24 +02:00
|
|
|
j_sigchld(int sig GCC_FUNC_ATTR(unused))
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
int errno_ = errno;
|
|
|
|
Job *j;
|
|
|
|
Proc UNINITIALIZED(*p);
|
|
|
|
int pid;
|
|
|
|
WAIT_T status;
|
|
|
|
struct tms t0, t1;
|
|
|
|
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
/* Don't wait for any processes if a job is partially started.
|
|
|
|
* This is so we don't do away with the process group leader
|
|
|
|
* before all the processes in a pipe line are started (so the
|
|
|
|
* setpgid() won't fail)
|
|
|
|
*/
|
|
|
|
for (j = job_list; j; j = j->next)
|
|
|
|
if (j->ppid == procpid && !(j->flags & JF_STARTED)) {
|
|
|
|
held_sigchld = 1;
|
|
|
|
return RETSIGVAL;
|
|
|
|
}
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
|
|
|
|
ksh_times(&t0);
|
|
|
|
do {
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
pid = ksh_waitpid(-1, &status, (WNOHANG|WUNTRACED));
|
|
|
|
#else /* JOB_SIGS */
|
|
|
|
pid = wait(&status);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
|
|
|
|
if (pid <= 0) /* return if would block (0) ... */
|
|
|
|
break; /* ... or no children or interrupted (-1) */
|
|
|
|
|
|
|
|
ksh_times(&t1);
|
|
|
|
|
|
|
|
/* find job and process structures for this pid */
|
|
|
|
for (j = job_list; j != (Job *) 0; j = j->next)
|
|
|
|
for (p = j->proc_list; p != (Proc *) 0; p = p->next)
|
|
|
|
if (p->pid == pid)
|
|
|
|
goto found;
|
|
|
|
found:
|
|
|
|
if (j == (Job *) 0) {
|
|
|
|
/* Can occur if process has kids, then execs shell
|
|
|
|
warningf(TRUE, "bad process waited for (pid = %d)",
|
|
|
|
pid);
|
|
|
|
*/
|
|
|
|
t0 = t1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
j->usrtime += t1.tms_cutime - t0.tms_cutime;
|
|
|
|
j->systime += t1.tms_cstime - t0.tms_cstime;
|
|
|
|
t0 = t1;
|
|
|
|
p->status = status;
|
|
|
|
#ifdef JOBS
|
|
|
|
if (WIFSTOPPED(status))
|
|
|
|
p->state = PSTOPPED;
|
|
|
|
else
|
|
|
|
#endif /* JOBS */
|
|
|
|
if (WIFSIGNALED(status))
|
|
|
|
p->state = PSIGNALLED;
|
|
|
|
else
|
|
|
|
p->state = PEXITED;
|
|
|
|
|
|
|
|
check_job(j); /* check to see if entire job is done */
|
|
|
|
}
|
|
|
|
#ifdef JOB_SIGS
|
|
|
|
while (1);
|
|
|
|
#else /* JOB_SIGS */
|
|
|
|
while (0);
|
|
|
|
#endif /* JOB_SIGS */
|
|
|
|
|
|
|
|
errno = errno_;
|
|
|
|
|
|
|
|
return RETSIGVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Called only when a process in j has exited/stopped (ie, called only
|
|
|
|
* from j_sigchld()). If no processes are running, the job status
|
|
|
|
* and state are updated, asynchronous job notification is done and,
|
|
|
|
* if unneeded, the job is removed.
|
|
|
|
*
|
|
|
|
* If jobs are compiled in then this routine expects sigchld to be blocked.
|
|
|
|
*/
|
|
|
|
static void
|
2004-10-28 13:53:44 +02:00
|
|
|
check_job(Job *j)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
int jstate;
|
|
|
|
Proc *p;
|
|
|
|
|
|
|
|
/* XXX debugging (nasty - interrupt routine using shl_out) */
|
|
|
|
if (!(j->flags & JF_STARTED)) {
|
|
|
|
internal_errorf(0, "check_job: job started (flags 0x%x)",
|
|
|
|
j->flags);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
jstate = PRUNNING;
|
|
|
|
for (p=j->proc_list; p != (Proc *) 0; p = p->next) {
|
|
|
|
if (p->state == PRUNNING)
|
|
|
|
return; /* some processes still running */
|
|
|
|
if (p->state > jstate)
|
|
|
|
jstate = p->state;
|
|
|
|
}
|
|
|
|
j->state = jstate;
|
|
|
|
|
|
|
|
switch (j->last_proc->state) {
|
|
|
|
case PEXITED:
|
|
|
|
j->status = WEXITSTATUS(j->last_proc->status);
|
|
|
|
break;
|
|
|
|
case PSIGNALLED:
|
|
|
|
j->status = 128 + WTERMSIG(j->last_proc->status);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
j->status = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Note when co-process dies: can't be done in j_wait() nor
|
|
|
|
* remove_job() since neither may be called for non-interactive
|
|
|
|
* shells.
|
|
|
|
*/
|
|
|
|
if (j->state == PEXITED || j->state == PSIGNALLED) {
|
|
|
|
/* No need to keep co-process input any more
|
2003-12-22 21:22:51 +01:00
|
|
|
* (at least, this is what ksh93d thinks)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
*/
|
|
|
|
if (coproc.job == j) {
|
|
|
|
coproc.job = (void *) 0;
|
|
|
|
/* XXX would be nice to get the closes out of here
|
|
|
|
* so they aren't done in the signal handler.
|
|
|
|
* Would mean a check in coproc_getfd() to
|
|
|
|
* do "if job == 0 && write >= 0, close write".
|
|
|
|
*/
|
|
|
|
coproc_write_close(coproc.write);
|
|
|
|
}
|
|
|
|
/* Do we need to keep the output? */
|
|
|
|
if (j->coproc_id && j->coproc_id == coproc.id
|
|
|
|
&& --coproc.njobs == 0)
|
|
|
|
coproc_readw_close(coproc.read);
|
|
|
|
}
|
|
|
|
|
|
|
|
j->flags |= JF_CHANGED;
|
|
|
|
#ifdef JOBS
|
|
|
|
if (Flag(FMONITOR) && !(j->flags & JF_XXCOM)) {
|
|
|
|
/* Only put stopped jobs at the front to avoid confusing
|
|
|
|
* the user (don't want finished jobs effecting %+ or %-)
|
|
|
|
*/
|
|
|
|
if (j->state == PSTOPPED)
|
|
|
|
put_job(j, PJ_ON_FRONT);
|
|
|
|
if (Flag(FNOTIFY)
|
|
|
|
&& (j->flags & (JF_WAITING|JF_W_ASYNCNOTIFY)) != JF_WAITING)
|
|
|
|
{
|
|
|
|
/* Look for the real file descriptor 2 */
|
|
|
|
{
|
|
|
|
struct env *ep;
|
|
|
|
int fd = 2;
|
|
|
|
|
|
|
|
for (ep = e; ep; ep = ep->oenv)
|
|
|
|
if (ep->savefd && ep->savefd[2])
|
|
|
|
fd = ep->savefd[2];
|
|
|
|
shf_reopen(fd, SHF_WR, shl_j);
|
|
|
|
}
|
|
|
|
/* Can't call j_notify() as it removes jobs. The job
|
|
|
|
* must stay in the job list as j_waitj() may be
|
|
|
|
* running with this job.
|
|
|
|
*/
|
|
|
|
j_print(j, JP_MEDIUM, shl_j);
|
|
|
|
shf_flush(shl_j);
|
|
|
|
if (!(j->flags & JF_WAITING) && j->state != PSTOPPED)
|
|
|
|
remove_job(j, "notify");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* JOBS */
|
|
|
|
if (!Flag(FMONITOR) && !(j->flags & (JF_WAITING|JF_FG))
|
|
|
|
&& j->state != PSTOPPED)
|
|
|
|
{
|
|
|
|
if (j == async_job || (j->flags & JF_KNOWN)) {
|
|
|
|
j->flags |= JF_ZOMBIE;
|
|
|
|
j->job = -1;
|
|
|
|
nzombie++;
|
|
|
|
} else
|
|
|
|
remove_job(j, "checkjob");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Print job status in either short, medium or long format.
|
|
|
|
*
|
|
|
|
* If jobs are compiled in then this routine expects sigchld to be blocked.
|
|
|
|
*/
|
|
|
|
static void
|
2004-10-28 13:53:44 +02:00
|
|
|
j_print(Job *j, int how, struct shf *shf)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
Proc *p;
|
|
|
|
int state;
|
|
|
|
WAIT_T status;
|
|
|
|
int coredumped;
|
|
|
|
char jobchar = ' ';
|
|
|
|
char buf[64];
|
|
|
|
const char *filler;
|
|
|
|
int output = 0;
|
|
|
|
|
|
|
|
if (how == JP_PGRP) {
|
|
|
|
/* POSIX doesn't say what to do it there is no process
|
|
|
|
* group leader (ie, !FMONITOR). We arbitrarily return
|
|
|
|
* last pid (which is what $! returns).
|
|
|
|
*/
|
|
|
|
shf_fprintf(shf, "%d\n", j->pgrp ? j->pgrp
|
|
|
|
: (j->last_proc ? j->last_proc->pid : 0));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
j->flags &= ~JF_CHANGED;
|
|
|
|
filler = j->job > 10 ? "\n " : "\n ";
|
|
|
|
if (j == job_list)
|
|
|
|
jobchar = '+';
|
|
|
|
else if (j == job_list->next)
|
|
|
|
jobchar = '-';
|
|
|
|
|
|
|
|
for (p = j->proc_list; p != (Proc *) 0;) {
|
|
|
|
coredumped = 0;
|
|
|
|
switch (p->state) {
|
|
|
|
case PRUNNING:
|
|
|
|
strlcpy(buf, "Running", sizeof buf);
|
|
|
|
break;
|
|
|
|
case PSTOPPED:
|
|
|
|
strlcpy(buf, sigtraps[WSTOPSIG(p->status)].mess,
|
|
|
|
sizeof buf);
|
|
|
|
break;
|
|
|
|
case PEXITED:
|
|
|
|
if (how == JP_SHORT)
|
|
|
|
buf[0] = '\0';
|
|
|
|
else if (WEXITSTATUS(p->status) == 0)
|
|
|
|
strlcpy(buf, "Done", sizeof buf);
|
|
|
|
else
|
|
|
|
shf_snprintf(buf, sizeof(buf), "Done (%d)",
|
|
|
|
WEXITSTATUS(p->status));
|
|
|
|
break;
|
|
|
|
case PSIGNALLED:
|
|
|
|
if (WIFCORED(p->status))
|
|
|
|
coredumped = 1;
|
2004-04-17 02:47:20 +02:00
|
|
|
/* kludge for not reporting 'normal termination signals'
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
* (ie, SIGINT, SIGPIPE)
|
|
|
|
*/
|
|
|
|
if (how == JP_SHORT && !coredumped
|
|
|
|
&& (WTERMSIG(p->status) == SIGINT
|
|
|
|
|| WTERMSIG(p->status) == SIGPIPE)) {
|
|
|
|
buf[0] = '\0';
|
|
|
|
} else
|
|
|
|
strlcpy(buf, sigtraps[WTERMSIG(p->status)].mess,
|
|
|
|
sizeof buf);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (how != JP_SHORT) {
|
|
|
|
if (p == j->proc_list)
|
|
|
|
shf_fprintf(shf, "[%d] %c ", j->job, jobchar);
|
|
|
|
else
|
|
|
|
shf_fprintf(shf, "%s", filler);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (how == JP_LONG)
|
|
|
|
shf_fprintf(shf, "%5d ", p->pid);
|
|
|
|
|
|
|
|
if (how == JP_SHORT) {
|
|
|
|
if (buf[0]) {
|
|
|
|
output = 1;
|
|
|
|
shf_fprintf(shf, "%s%s ",
|
|
|
|
buf, coredumped ? " (core dumped)" : null);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
output = 1;
|
|
|
|
shf_fprintf(shf, "%-20s %s%s%s", buf, p->command,
|
|
|
|
p->next ? "|" : null,
|
|
|
|
coredumped ? " (core dumped)" : null);
|
|
|
|
}
|
|
|
|
|
|
|
|
state = p->state;
|
|
|
|
status = p->status;
|
|
|
|
p = p->next;
|
|
|
|
while (p && p->state == state
|
|
|
|
&& WSTATUS(p->status) == WSTATUS(status))
|
|
|
|
{
|
|
|
|
if (how == JP_LONG)
|
|
|
|
shf_fprintf(shf, "%s%5d %-20s %s%s", filler, p->pid,
|
|
|
|
space, p->command, p->next ? "|" : null);
|
|
|
|
else if (how == JP_MEDIUM)
|
|
|
|
shf_fprintf(shf, " %s%s", p->command,
|
|
|
|
p->next ? "|" : null);
|
|
|
|
p = p->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (output)
|
|
|
|
shf_fprintf(shf, newline);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert % sequence to job
|
|
|
|
*
|
|
|
|
* If jobs are compiled in then this routine expects sigchld to be blocked.
|
|
|
|
*/
|
|
|
|
static Job *
|
2004-10-28 13:53:44 +02:00
|
|
|
j_lookup(const char *cp, int *ecodep)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
Job *j, *last_match;
|
|
|
|
Proc *p;
|
|
|
|
int len, job = 0;
|
|
|
|
|
|
|
|
if (digit(*cp)) {
|
|
|
|
job = atoi(cp);
|
|
|
|
/* Look for last_proc->pid (what $! returns) first... */
|
|
|
|
for (j = job_list; j != (Job *) 0; j = j->next)
|
|
|
|
if (j->last_proc && j->last_proc->pid == job)
|
|
|
|
return j;
|
|
|
|
/* ...then look for process group (this is non-POSIX),
|
|
|
|
* but should not break anything (so FPOSIX isn't used).
|
|
|
|
*/
|
|
|
|
for (j = job_list; j != (Job *) 0; j = j->next)
|
|
|
|
if (j->pgrp && j->pgrp == job)
|
|
|
|
return j;
|
|
|
|
if (ecodep)
|
|
|
|
*ecodep = JL_NOSUCH;
|
|
|
|
return (Job *) 0;
|
|
|
|
}
|
|
|
|
if (*cp != '%') {
|
|
|
|
if (ecodep)
|
|
|
|
*ecodep = JL_INVALID;
|
|
|
|
return (Job *) 0;
|
|
|
|
}
|
|
|
|
switch (*++cp) {
|
|
|
|
case '\0': /* non-standard */
|
|
|
|
case '+':
|
|
|
|
case '%':
|
|
|
|
if (job_list != (Job *) 0)
|
|
|
|
return job_list;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '-':
|
|
|
|
if (job_list != (Job *) 0 && job_list->next)
|
|
|
|
return job_list->next;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '0': case '1': case '2': case '3': case '4':
|
|
|
|
case '5': case '6': case '7': case '8': case '9':
|
|
|
|
job = atoi(cp);
|
|
|
|
for (j = job_list; j != (Job *) 0; j = j->next)
|
|
|
|
if (j->job == job)
|
|
|
|
return j;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '?': /* %?string */
|
|
|
|
last_match = (Job *) 0;
|
|
|
|
for (j = job_list; j != (Job *) 0; j = j->next)
|
|
|
|
for (p = j->proc_list; p != (Proc *) 0; p = p->next)
|
|
|
|
if (strstr(p->command, cp+1) != (char *) 0) {
|
|
|
|
if (last_match) {
|
|
|
|
if (ecodep)
|
|
|
|
*ecodep = JL_AMBIG;
|
|
|
|
return (Job *) 0;
|
|
|
|
}
|
|
|
|
last_match = j;
|
|
|
|
}
|
|
|
|
if (last_match)
|
|
|
|
return last_match;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default: /* %string */
|
|
|
|
len = strlen(cp);
|
|
|
|
last_match = (Job *) 0;
|
|
|
|
for (j = job_list; j != (Job *) 0; j = j->next)
|
|
|
|
if (strncmp(cp, j->proc_list->command, len) == 0) {
|
|
|
|
if (last_match) {
|
|
|
|
if (ecodep)
|
|
|
|
*ecodep = JL_AMBIG;
|
|
|
|
return (Job *) 0;
|
|
|
|
}
|
|
|
|
last_match = j;
|
|
|
|
}
|
|
|
|
if (last_match)
|
|
|
|
return last_match;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (ecodep)
|
|
|
|
*ecodep = JL_NOSUCH;
|
|
|
|
return (Job *) 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Job *free_jobs;
|
|
|
|
static Proc *free_procs;
|
|
|
|
|
|
|
|
/* allocate a new job and fill in the job number.
|
|
|
|
*
|
|
|
|
* If jobs are compiled in then this routine expects sigchld to be blocked.
|
|
|
|
*/
|
|
|
|
static Job *
|
2004-10-28 13:53:44 +02:00
|
|
|
new_job(void)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
Job *newj, *j;
|
|
|
|
|
|
|
|
if (free_jobs != (Job *) 0) {
|
|
|
|
newj = free_jobs;
|
|
|
|
free_jobs = free_jobs->next;
|
|
|
|
} else
|
|
|
|
newj = (Job *) alloc(sizeof(Job), APERM);
|
|
|
|
|
|
|
|
/* brute force method */
|
|
|
|
for (i = 1; ; i++) {
|
|
|
|
for (j = job_list; j && j->job != i; j = j->next)
|
|
|
|
;
|
|
|
|
if (j == (Job *) 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
newj->job = i;
|
|
|
|
|
|
|
|
return newj;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate new process strut
|
|
|
|
*
|
|
|
|
* If jobs are compiled in then this routine expects sigchld to be blocked.
|
|
|
|
*/
|
|
|
|
static Proc *
|
2004-10-28 13:53:44 +02:00
|
|
|
new_proc(void)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
Proc *p;
|
|
|
|
|
|
|
|
if (free_procs != (Proc *) 0) {
|
|
|
|
p = free_procs;
|
|
|
|
free_procs = free_procs->next;
|
|
|
|
} else
|
|
|
|
p = (Proc *) alloc(sizeof(Proc), APERM);
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Take job out of job_list and put old structures into free list.
|
|
|
|
* Keeps nzombies, last_job and async_job up to date.
|
|
|
|
*
|
|
|
|
* If jobs are compiled in then this routine expects sigchld to be blocked.
|
|
|
|
*/
|
|
|
|
static void
|
2004-10-28 13:53:44 +02:00
|
|
|
remove_job(Job *j, const char *where)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
Proc *p, *tmp;
|
|
|
|
Job **prev, *curr;
|
|
|
|
|
|
|
|
prev = &job_list;
|
|
|
|
curr = *prev;
|
|
|
|
for (; curr != (Job *) 0 && curr != j; prev = &curr->next, curr = *prev)
|
|
|
|
;
|
|
|
|
if (curr != j) {
|
|
|
|
internal_errorf(0, "remove_job: job not found (%s)", where);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
*prev = curr->next;
|
|
|
|
|
|
|
|
/* free up proc structures */
|
|
|
|
for (p = j->proc_list; p != (Proc *) 0; ) {
|
|
|
|
tmp = p;
|
|
|
|
p = p->next;
|
|
|
|
tmp->next = free_procs;
|
|
|
|
free_procs = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((j->flags & JF_ZOMBIE) && j->ppid == procpid)
|
|
|
|
--nzombie;
|
|
|
|
j->next = free_jobs;
|
|
|
|
free_jobs = j;
|
|
|
|
|
|
|
|
if (j == last_job)
|
|
|
|
last_job = (Job *) 0;
|
|
|
|
if (j == async_job)
|
|
|
|
async_job = (Job *) 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* put j in a particular location (taking it out job_list if it is there
|
|
|
|
* already)
|
|
|
|
*
|
|
|
|
* If jobs are compiled in then this routine expects sigchld to be blocked.
|
|
|
|
*/
|
|
|
|
static void
|
2004-10-28 13:53:44 +02:00
|
|
|
put_job(Job *j, int where)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
Job **prev, *curr;
|
|
|
|
|
|
|
|
/* Remove job from list (if there) */
|
|
|
|
prev = &job_list;
|
|
|
|
curr = job_list;
|
|
|
|
for (; curr && curr != j; prev = &curr->next, curr = *prev)
|
|
|
|
;
|
|
|
|
if (curr == j)
|
|
|
|
*prev = curr->next;
|
|
|
|
|
|
|
|
switch (where) {
|
|
|
|
case PJ_ON_FRONT:
|
|
|
|
j->next = job_list;
|
|
|
|
job_list = j;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PJ_PAST_STOPPED:
|
|
|
|
prev = &job_list;
|
|
|
|
curr = job_list;
|
|
|
|
for (; curr && curr->state == PSTOPPED; prev = &curr->next,
|
|
|
|
curr = *prev)
|
|
|
|
;
|
|
|
|
j->next = curr;
|
|
|
|
*prev = j;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* nuke a job (called when unable to start full job).
|
|
|
|
*
|
|
|
|
* If jobs are compiled in then this routine expects sigchld to be blocked.
|
|
|
|
*/
|
|
|
|
static int
|
2004-10-28 13:53:44 +02:00
|
|
|
kill_job(Job *j, int sig)
|
Import OpenBSD 3.3 source repository from CTM 3132 the first time
This opens an OpenBSD-mirabile (aka MirBSD) repository.
### MirBSD is:
# Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
# Copyright © 1968-2003 The authors of And contributors to UNIX®, the
# C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD.
#
# Anyone who obtained a copy of this work is hereby permitted to freely use,
# distribute, modify, merge, sublicence, give away or sell it as long as the
# authors are given due credit and the following notice is retained:
#
# This work is provided "as is", with no explicit or implicit warranty what-
# soever. Use it only at your own risk. In no event may an author or contri-
# butor be held liable for any damage, directly or indirectly, that origina-
# ted through or is caused by creation or modification of this work.
MirBSD is my private tree. MirBSD does not differ very much from OpenBSD
and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the
official one. It's like with DarrenBSD.
At time of this writing, no advertising for MirBSD must be done,
because the advertising clause has not yet been sorted out.
http://templeofhate.com/tglaser/MirBSD/index.php
2003-03-22 18:35:03 +01:00
|
|
|
{
|
|
|
|
Proc *p;
|
|
|
|
int rval = 0;
|
|
|
|
|
|
|
|
for (p = j->proc_list; p != (Proc *) 0; p = p->next)
|
|
|
|
if (p->pid != 0)
|
|
|
|
if (kill(p->pid, sig) < 0)
|
|
|
|
rval = -1;
|
|
|
|
return rval;
|
|
|
|
}
|