ash: preparatory work for pipefail and code shrink. -44 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
7a7b034482
commit
285ad155c4
125
shell/ash.c
125
shell/ash.c
@ -100,15 +100,15 @@ static const char *const optletters_optnames[] = {
|
|||||||
"a" "allexport",
|
"a" "allexport",
|
||||||
"b" "notify",
|
"b" "notify",
|
||||||
"u" "nounset",
|
"u" "nounset",
|
||||||
"\0" "vi"
|
"\0" "vi",
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
,"\0" "nolog"
|
,"\0" "nolog"
|
||||||
,"\0" "debug"
|
,"\0" "debug"
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define optletters(n) optletters_optnames[(n)][0]
|
#define optletters(n) optletters_optnames[n][0]
|
||||||
#define optnames(n) (&optletters_optnames[(n)][1])
|
#define optnames(n) (optletters_optnames[n] + 1)
|
||||||
|
|
||||||
enum { NOPTS = ARRAY_SIZE(optletters_optnames) };
|
enum { NOPTS = ARRAY_SIZE(optletters_optnames) };
|
||||||
|
|
||||||
@ -3210,9 +3210,9 @@ unaliascmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
|||||||
* array of pids.
|
* array of pids.
|
||||||
*/
|
*/
|
||||||
struct procstat {
|
struct procstat {
|
||||||
pid_t pid; /* process id */
|
pid_t ps_pid; /* process id */
|
||||||
int status; /* last process status from wait() */
|
int ps_status; /* last process status from wait() */
|
||||||
char *cmd; /* text of command being run */
|
char *ps_cmd; /* text of command being run */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct job {
|
struct job {
|
||||||
@ -3518,7 +3518,7 @@ getjob(const char *name, int getctl)
|
|||||||
|
|
||||||
found = NULL;
|
found = NULL;
|
||||||
while (jp) {
|
while (jp) {
|
||||||
if (match(jp->ps[0].cmd, p)) {
|
if (match(jp->ps[0].ps_cmd, p)) {
|
||||||
if (found)
|
if (found)
|
||||||
goto err;
|
goto err;
|
||||||
found = jp;
|
found = jp;
|
||||||
@ -3552,8 +3552,8 @@ freejob(struct job *jp)
|
|||||||
|
|
||||||
INT_OFF;
|
INT_OFF;
|
||||||
for (i = jp->nprocs, ps = jp->ps; --i >= 0; ps++) {
|
for (i = jp->nprocs, ps = jp->ps; --i >= 0; ps++) {
|
||||||
if (ps->cmd != nullstr)
|
if (ps->ps_cmd != nullstr)
|
||||||
free(ps->cmd);
|
free(ps->ps_cmd);
|
||||||
}
|
}
|
||||||
if (jp->ps != &jp->ps0)
|
if (jp->ps != &jp->ps0)
|
||||||
free(jp->ps);
|
free(jp->ps);
|
||||||
@ -3655,7 +3655,7 @@ killcmd(int argc, char **argv)
|
|||||||
do {
|
do {
|
||||||
if (argv[i][0] == '%') {
|
if (argv[i][0] == '%') {
|
||||||
struct job *jp = getjob(argv[i], 0);
|
struct job *jp = getjob(argv[i], 0);
|
||||||
unsigned pid = jp->ps[0].pid;
|
unsigned pid = jp->ps[0].ps_pid;
|
||||||
/* Enough space for ' -NNN<nul>' */
|
/* Enough space for ' -NNN<nul>' */
|
||||||
argv[i] = alloca(sizeof(int)*3 + 3);
|
argv[i] = alloca(sizeof(int)*3 + 3);
|
||||||
/* kill_main has matching code to expect
|
/* kill_main has matching code to expect
|
||||||
@ -3669,15 +3669,15 @@ killcmd(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
showpipe(struct job *jp, FILE *out)
|
showpipe(struct job *jp /*, FILE *out*/)
|
||||||
{
|
{
|
||||||
struct procstat *sp;
|
struct procstat *ps;
|
||||||
struct procstat *spend;
|
struct procstat *psend;
|
||||||
|
|
||||||
spend = jp->ps + jp->nprocs;
|
psend = jp->ps + jp->nprocs;
|
||||||
for (sp = jp->ps + 1; sp < spend; sp++)
|
for (ps = jp->ps + 1; ps < psend; ps++)
|
||||||
fprintf(out, " | %s", sp->cmd);
|
printf(" | %s", ps->ps_cmd);
|
||||||
outcslow('\n', out);
|
outcslow('\n', stdout);
|
||||||
flush_stdout_stderr();
|
flush_stdout_stderr();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3694,15 +3694,15 @@ restartjob(struct job *jp, int mode)
|
|||||||
if (jp->state == JOBDONE)
|
if (jp->state == JOBDONE)
|
||||||
goto out;
|
goto out;
|
||||||
jp->state = JOBRUNNING;
|
jp->state = JOBRUNNING;
|
||||||
pgid = jp->ps->pid;
|
pgid = jp->ps[0].ps_pid;
|
||||||
if (mode == FORK_FG)
|
if (mode == FORK_FG)
|
||||||
xtcsetpgrp(ttyfd, pgid);
|
xtcsetpgrp(ttyfd, pgid);
|
||||||
killpg(pgid, SIGCONT);
|
killpg(pgid, SIGCONT);
|
||||||
ps = jp->ps;
|
ps = jp->ps;
|
||||||
i = jp->nprocs;
|
i = jp->nprocs;
|
||||||
do {
|
do {
|
||||||
if (WIFSTOPPED(ps->status)) {
|
if (WIFSTOPPED(ps->ps_status)) {
|
||||||
ps->status = -1;
|
ps->ps_status = -1;
|
||||||
}
|
}
|
||||||
ps++;
|
ps++;
|
||||||
} while (--i);
|
} while (--i);
|
||||||
@ -3716,22 +3716,20 @@ static int FAST_FUNC
|
|||||||
fg_bgcmd(int argc UNUSED_PARAM, char **argv)
|
fg_bgcmd(int argc UNUSED_PARAM, char **argv)
|
||||||
{
|
{
|
||||||
struct job *jp;
|
struct job *jp;
|
||||||
FILE *out;
|
|
||||||
int mode;
|
int mode;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
mode = (**argv == 'f') ? FORK_FG : FORK_BG;
|
mode = (**argv == 'f') ? FORK_FG : FORK_BG;
|
||||||
nextopt(nullstr);
|
nextopt(nullstr);
|
||||||
argv = argptr;
|
argv = argptr;
|
||||||
out = stdout;
|
|
||||||
do {
|
do {
|
||||||
jp = getjob(*argv, 1);
|
jp = getjob(*argv, 1);
|
||||||
if (mode == FORK_BG) {
|
if (mode == FORK_BG) {
|
||||||
set_curjob(jp, CUR_RUNNING);
|
set_curjob(jp, CUR_RUNNING);
|
||||||
fprintf(out, "[%d] ", jobno(jp));
|
printf("[%d] ", jobno(jp));
|
||||||
}
|
}
|
||||||
outstr(jp->ps->cmd, out);
|
out1str(jp->ps[0].ps_cmd);
|
||||||
showpipe(jp, out);
|
showpipe(jp /*, stdout*/);
|
||||||
retval = restartjob(jp, mode);
|
retval = restartjob(jp, mode);
|
||||||
} while (*argv && *++argv);
|
} while (*argv && *++argv);
|
||||||
return retval;
|
return retval;
|
||||||
@ -3790,8 +3788,9 @@ dowait(int wait_flags, struct job *job)
|
|||||||
/* Do a wait system call. If job control is compiled in, we accept
|
/* Do a wait system call. If job control is compiled in, we accept
|
||||||
* stopped processes. wait_flags may have WNOHANG, preventing blocking.
|
* stopped processes. wait_flags may have WNOHANG, preventing blocking.
|
||||||
* NB: _not_ safe_waitpid, we need to detect EINTR */
|
* NB: _not_ safe_waitpid, we need to detect EINTR */
|
||||||
pid = waitpid(-1, &status,
|
if (doing_jobctl)
|
||||||
(doing_jobctl ? (wait_flags | WUNTRACED) : wait_flags));
|
wait_flags |= WUNTRACED;
|
||||||
|
pid = waitpid(-1, &status, wait_flags);
|
||||||
TRACE(("wait returns pid=%d, status=0x%x, errno=%d(%s)\n",
|
TRACE(("wait returns pid=%d, status=0x%x, errno=%d(%s)\n",
|
||||||
pid, status, errno, strerror(errno)));
|
pid, status, errno, strerror(errno)));
|
||||||
if (pid <= 0)
|
if (pid <= 0)
|
||||||
@ -3800,32 +3799,32 @@ dowait(int wait_flags, struct job *job)
|
|||||||
INT_OFF;
|
INT_OFF;
|
||||||
thisjob = NULL;
|
thisjob = NULL;
|
||||||
for (jp = curjob; jp; jp = jp->prev_job) {
|
for (jp = curjob; jp; jp = jp->prev_job) {
|
||||||
struct procstat *sp;
|
struct procstat *ps;
|
||||||
struct procstat *spend;
|
struct procstat *psend;
|
||||||
if (jp->state == JOBDONE)
|
if (jp->state == JOBDONE)
|
||||||
continue;
|
continue;
|
||||||
state = JOBDONE;
|
state = JOBDONE;
|
||||||
spend = jp->ps + jp->nprocs;
|
ps = jp->ps;
|
||||||
sp = jp->ps;
|
psend = ps + jp->nprocs;
|
||||||
do {
|
do {
|
||||||
if (sp->pid == pid) {
|
if (ps->ps_pid == pid) {
|
||||||
TRACE(("Job %d: changing status of proc %d "
|
TRACE(("Job %d: changing status of proc %d "
|
||||||
"from 0x%x to 0x%x\n",
|
"from 0x%x to 0x%x\n",
|
||||||
jobno(jp), pid, sp->status, status));
|
jobno(jp), pid, ps->ps_status, status));
|
||||||
sp->status = status;
|
ps->ps_status = status;
|
||||||
thisjob = jp;
|
thisjob = jp;
|
||||||
}
|
}
|
||||||
if (sp->status == -1)
|
if (ps->ps_status == -1)
|
||||||
state = JOBRUNNING;
|
state = JOBRUNNING;
|
||||||
#if JOBS
|
#if JOBS
|
||||||
if (state == JOBRUNNING)
|
if (state == JOBRUNNING)
|
||||||
continue;
|
continue;
|
||||||
if (WIFSTOPPED(sp->status)) {
|
if (WIFSTOPPED(ps->ps_status)) {
|
||||||
jp->stopstatus = sp->status;
|
jp->stopstatus = ps->ps_status;
|
||||||
state = JOBSTOPPED;
|
state = JOBSTOPPED;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} while (++sp < spend);
|
} while (++ps < psend);
|
||||||
if (thisjob)
|
if (thisjob)
|
||||||
goto gotjob;
|
goto gotjob;
|
||||||
}
|
}
|
||||||
@ -3891,7 +3890,7 @@ showjob(FILE *out, struct job *jp, int mode)
|
|||||||
|
|
||||||
if (mode & SHOW_ONLY_PGID) { /* jobs -p */
|
if (mode & SHOW_ONLY_PGID) { /* jobs -p */
|
||||||
/* just output process (group) id of pipeline */
|
/* just output process (group) id of pipeline */
|
||||||
fprintf(out, "%d\n", ps->pid);
|
fprintf(out, "%d\n", ps->ps_pid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3904,7 +3903,7 @@ showjob(FILE *out, struct job *jp, int mode)
|
|||||||
s[col - 3] = '-';
|
s[col - 3] = '-';
|
||||||
|
|
||||||
if (mode & SHOW_PIDS)
|
if (mode & SHOW_PIDS)
|
||||||
col += fmtstr(s + col, 16, "%d ", ps->pid);
|
col += fmtstr(s + col, 16, "%d ", ps->ps_pid);
|
||||||
|
|
||||||
psend = ps + jp->nprocs;
|
psend = ps + jp->nprocs;
|
||||||
|
|
||||||
@ -3912,7 +3911,7 @@ showjob(FILE *out, struct job *jp, int mode)
|
|||||||
strcpy(s + col, "Running");
|
strcpy(s + col, "Running");
|
||||||
col += sizeof("Running") - 1;
|
col += sizeof("Running") - 1;
|
||||||
} else {
|
} else {
|
||||||
int status = psend[-1].status;
|
int status = psend[-1].ps_status;
|
||||||
if (jp->state == JOBSTOPPED)
|
if (jp->state == JOBSTOPPED)
|
||||||
status = jp->stopstatus;
|
status = jp->stopstatus;
|
||||||
col += sprint_status(s + col, status, 0);
|
col += sprint_status(s + col, status, 0);
|
||||||
@ -3928,20 +3927,20 @@ showjob(FILE *out, struct job *jp, int mode)
|
|||||||
* making it impossible to know 1st process status.
|
* making it impossible to know 1st process status.
|
||||||
*/
|
*/
|
||||||
goto start;
|
goto start;
|
||||||
while (1) {
|
do {
|
||||||
/* for each process */
|
/* for each process */
|
||||||
s[0] = '\0';
|
s[0] = '\0';
|
||||||
col = 33;
|
col = 33;
|
||||||
if (mode & SHOW_PIDS)
|
if (mode & SHOW_PIDS)
|
||||||
col = fmtstr(s, 48, "\n%*c%d ", indent_col, ' ', ps->pid) - 1;
|
col = fmtstr(s, 48, "\n%*c%d ", indent_col, ' ', ps->ps_pid) - 1;
|
||||||
start:
|
start:
|
||||||
fprintf(out, "%s%*c", s, 33 - col >= 0 ? 33 - col : 0, ' ');
|
fprintf(out, "%s%*c%s%s",
|
||||||
if (ps != jp->ps)
|
s,
|
||||||
fprintf(out, "| ");
|
33 - col >= 0 ? 33 - col : 0, ' ',
|
||||||
fprintf(out, "%s", ps->cmd);
|
ps == jp->ps ? "" : "| ",
|
||||||
if (++ps == psend)
|
ps->ps_cmd
|
||||||
break;
|
);
|
||||||
}
|
} while (++ps != psend);
|
||||||
outcslow('\n', out);
|
outcslow('\n', out);
|
||||||
|
|
||||||
jp->changed = 0;
|
jp->changed = 0;
|
||||||
@ -3992,8 +3991,9 @@ jobscmd(int argc UNUSED_PARAM, char **argv)
|
|||||||
do
|
do
|
||||||
showjob(stdout, getjob(*argv, 0), mode);
|
showjob(stdout, getjob(*argv, 0), mode);
|
||||||
while (*++argv);
|
while (*++argv);
|
||||||
} else
|
} else {
|
||||||
showjobs(stdout, mode);
|
showjobs(stdout, mode);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -4005,7 +4005,7 @@ getstatus(struct job *job)
|
|||||||
int status;
|
int status;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
status = job->ps[job->nprocs - 1].status;
|
status = job->ps[job->nprocs - 1].ps_status;
|
||||||
retval = WEXITSTATUS(status);
|
retval = WEXITSTATUS(status);
|
||||||
if (!WIFEXITED(status)) {
|
if (!WIFEXITED(status)) {
|
||||||
#if JOBS
|
#if JOBS
|
||||||
@ -4072,7 +4072,7 @@ waitcmd(int argc UNUSED_PARAM, char **argv)
|
|||||||
while (1) {
|
while (1) {
|
||||||
if (!job)
|
if (!job)
|
||||||
goto repeat;
|
goto repeat;
|
||||||
if (job->ps[job->nprocs - 1].pid == pid)
|
if (job->ps[job->nprocs - 1].ps_pid == pid)
|
||||||
break;
|
break;
|
||||||
job = job->prev_job;
|
job = job->prev_job;
|
||||||
}
|
}
|
||||||
@ -4576,7 +4576,7 @@ forkchild(struct job *jp, union node *n, int mode)
|
|||||||
if (jp->nprocs == 0)
|
if (jp->nprocs == 0)
|
||||||
pgrp = getpid();
|
pgrp = getpid();
|
||||||
else
|
else
|
||||||
pgrp = jp->ps[0].pid;
|
pgrp = jp->ps[0].ps_pid;
|
||||||
/* this can fail because we are doing it in the parent also */
|
/* this can fail because we are doing it in the parent also */
|
||||||
setpgid(0, pgrp);
|
setpgid(0, pgrp);
|
||||||
if (mode == FORK_FG)
|
if (mode == FORK_FG)
|
||||||
@ -4648,7 +4648,7 @@ forkparent(struct job *jp, union node *n, int mode, pid_t pid)
|
|||||||
if (jp->nprocs == 0)
|
if (jp->nprocs == 0)
|
||||||
pgrp = pid;
|
pgrp = pid;
|
||||||
else
|
else
|
||||||
pgrp = jp->ps[0].pid;
|
pgrp = jp->ps[0].ps_pid;
|
||||||
/* This can fail because we are doing it in the child also */
|
/* This can fail because we are doing it in the child also */
|
||||||
setpgid(pid, pgrp);
|
setpgid(pid, pgrp);
|
||||||
}
|
}
|
||||||
@ -4659,12 +4659,12 @@ forkparent(struct job *jp, union node *n, int mode, pid_t pid)
|
|||||||
}
|
}
|
||||||
if (jp) {
|
if (jp) {
|
||||||
struct procstat *ps = &jp->ps[jp->nprocs++];
|
struct procstat *ps = &jp->ps[jp->nprocs++];
|
||||||
ps->pid = pid;
|
ps->ps_pid = pid;
|
||||||
ps->status = -1;
|
ps->ps_status = -1;
|
||||||
ps->cmd = nullstr;
|
ps->ps_cmd = nullstr;
|
||||||
#if JOBS
|
#if JOBS
|
||||||
if (doing_jobctl && n)
|
if (doing_jobctl && n)
|
||||||
ps->cmd = commandtext(n);
|
ps->ps_cmd = commandtext(n);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7683,7 +7683,7 @@ describe_command(char *command, int describe_command_verbose)
|
|||||||
return 127;
|
return 127;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
outstr("\n", stdout);
|
out1str("\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11852,8 +11852,9 @@ evalcmd(int argc UNUSED_PARAM, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read and execute commands. "Top" is nonzero for the top level command
|
* Read and execute commands.
|
||||||
* loop; it turns on prompting if the shell is interactive.
|
* "Top" is nonzero for the top level command loop;
|
||||||
|
* it turns on prompting if the shell is interactive.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
cmdloop(int top)
|
cmdloop(int top)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user