diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-12-04 23:02:27 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-12-04 23:02:27 +0100 |
commit | 285ad155c4769e4a37a936826ba41e402f7d863b (patch) | |
tree | 71cd00cf6fe40faf5a0405cfdaace39367c5e975 | |
parent | 7a7b034482b1ecf4f9924160757339958f1f95d1 (diff) | |
download | busybox-w32-285ad155c4769e4a37a936826ba41e402f7d863b.tar.gz busybox-w32-285ad155c4769e4a37a936826ba41e402f7d863b.tar.bz2 busybox-w32-285ad155c4769e4a37a936826ba41e402f7d863b.zip |
ash: preparatory work for pipefail and code shrink. -44 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/ash.c | 129 |
1 files changed, 65 insertions, 64 deletions
diff --git a/shell/ash.c b/shell/ash.c index 5d0fc6d29..65d41cc5b 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -100,15 +100,15 @@ static const char *const optletters_optnames[] = { | |||
100 | "a" "allexport", | 100 | "a" "allexport", |
101 | "b" "notify", | 101 | "b" "notify", |
102 | "u" "nounset", | 102 | "u" "nounset", |
103 | "\0" "vi" | 103 | "\0" "vi", |
104 | #if DEBUG | 104 | #if DEBUG |
105 | ,"\0" "nolog" | 105 | ,"\0" "nolog" |
106 | ,"\0" "debug" | 106 | ,"\0" "debug" |
107 | #endif | 107 | #endif |
108 | }; | 108 | }; |
109 | 109 | ||
110 | #define optletters(n) optletters_optnames[(n)][0] | 110 | #define optletters(n) optletters_optnames[n][0] |
111 | #define optnames(n) (&optletters_optnames[(n)][1]) | 111 | #define optnames(n) (optletters_optnames[n] + 1) |
112 | 112 | ||
113 | enum { NOPTS = ARRAY_SIZE(optletters_optnames) }; | 113 | enum { NOPTS = ARRAY_SIZE(optletters_optnames) }; |
114 | 114 | ||
@@ -3194,8 +3194,8 @@ unaliascmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
3194 | /* ============ jobs.c */ | 3194 | /* ============ jobs.c */ |
3195 | 3195 | ||
3196 | /* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */ | 3196 | /* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */ |
3197 | #define FORK_FG 0 | 3197 | #define FORK_FG 0 |
3198 | #define FORK_BG 1 | 3198 | #define FORK_BG 1 |
3199 | #define FORK_NOJOB 2 | 3199 | #define FORK_NOJOB 2 |
3200 | 3200 | ||
3201 | /* mode flags for showjob(s) */ | 3201 | /* mode flags for showjob(s) */ |
@@ -3210,9 +3210,9 @@ unaliascmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
3210 | * array of pids. | 3210 | * array of pids. |
3211 | */ | 3211 | */ |
3212 | struct procstat { | 3212 | struct procstat { |
3213 | pid_t pid; /* process id */ | 3213 | pid_t ps_pid; /* process id */ |
3214 | int status; /* last process status from wait() */ | 3214 | int ps_status; /* last process status from wait() */ |
3215 | char *cmd; /* text of command being run */ | 3215 | char *ps_cmd; /* text of command being run */ |
3216 | }; | 3216 | }; |
3217 | 3217 | ||
3218 | struct job { | 3218 | struct job { |
@@ -3518,7 +3518,7 @@ getjob(const char *name, int getctl) | |||
3518 | 3518 | ||
3519 | found = NULL; | 3519 | found = NULL; |
3520 | while (jp) { | 3520 | while (jp) { |
3521 | if (match(jp->ps[0].cmd, p)) { | 3521 | if (match(jp->ps[0].ps_cmd, p)) { |
3522 | if (found) | 3522 | if (found) |
3523 | goto err; | 3523 | goto err; |
3524 | found = jp; | 3524 | found = jp; |
@@ -3552,8 +3552,8 @@ freejob(struct job *jp) | |||
3552 | 3552 | ||
3553 | INT_OFF; | 3553 | INT_OFF; |
3554 | for (i = jp->nprocs, ps = jp->ps; --i >= 0; ps++) { | 3554 | for (i = jp->nprocs, ps = jp->ps; --i >= 0; ps++) { |
3555 | if (ps->cmd != nullstr) | 3555 | if (ps->ps_cmd != nullstr) |
3556 | free(ps->cmd); | 3556 | free(ps->ps_cmd); |
3557 | } | 3557 | } |
3558 | if (jp->ps != &jp->ps0) | 3558 | if (jp->ps != &jp->ps0) |
3559 | free(jp->ps); | 3559 | free(jp->ps); |
@@ -3655,7 +3655,7 @@ killcmd(int argc, char **argv) | |||
3655 | do { | 3655 | do { |
3656 | if (argv[i][0] == '%') { | 3656 | if (argv[i][0] == '%') { |
3657 | struct job *jp = getjob(argv[i], 0); | 3657 | struct job *jp = getjob(argv[i], 0); |
3658 | unsigned pid = jp->ps[0].pid; | 3658 | unsigned pid = jp->ps[0].ps_pid; |
3659 | /* Enough space for ' -NNN<nul>' */ | 3659 | /* Enough space for ' -NNN<nul>' */ |
3660 | argv[i] = alloca(sizeof(int)*3 + 3); | 3660 | argv[i] = alloca(sizeof(int)*3 + 3); |
3661 | /* kill_main has matching code to expect | 3661 | /* kill_main has matching code to expect |
@@ -3669,15 +3669,15 @@ killcmd(int argc, char **argv) | |||
3669 | } | 3669 | } |
3670 | 3670 | ||
3671 | static void | 3671 | static void |
3672 | showpipe(struct job *jp, FILE *out) | 3672 | showpipe(struct job *jp /*, FILE *out*/) |
3673 | { | 3673 | { |
3674 | struct procstat *sp; | 3674 | struct procstat *ps; |
3675 | struct procstat *spend; | 3675 | struct procstat *psend; |
3676 | 3676 | ||
3677 | spend = jp->ps + jp->nprocs; | 3677 | psend = jp->ps + jp->nprocs; |
3678 | for (sp = jp->ps + 1; sp < spend; sp++) | 3678 | for (ps = jp->ps + 1; ps < psend; ps++) |
3679 | fprintf(out, " | %s", sp->cmd); | 3679 | printf(" | %s", ps->ps_cmd); |
3680 | outcslow('\n', out); | 3680 | outcslow('\n', stdout); |
3681 | flush_stdout_stderr(); | 3681 | flush_stdout_stderr(); |
3682 | } | 3682 | } |
3683 | 3683 | ||
@@ -3694,15 +3694,15 @@ restartjob(struct job *jp, int mode) | |||
3694 | if (jp->state == JOBDONE) | 3694 | if (jp->state == JOBDONE) |
3695 | goto out; | 3695 | goto out; |
3696 | jp->state = JOBRUNNING; | 3696 | jp->state = JOBRUNNING; |
3697 | pgid = jp->ps->pid; | 3697 | pgid = jp->ps[0].ps_pid; |
3698 | if (mode == FORK_FG) | 3698 | if (mode == FORK_FG) |
3699 | xtcsetpgrp(ttyfd, pgid); | 3699 | xtcsetpgrp(ttyfd, pgid); |
3700 | killpg(pgid, SIGCONT); | 3700 | killpg(pgid, SIGCONT); |
3701 | ps = jp->ps; | 3701 | ps = jp->ps; |
3702 | i = jp->nprocs; | 3702 | i = jp->nprocs; |
3703 | do { | 3703 | do { |
3704 | if (WIFSTOPPED(ps->status)) { | 3704 | if (WIFSTOPPED(ps->ps_status)) { |
3705 | ps->status = -1; | 3705 | ps->ps_status = -1; |
3706 | } | 3706 | } |
3707 | ps++; | 3707 | ps++; |
3708 | } while (--i); | 3708 | } while (--i); |
@@ -3716,22 +3716,20 @@ static int FAST_FUNC | |||
3716 | fg_bgcmd(int argc UNUSED_PARAM, char **argv) | 3716 | fg_bgcmd(int argc UNUSED_PARAM, char **argv) |
3717 | { | 3717 | { |
3718 | struct job *jp; | 3718 | struct job *jp; |
3719 | FILE *out; | ||
3720 | int mode; | 3719 | int mode; |
3721 | int retval; | 3720 | int retval; |
3722 | 3721 | ||
3723 | mode = (**argv == 'f') ? FORK_FG : FORK_BG; | 3722 | mode = (**argv == 'f') ? FORK_FG : FORK_BG; |
3724 | nextopt(nullstr); | 3723 | nextopt(nullstr); |
3725 | argv = argptr; | 3724 | argv = argptr; |
3726 | out = stdout; | ||
3727 | do { | 3725 | do { |
3728 | jp = getjob(*argv, 1); | 3726 | jp = getjob(*argv, 1); |
3729 | if (mode == FORK_BG) { | 3727 | if (mode == FORK_BG) { |
3730 | set_curjob(jp, CUR_RUNNING); | 3728 | set_curjob(jp, CUR_RUNNING); |
3731 | fprintf(out, "[%d] ", jobno(jp)); | 3729 | printf("[%d] ", jobno(jp)); |
3732 | } | 3730 | } |
3733 | outstr(jp->ps->cmd, out); | 3731 | out1str(jp->ps[0].ps_cmd); |
3734 | showpipe(jp, out); | 3732 | showpipe(jp /*, stdout*/); |
3735 | retval = restartjob(jp, mode); | 3733 | retval = restartjob(jp, mode); |
3736 | } while (*argv && *++argv); | 3734 | } while (*argv && *++argv); |
3737 | return retval; | 3735 | return retval; |
@@ -3790,8 +3788,9 @@ dowait(int wait_flags, struct job *job) | |||
3790 | /* Do a wait system call. If job control is compiled in, we accept | 3788 | /* Do a wait system call. If job control is compiled in, we accept |
3791 | * stopped processes. wait_flags may have WNOHANG, preventing blocking. | 3789 | * stopped processes. wait_flags may have WNOHANG, preventing blocking. |
3792 | * NB: _not_ safe_waitpid, we need to detect EINTR */ | 3790 | * NB: _not_ safe_waitpid, we need to detect EINTR */ |
3793 | pid = waitpid(-1, &status, | 3791 | if (doing_jobctl) |
3794 | (doing_jobctl ? (wait_flags | WUNTRACED) : wait_flags)); | 3792 | wait_flags |= WUNTRACED; |
3793 | pid = waitpid(-1, &status, wait_flags); | ||
3795 | TRACE(("wait returns pid=%d, status=0x%x, errno=%d(%s)\n", | 3794 | TRACE(("wait returns pid=%d, status=0x%x, errno=%d(%s)\n", |
3796 | pid, status, errno, strerror(errno))); | 3795 | pid, status, errno, strerror(errno))); |
3797 | if (pid <= 0) | 3796 | if (pid <= 0) |
@@ -3800,32 +3799,32 @@ dowait(int wait_flags, struct job *job) | |||
3800 | INT_OFF; | 3799 | INT_OFF; |
3801 | thisjob = NULL; | 3800 | thisjob = NULL; |
3802 | for (jp = curjob; jp; jp = jp->prev_job) { | 3801 | for (jp = curjob; jp; jp = jp->prev_job) { |
3803 | struct procstat *sp; | 3802 | struct procstat *ps; |
3804 | struct procstat *spend; | 3803 | struct procstat *psend; |
3805 | if (jp->state == JOBDONE) | 3804 | if (jp->state == JOBDONE) |
3806 | continue; | 3805 | continue; |
3807 | state = JOBDONE; | 3806 | state = JOBDONE; |
3808 | spend = jp->ps + jp->nprocs; | 3807 | ps = jp->ps; |
3809 | sp = jp->ps; | 3808 | psend = ps + jp->nprocs; |
3810 | do { | 3809 | do { |
3811 | if (sp->pid == pid) { | 3810 | if (ps->ps_pid == pid) { |
3812 | TRACE(("Job %d: changing status of proc %d " | 3811 | TRACE(("Job %d: changing status of proc %d " |
3813 | "from 0x%x to 0x%x\n", | 3812 | "from 0x%x to 0x%x\n", |
3814 | jobno(jp), pid, sp->status, status)); | 3813 | jobno(jp), pid, ps->ps_status, status)); |
3815 | sp->status = status; | 3814 | ps->ps_status = status; |
3816 | thisjob = jp; | 3815 | thisjob = jp; |
3817 | } | 3816 | } |
3818 | if (sp->status == -1) | 3817 | if (ps->ps_status == -1) |
3819 | state = JOBRUNNING; | 3818 | state = JOBRUNNING; |
3820 | #if JOBS | 3819 | #if JOBS |
3821 | if (state == JOBRUNNING) | 3820 | if (state == JOBRUNNING) |
3822 | continue; | 3821 | continue; |
3823 | if (WIFSTOPPED(sp->status)) { | 3822 | if (WIFSTOPPED(ps->ps_status)) { |
3824 | jp->stopstatus = sp->status; | 3823 | jp->stopstatus = ps->ps_status; |
3825 | state = JOBSTOPPED; | 3824 | state = JOBSTOPPED; |
3826 | } | 3825 | } |
3827 | #endif | 3826 | #endif |
3828 | } while (++sp < spend); | 3827 | } while (++ps < psend); |
3829 | if (thisjob) | 3828 | if (thisjob) |
3830 | goto gotjob; | 3829 | goto gotjob; |
3831 | } | 3830 | } |
@@ -3891,7 +3890,7 @@ showjob(FILE *out, struct job *jp, int mode) | |||
3891 | 3890 | ||
3892 | if (mode & SHOW_ONLY_PGID) { /* jobs -p */ | 3891 | if (mode & SHOW_ONLY_PGID) { /* jobs -p */ |
3893 | /* just output process (group) id of pipeline */ | 3892 | /* just output process (group) id of pipeline */ |
3894 | fprintf(out, "%d\n", ps->pid); | 3893 | fprintf(out, "%d\n", ps->ps_pid); |
3895 | return; | 3894 | return; |
3896 | } | 3895 | } |
3897 | 3896 | ||
@@ -3904,7 +3903,7 @@ showjob(FILE *out, struct job *jp, int mode) | |||
3904 | s[col - 3] = '-'; | 3903 | s[col - 3] = '-'; |
3905 | 3904 | ||
3906 | if (mode & SHOW_PIDS) | 3905 | if (mode & SHOW_PIDS) |
3907 | col += fmtstr(s + col, 16, "%d ", ps->pid); | 3906 | col += fmtstr(s + col, 16, "%d ", ps->ps_pid); |
3908 | 3907 | ||
3909 | psend = ps + jp->nprocs; | 3908 | psend = ps + jp->nprocs; |
3910 | 3909 | ||
@@ -3912,7 +3911,7 @@ showjob(FILE *out, struct job *jp, int mode) | |||
3912 | strcpy(s + col, "Running"); | 3911 | strcpy(s + col, "Running"); |
3913 | col += sizeof("Running") - 1; | 3912 | col += sizeof("Running") - 1; |
3914 | } else { | 3913 | } else { |
3915 | int status = psend[-1].status; | 3914 | int status = psend[-1].ps_status; |
3916 | if (jp->state == JOBSTOPPED) | 3915 | if (jp->state == JOBSTOPPED) |
3917 | status = jp->stopstatus; | 3916 | status = jp->stopstatus; |
3918 | col += sprint_status(s + col, status, 0); | 3917 | col += sprint_status(s + col, status, 0); |
@@ -3928,20 +3927,20 @@ showjob(FILE *out, struct job *jp, int mode) | |||
3928 | * making it impossible to know 1st process status. | 3927 | * making it impossible to know 1st process status. |
3929 | */ | 3928 | */ |
3930 | goto start; | 3929 | goto start; |
3931 | while (1) { | 3930 | do { |
3932 | /* for each process */ | 3931 | /* for each process */ |
3933 | s[0] = '\0'; | 3932 | s[0] = '\0'; |
3934 | col = 33; | 3933 | col = 33; |
3935 | if (mode & SHOW_PIDS) | 3934 | if (mode & SHOW_PIDS) |
3936 | col = fmtstr(s, 48, "\n%*c%d ", indent_col, ' ', ps->pid) - 1; | 3935 | col = fmtstr(s, 48, "\n%*c%d ", indent_col, ' ', ps->ps_pid) - 1; |
3937 | start: | 3936 | start: |
3938 | fprintf(out, "%s%*c", s, 33 - col >= 0 ? 33 - col : 0, ' '); | 3937 | fprintf(out, "%s%*c%s%s", |
3939 | if (ps != jp->ps) | 3938 | s, |
3940 | fprintf(out, "| "); | 3939 | 33 - col >= 0 ? 33 - col : 0, ' ', |
3941 | fprintf(out, "%s", ps->cmd); | 3940 | ps == jp->ps ? "" : "| ", |
3942 | if (++ps == psend) | 3941 | ps->ps_cmd |
3943 | break; | 3942 | ); |
3944 | } | 3943 | } while (++ps != psend); |
3945 | outcslow('\n', out); | 3944 | outcslow('\n', out); |
3946 | 3945 | ||
3947 | jp->changed = 0; | 3946 | jp->changed = 0; |
@@ -3992,8 +3991,9 @@ jobscmd(int argc UNUSED_PARAM, char **argv) | |||
3992 | do | 3991 | do |
3993 | showjob(stdout, getjob(*argv, 0), mode); | 3992 | showjob(stdout, getjob(*argv, 0), mode); |
3994 | while (*++argv); | 3993 | while (*++argv); |
3995 | } else | 3994 | } else { |
3996 | showjobs(stdout, mode); | 3995 | showjobs(stdout, mode); |
3996 | } | ||
3997 | 3997 | ||
3998 | return 0; | 3998 | return 0; |
3999 | } | 3999 | } |
@@ -4005,7 +4005,7 @@ getstatus(struct job *job) | |||
4005 | int status; | 4005 | int status; |
4006 | int retval; | 4006 | int retval; |
4007 | 4007 | ||
4008 | status = job->ps[job->nprocs - 1].status; | 4008 | status = job->ps[job->nprocs - 1].ps_status; |
4009 | retval = WEXITSTATUS(status); | 4009 | retval = WEXITSTATUS(status); |
4010 | if (!WIFEXITED(status)) { | 4010 | if (!WIFEXITED(status)) { |
4011 | #if JOBS | 4011 | #if JOBS |
@@ -4072,7 +4072,7 @@ waitcmd(int argc UNUSED_PARAM, char **argv) | |||
4072 | while (1) { | 4072 | while (1) { |
4073 | if (!job) | 4073 | if (!job) |
4074 | goto repeat; | 4074 | goto repeat; |
4075 | if (job->ps[job->nprocs - 1].pid == pid) | 4075 | if (job->ps[job->nprocs - 1].ps_pid == pid) |
4076 | break; | 4076 | break; |
4077 | job = job->prev_job; | 4077 | job = job->prev_job; |
4078 | } | 4078 | } |
@@ -4576,7 +4576,7 @@ forkchild(struct job *jp, union node *n, int mode) | |||
4576 | if (jp->nprocs == 0) | 4576 | if (jp->nprocs == 0) |
4577 | pgrp = getpid(); | 4577 | pgrp = getpid(); |
4578 | else | 4578 | else |
4579 | pgrp = jp->ps[0].pid; | 4579 | pgrp = jp->ps[0].ps_pid; |
4580 | /* this can fail because we are doing it in the parent also */ | 4580 | /* this can fail because we are doing it in the parent also */ |
4581 | setpgid(0, pgrp); | 4581 | setpgid(0, pgrp); |
4582 | if (mode == FORK_FG) | 4582 | if (mode == FORK_FG) |
@@ -4648,7 +4648,7 @@ forkparent(struct job *jp, union node *n, int mode, pid_t pid) | |||
4648 | if (jp->nprocs == 0) | 4648 | if (jp->nprocs == 0) |
4649 | pgrp = pid; | 4649 | pgrp = pid; |
4650 | else | 4650 | else |
4651 | pgrp = jp->ps[0].pid; | 4651 | pgrp = jp->ps[0].ps_pid; |
4652 | /* This can fail because we are doing it in the child also */ | 4652 | /* This can fail because we are doing it in the child also */ |
4653 | setpgid(pid, pgrp); | 4653 | setpgid(pid, pgrp); |
4654 | } | 4654 | } |
@@ -4659,12 +4659,12 @@ forkparent(struct job *jp, union node *n, int mode, pid_t pid) | |||
4659 | } | 4659 | } |
4660 | if (jp) { | 4660 | if (jp) { |
4661 | struct procstat *ps = &jp->ps[jp->nprocs++]; | 4661 | struct procstat *ps = &jp->ps[jp->nprocs++]; |
4662 | ps->pid = pid; | 4662 | ps->ps_pid = pid; |
4663 | ps->status = -1; | 4663 | ps->ps_status = -1; |
4664 | ps->cmd = nullstr; | 4664 | ps->ps_cmd = nullstr; |
4665 | #if JOBS | 4665 | #if JOBS |
4666 | if (doing_jobctl && n) | 4666 | if (doing_jobctl && n) |
4667 | ps->cmd = commandtext(n); | 4667 | ps->ps_cmd = commandtext(n); |
4668 | #endif | 4668 | #endif |
4669 | } | 4669 | } |
4670 | } | 4670 | } |
@@ -7683,7 +7683,7 @@ describe_command(char *command, int describe_command_verbose) | |||
7683 | return 127; | 7683 | return 127; |
7684 | } | 7684 | } |
7685 | out: | 7685 | out: |
7686 | outstr("\n", stdout); | 7686 | out1str("\n"); |
7687 | return 0; | 7687 | return 0; |
7688 | } | 7688 | } |
7689 | 7689 | ||
@@ -11852,8 +11852,9 @@ evalcmd(int argc UNUSED_PARAM, char **argv) | |||
11852 | } | 11852 | } |
11853 | 11853 | ||
11854 | /* | 11854 | /* |
11855 | * Read and execute commands. "Top" is nonzero for the top level command | 11855 | * Read and execute commands. |
11856 | * loop; it turns on prompting if the shell is interactive. | 11856 | * "Top" is nonzero for the top level command loop; |
11857 | * it turns on prompting if the shell is interactive. | ||
11857 | */ | 11858 | */ |
11858 | static int | 11859 | static int |
11859 | cmdloop(int top) | 11860 | cmdloop(int top) |