diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2025-08-10 23:39:44 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2025-08-10 23:39:44 +0200 |
| commit | ea2022efb32661e33ec43f3cd9f5cae8bc2b9547 (patch) | |
| tree | fed618f1ca27f007925679380504ca87f8e6ad8d /shell | |
| parent | f6fb3c603a330d8b9b4910763f8fcee0fa90bba3 (diff) | |
| download | busybox-w32-ea2022efb32661e33ec43f3cd9f5cae8bc2b9547.tar.gz busybox-w32-ea2022efb32661e33ec43f3cd9f5cae8bc2b9547.tar.bz2 busybox-w32-ea2022efb32661e33ec43f3cd9f5cae8bc2b9547.zip | |
ash: converge waiting code to dash in its form, add comments, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/ash.c | 56 |
1 files changed, 30 insertions, 26 deletions
diff --git a/shell/ash.c b/shell/ash.c index 14c59a769..ad1b9fd9f 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -4412,11 +4412,12 @@ sprint_status48(char *os, int status, int sigonly) | |||
| 4412 | return s - os; | 4412 | return s - os; |
| 4413 | } | 4413 | } |
| 4414 | 4414 | ||
| 4415 | #define DOWAIT_NONBLOCK 0 | 4415 | /* Inside dowait(): */ |
| 4416 | #define DOWAIT_BLOCK 1 | 4416 | #define DOWAIT_NONBLOCK 0 /* waitpid() will use WNOHANG and won't wait for signals */ |
| 4417 | #define DOWAIT_BLOCK_OR_SIG 2 | 4417 | #define DOWAIT_BLOCK 1 /* waitpid() will NOT use WNOHANG */ |
| 4418 | #define DOWAIT_CHILD_OR_SIG 2 /* waitpid() will use WNOHANG and if got 0, will wait for signals, then loop back */ | ||
| 4418 | #if BASH_WAIT_N | 4419 | #if BASH_WAIT_N |
| 4419 | # define DOWAIT_JOBSTATUS 0x10 /* OR this to get job's exitstatus instead of pid */ | 4420 | # define DOWAIT_JOBSTATUS 0x10 /* OR this to get job's exitstatus instead of pid */ |
| 4420 | #endif | 4421 | #endif |
| 4421 | 4422 | ||
| 4422 | static int | 4423 | static int |
| @@ -4437,9 +4438,16 @@ waitproc(int block, int *status) | |||
| 4437 | err = waitpid(-1, status, flags); | 4438 | err = waitpid(-1, status, flags); |
| 4438 | while (err < 0 && errno == EINTR); | 4439 | while (err < 0 && errno == EINTR); |
| 4439 | 4440 | ||
| 4441 | /* Return if error (for example, ECHILD); or if pid found; | ||
| 4442 | * or if "block" is DOWAIT_NONBLOCK (=0), in this case return -1. | ||
| 4443 | */ | ||
| 4440 | if (err || (err = -!block)) | 4444 | if (err || (err = -!block)) |
| 4441 | break; | 4445 | break; |
| 4442 | 4446 | ||
| 4447 | /* "block" is DOWAIT_CHILD_OR_SIG. All children are running | ||
| 4448 | * (waitpid(WNOHAG) above returned 0), wait for signals: | ||
| 4449 | */ | ||
| 4450 | |||
| 4443 | //simpler, but unsafe: a signal can set pending_sig after check, but before pause(): | 4451 | //simpler, but unsafe: a signal can set pending_sig after check, but before pause(): |
| 4444 | //while (!gotsigchld && !pending_sig) | 4452 | //while (!gotsigchld && !pending_sig) |
| 4445 | // pause(); | 4453 | // pause(); |
| @@ -4451,12 +4459,12 @@ waitproc(int block, int *status) | |||
| 4451 | 4459 | ||
| 4452 | sigclearmask(); | 4460 | sigclearmask(); |
| 4453 | } while (gotsigchld); | 4461 | } while (gotsigchld); |
| 4462 | /* If we fall off the loop, err is 0, which means we got a !SIGCHLD signal */ | ||
| 4454 | 4463 | ||
| 4455 | return err; | 4464 | return err; |
| 4456 | } | 4465 | } |
| 4457 | 4466 | ||
| 4458 | static int | 4467 | static int waitone(int block, struct job *job) |
| 4459 | waitone(int block, struct job *job) | ||
| 4460 | { | 4468 | { |
| 4461 | int pid; | 4469 | int pid; |
| 4462 | int status; | 4470 | int status; |
| @@ -4495,32 +4503,30 @@ waitone(int block, struct job *job) | |||
| 4495 | 4503 | ||
| 4496 | for (jp = curjob; jp; jp = jp->prev_job) { | 4504 | for (jp = curjob; jp; jp = jp->prev_job) { |
| 4497 | int jobstate; | 4505 | int jobstate; |
| 4498 | struct procstat *ps; | 4506 | struct procstat *sp; |
| 4499 | struct procstat *psend; | 4507 | struct procstat *spend; |
| 4500 | if (jp->state == JOBDONE) | 4508 | if (jp->state == JOBDONE) |
| 4501 | continue; | 4509 | continue; |
| 4502 | jobstate = JOBDONE; | 4510 | jobstate = JOBDONE; |
| 4503 | ps = jp->ps; | 4511 | spend = jp->ps + jp->nprocs; |
| 4504 | psend = ps + jp->nprocs; | 4512 | sp = jp->ps; |
| 4505 | do { | 4513 | do { |
| 4506 | if (ps->ps_pid == pid) { | 4514 | if (sp->ps_pid == pid) { |
| 4507 | TRACE(("Job %d: changing status of proc %d " | 4515 | TRACE(("Job %d: changing status of proc %d from 0x%x to 0x%x\n", jobno(jp), pid, sp->ps_status, status)); |
| 4508 | "from 0x%x to 0x%x\n", | 4516 | sp->ps_status = status; |
| 4509 | jobno(jp), pid, ps->ps_status, status)); | ||
| 4510 | ps->ps_status = status; | ||
| 4511 | thisjob = jp; | 4517 | thisjob = jp; |
| 4512 | } | 4518 | } |
| 4513 | if (ps->ps_status == -1) | 4519 | if (sp->ps_status == -1) |
| 4514 | jobstate = JOBRUNNING; | 4520 | jobstate = JOBRUNNING; |
| 4515 | #if JOBS | 4521 | #if JOBS |
| 4516 | if (jobstate == JOBRUNNING) | 4522 | if (jobstate == JOBRUNNING) |
| 4517 | continue; | 4523 | continue; |
| 4518 | if (WIFSTOPPED(ps->ps_status)) { | 4524 | if (WIFSTOPPED(sp->ps_status)) { |
| 4519 | jp->stopstatus = ps->ps_status; | 4525 | jp->stopstatus = sp->ps_status; |
| 4520 | jobstate = JOBSTOPPED; | 4526 | jobstate = JOBSTOPPED; |
| 4521 | } | 4527 | } |
| 4522 | #endif | 4528 | #endif |
| 4523 | } while (++ps < psend); | 4529 | } while (++sp < spend); |
| 4524 | if (!thisjob) | 4530 | if (!thisjob) |
| 4525 | continue; | 4531 | continue; |
| 4526 | 4532 | ||
| @@ -4532,8 +4538,7 @@ waitone(int block, struct job *job) | |||
| 4532 | */ | 4538 | */ |
| 4533 | thisjob->changed = 1; | 4539 | thisjob->changed = 1; |
| 4534 | if (thisjob->state != jobstate) { | 4540 | if (thisjob->state != jobstate) { |
| 4535 | TRACE(("Job %d: changing state from %d to %d\n", | 4541 | TRACE(("Job %d: changing state from %d to %d\n", jobno(thisjob), thisjob->state, jobstate)); |
| 4536 | jobno(thisjob), thisjob->state, jobstate)); | ||
| 4537 | thisjob->state = jobstate; | 4542 | thisjob->state = jobstate; |
| 4538 | #if JOBS | 4543 | #if JOBS |
| 4539 | if (jobstate == JOBSTOPPED) | 4544 | if (jobstate == JOBSTOPPED) |
| @@ -4568,8 +4573,7 @@ waitone(int block, struct job *job) | |||
| 4568 | return pid; | 4573 | return pid; |
| 4569 | } | 4574 | } |
| 4570 | 4575 | ||
| 4571 | static int | 4576 | static int dowait(int block, struct job *jp) |
| 4572 | dowait(int block, struct job *jp) | ||
| 4573 | { | 4577 | { |
| 4574 | smallint gotchld = *(volatile smallint *)&gotsigchld; | 4578 | smallint gotchld = *(volatile smallint *)&gotsigchld; |
| 4575 | int rpid; | 4579 | int rpid; |
| @@ -4795,9 +4799,9 @@ waitcmd(int argc UNUSED_PARAM, char **argv) | |||
| 4795 | * the trap is executed." | 4799 | * the trap is executed." |
| 4796 | */ | 4800 | */ |
| 4797 | #if BASH_WAIT_N | 4801 | #if BASH_WAIT_N |
| 4798 | status = dowait(DOWAIT_BLOCK_OR_SIG | DOWAIT_JOBSTATUS, NULL); | 4802 | status = dowait(DOWAIT_CHILD_OR_SIG | DOWAIT_JOBSTATUS, NULL); |
| 4799 | #else | 4803 | #else |
| 4800 | dowait(DOWAIT_BLOCK_OR_SIG, NULL); | 4804 | dowait(DOWAIT_CHILD_OR_SIG, NULL); |
| 4801 | #endif | 4805 | #endif |
| 4802 | /* if child sends us a signal *and immediately exits*, | 4806 | /* if child sends us a signal *and immediately exits*, |
| 4803 | * dowait() returns pid > 0. Check this case, | 4807 | * dowait() returns pid > 0. Check this case, |
| @@ -4838,7 +4842,7 @@ waitcmd(int argc UNUSED_PARAM, char **argv) | |||
| 4838 | job = getjob(*argv, 0); | 4842 | job = getjob(*argv, 0); |
| 4839 | } | 4843 | } |
| 4840 | /* loop until process terminated or stopped */ | 4844 | /* loop until process terminated or stopped */ |
| 4841 | dowait(DOWAIT_BLOCK_OR_SIG, job); | 4845 | dowait(DOWAIT_CHILD_OR_SIG, job); |
| 4842 | if (pending_sig) | 4846 | if (pending_sig) |
| 4843 | goto sigout; | 4847 | goto sigout; |
| 4844 | job->waited = 1; | 4848 | job->waited = 1; |
