mirror of
https://git.busybox.net/busybox
synced 2026-01-31 16:43:21 +00:00
ash: converge waiting code to dash in its form, add comments, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
f6fb3c603a
commit
ea2022efb3
1 changed files with 30 additions and 26 deletions
56
shell/ash.c
56
shell/ash.c
|
|
@ -4412,11 +4412,12 @@ sprint_status48(char *os, int status, int sigonly)
|
|||
return s - os;
|
||||
}
|
||||
|
||||
#define DOWAIT_NONBLOCK 0
|
||||
#define DOWAIT_BLOCK 1
|
||||
#define DOWAIT_BLOCK_OR_SIG 2
|
||||
/* Inside dowait(): */
|
||||
#define DOWAIT_NONBLOCK 0 /* waitpid() will use WNOHANG and won't wait for signals */
|
||||
#define DOWAIT_BLOCK 1 /* waitpid() will NOT use WNOHANG */
|
||||
#define DOWAIT_CHILD_OR_SIG 2 /* waitpid() will use WNOHANG and if got 0, will wait for signals, then loop back */
|
||||
#if BASH_WAIT_N
|
||||
# define DOWAIT_JOBSTATUS 0x10 /* OR this to get job's exitstatus instead of pid */
|
||||
# define DOWAIT_JOBSTATUS 0x10 /* OR this to get job's exitstatus instead of pid */
|
||||
#endif
|
||||
|
||||
static int
|
||||
|
|
@ -4437,9 +4438,16 @@ waitproc(int block, int *status)
|
|||
err = waitpid(-1, status, flags);
|
||||
while (err < 0 && errno == EINTR);
|
||||
|
||||
/* Return if error (for example, ECHILD); or if pid found;
|
||||
* or if "block" is DOWAIT_NONBLOCK (=0), in this case return -1.
|
||||
*/
|
||||
if (err || (err = -!block))
|
||||
break;
|
||||
|
||||
/* "block" is DOWAIT_CHILD_OR_SIG. All children are running
|
||||
* (waitpid(WNOHAG) above returned 0), wait for signals:
|
||||
*/
|
||||
|
||||
//simpler, but unsafe: a signal can set pending_sig after check, but before pause():
|
||||
//while (!gotsigchld && !pending_sig)
|
||||
// pause();
|
||||
|
|
@ -4451,12 +4459,12 @@ waitproc(int block, int *status)
|
|||
|
||||
sigclearmask();
|
||||
} while (gotsigchld);
|
||||
/* If we fall off the loop, err is 0, which means we got a !SIGCHLD signal */
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
waitone(int block, struct job *job)
|
||||
static int waitone(int block, struct job *job)
|
||||
{
|
||||
int pid;
|
||||
int status;
|
||||
|
|
@ -4495,32 +4503,30 @@ waitone(int block, struct job *job)
|
|||
|
||||
for (jp = curjob; jp; jp = jp->prev_job) {
|
||||
int jobstate;
|
||||
struct procstat *ps;
|
||||
struct procstat *psend;
|
||||
struct procstat *sp;
|
||||
struct procstat *spend;
|
||||
if (jp->state == JOBDONE)
|
||||
continue;
|
||||
jobstate = JOBDONE;
|
||||
ps = jp->ps;
|
||||
psend = ps + jp->nprocs;
|
||||
spend = jp->ps + jp->nprocs;
|
||||
sp = jp->ps;
|
||||
do {
|
||||
if (ps->ps_pid == pid) {
|
||||
TRACE(("Job %d: changing status of proc %d "
|
||||
"from 0x%x to 0x%x\n",
|
||||
jobno(jp), pid, ps->ps_status, status));
|
||||
ps->ps_status = status;
|
||||
if (sp->ps_pid == pid) {
|
||||
TRACE(("Job %d: changing status of proc %d from 0x%x to 0x%x\n", jobno(jp), pid, sp->ps_status, status));
|
||||
sp->ps_status = status;
|
||||
thisjob = jp;
|
||||
}
|
||||
if (ps->ps_status == -1)
|
||||
if (sp->ps_status == -1)
|
||||
jobstate = JOBRUNNING;
|
||||
#if JOBS
|
||||
if (jobstate == JOBRUNNING)
|
||||
continue;
|
||||
if (WIFSTOPPED(ps->ps_status)) {
|
||||
jp->stopstatus = ps->ps_status;
|
||||
if (WIFSTOPPED(sp->ps_status)) {
|
||||
jp->stopstatus = sp->ps_status;
|
||||
jobstate = JOBSTOPPED;
|
||||
}
|
||||
#endif
|
||||
} while (++ps < psend);
|
||||
} while (++sp < spend);
|
||||
if (!thisjob)
|
||||
continue;
|
||||
|
||||
|
|
@ -4532,8 +4538,7 @@ waitone(int block, struct job *job)
|
|||
*/
|
||||
thisjob->changed = 1;
|
||||
if (thisjob->state != jobstate) {
|
||||
TRACE(("Job %d: changing state from %d to %d\n",
|
||||
jobno(thisjob), thisjob->state, jobstate));
|
||||
TRACE(("Job %d: changing state from %d to %d\n", jobno(thisjob), thisjob->state, jobstate));
|
||||
thisjob->state = jobstate;
|
||||
#if JOBS
|
||||
if (jobstate == JOBSTOPPED)
|
||||
|
|
@ -4568,8 +4573,7 @@ waitone(int block, struct job *job)
|
|||
return pid;
|
||||
}
|
||||
|
||||
static int
|
||||
dowait(int block, struct job *jp)
|
||||
static int dowait(int block, struct job *jp)
|
||||
{
|
||||
smallint gotchld = *(volatile smallint *)&gotsigchld;
|
||||
int rpid;
|
||||
|
|
@ -4795,9 +4799,9 @@ waitcmd(int argc UNUSED_PARAM, char **argv)
|
|||
* the trap is executed."
|
||||
*/
|
||||
#if BASH_WAIT_N
|
||||
status = dowait(DOWAIT_BLOCK_OR_SIG | DOWAIT_JOBSTATUS, NULL);
|
||||
status = dowait(DOWAIT_CHILD_OR_SIG | DOWAIT_JOBSTATUS, NULL);
|
||||
#else
|
||||
dowait(DOWAIT_BLOCK_OR_SIG, NULL);
|
||||
dowait(DOWAIT_CHILD_OR_SIG, NULL);
|
||||
#endif
|
||||
/* if child sends us a signal *and immediately exits*,
|
||||
* dowait() returns pid > 0. Check this case,
|
||||
|
|
@ -4838,7 +4842,7 @@ waitcmd(int argc UNUSED_PARAM, char **argv)
|
|||
job = getjob(*argv, 0);
|
||||
}
|
||||
/* loop until process terminated or stopped */
|
||||
dowait(DOWAIT_BLOCK_OR_SIG, job);
|
||||
dowait(DOWAIT_CHILD_OR_SIG, job);
|
||||
if (pending_sig)
|
||||
goto sigout;
|
||||
job->waited = 1;
|
||||
|
|
|
|||
Loading…
Reference in a new issue