75 |
/* mode flags for dowait */ |
/* mode flags for dowait */ |
76 |
#define DOWAIT_NORMAL 0 |
#define DOWAIT_NORMAL 0 |
77 |
#define DOWAIT_BLOCK 1 |
#define DOWAIT_BLOCK 1 |
78 |
|
#define DOWAIT_WAITCMD 2 |
79 |
|
|
80 |
/* array of jobs */ |
/* array of jobs */ |
81 |
static struct job *jobtab; |
static struct job *jobtab; |
189 |
if (on == jobctl || rootshell == 0) |
if (on == jobctl || rootshell == 0) |
190 |
return; |
return; |
191 |
if (on) { |
if (on) { |
192 |
fd = open(_PATH_TTY, O_RDWR); |
int ofd; |
193 |
|
ofd = fd = open(_PATH_TTY, O_RDWR); |
194 |
if (fd < 0) { |
if (fd < 0) { |
195 |
fd += 3; |
fd += 3; |
196 |
while (!isatty(fd)) |
while (!isatty(fd)) |
197 |
if (--fd < 0) |
if (--fd < 0) |
198 |
goto out; |
goto out; |
199 |
} |
} |
200 |
fd = savefd(fd); |
fd = savefd(fd, ofd); |
201 |
do { /* while we are in the background */ |
do { /* while we are in the background */ |
202 |
if ((pgrp = tcgetpgrp(fd)) < 0) { |
if ((pgrp = tcgetpgrp(fd)) < 0) { |
203 |
out: |
out: |
362 |
return retval; |
return retval; |
363 |
} |
} |
364 |
|
|
365 |
int bgcmd(int, char **) __attribute__((__alias__("fgcmd"))); |
int bgcmd(int argc, char **argv) |
366 |
|
#ifdef HAVE_ALIAS_ATTRIBUTE |
367 |
|
__attribute__((__alias__("fgcmd"))); |
368 |
|
#else |
369 |
|
{ |
370 |
|
return fgcmd(argc, argv); |
371 |
|
} |
372 |
|
#endif |
373 |
|
|
374 |
|
|
375 |
STATIC int |
STATIC int |
590 |
int retval; |
int retval; |
591 |
struct job *jp; |
struct job *jp; |
592 |
|
|
|
EXSIGON(); |
|
|
|
|
593 |
nextopt(nullstr); |
nextopt(nullstr); |
594 |
retval = 0; |
retval = 0; |
595 |
|
|
608 |
jp->waited = 1; |
jp->waited = 1; |
609 |
jp = jp->prev_job; |
jp = jp->prev_job; |
610 |
} |
} |
611 |
dowait(DOWAIT_BLOCK, 0); |
if (dowait(DOWAIT_WAITCMD, 0) <= 0) |
612 |
|
goto sigout; |
613 |
} |
} |
614 |
} |
} |
615 |
|
|
631 |
job = getjob(*argv, 0); |
job = getjob(*argv, 0); |
632 |
/* loop until process terminated or stopped */ |
/* loop until process terminated or stopped */ |
633 |
while (job->state == JOBRUNNING) |
while (job->state == JOBRUNNING) |
634 |
dowait(DOWAIT_BLOCK, 0); |
if (dowait(DOWAIT_WAITCMD, 0) <= 0) |
635 |
|
goto sigout; |
636 |
job->waited = 1; |
job->waited = 1; |
637 |
retval = getstatus(job); |
retval = getstatus(job); |
638 |
repeat: |
repeat: |
641 |
|
|
642 |
out: |
out: |
643 |
return retval; |
return retval; |
644 |
|
|
645 |
|
sigout: |
646 |
|
retval = 128 + pendingsigs; |
647 |
|
goto out; |
648 |
} |
} |
649 |
|
|
650 |
|
|
1003 |
int pid; |
int pid; |
1004 |
int status; |
int status; |
1005 |
struct job *jp; |
struct job *jp; |
1006 |
struct job *thisjob; |
struct job *thisjob = NULL; |
1007 |
int state; |
int state; |
1008 |
|
|
1009 |
|
INTOFF; |
1010 |
TRACE(("dowait(%d) called\n", block)); |
TRACE(("dowait(%d) called\n", block)); |
1011 |
pid = waitproc(block, &status); |
pid = waitproc(block, &status); |
1012 |
TRACE(("wait returns pid %d, status=%d\n", pid, status)); |
TRACE(("wait returns pid %d, status=%d\n", pid, status)); |
1013 |
if (pid <= 0) |
if (pid <= 0) |
1014 |
return pid; |
goto out; |
1015 |
INTOFF; |
|
|
thisjob = NULL; |
|
1016 |
for (jp = curjob; jp; jp = jp->prev_job) { |
for (jp = curjob; jp; jp = jp->prev_job) { |
1017 |
struct procstat *sp; |
struct procstat *sp; |
1018 |
struct procstat *spend; |
struct procstat *spend; |
1120 |
STATIC int |
STATIC int |
1121 |
waitproc(int block, int *status) |
waitproc(int block, int *status) |
1122 |
{ |
{ |
1123 |
#ifdef BSD |
sigset_t mask, oldmask; |
1124 |
int flags = 0; |
int flags = block == DOWAIT_BLOCK ? 0 : WNOHANG; |
1125 |
|
int err; |
1126 |
|
int sig; |
1127 |
|
|
1128 |
#if JOBS |
#if JOBS |
1129 |
if (jobctl) |
if (jobctl) |
1130 |
flags |= WUNTRACED; |
flags |= WUNTRACED; |
1131 |
#endif |
#endif |
|
if (block == 0) |
|
|
flags |= WNOHANG; |
|
|
return wait3(status, flags, (struct rusage *)NULL); |
|
|
#else |
|
|
#ifdef SYSV |
|
|
int (*save)(); |
|
1132 |
|
|
1133 |
if (block == 0) { |
do { |
1134 |
gotsigchild = 0; |
err = wait3(status, flags, NULL); |
1135 |
save = signal(SIGCLD, onsigchild); |
if (err || !block) |
1136 |
signal(SIGCLD, save); |
break; |
1137 |
if (gotsigchild == 0) |
|
1138 |
return 0; |
block = 0; |
1139 |
} |
|
1140 |
return wait(status); |
sigfillset(&mask); |
1141 |
#else |
sigprocmask(SIG_SETMASK, &mask, &oldmask); |
1142 |
if (block == 0) |
|
1143 |
return 0; |
while (!(sig = pendingsigs)) |
1144 |
return wait(status); |
sigsuspend(&oldmask); |
1145 |
#endif |
|
1146 |
#endif |
sigclearmask(); |
1147 |
|
} while (sig == SIGCHLD); |
1148 |
|
|
1149 |
|
return err; |
1150 |
} |
} |
1151 |
|
|
1152 |
/* |
/* |
1246 |
cmdputs("if "); |
cmdputs("if "); |
1247 |
cmdtxt(n->nif.test); |
cmdtxt(n->nif.test); |
1248 |
cmdputs("; then "); |
cmdputs("; then "); |
|
n = n->nif.ifpart; |
|
1249 |
if (n->nif.elsepart) { |
if (n->nif.elsepart) { |
1250 |
cmdtxt(n); |
cmdtxt(n->nif.ifpart); |
1251 |
cmdputs("; else "); |
cmdputs("; else "); |
1252 |
n = n->nif.elsepart; |
n = n->nif.elsepart; |
1253 |
|
} else { |
1254 |
|
n = n->nif.ifpart; |
1255 |
} |
} |
1256 |
p = "; fi"; |
p = "; fi"; |
1257 |
goto dotail; |
goto dotail; |
1389 |
str = "${#"; |
str = "${#"; |
1390 |
else |
else |
1391 |
str = "${"; |
str = "${"; |
1392 |
if (!(subtype & VSQUOTE) != !(quoted & 1)) { |
goto dostr; |
|
quoted ^= 1; |
|
|
c = '"'; |
|
|
} else |
|
|
goto dostr; |
|
|
break; |
|
1393 |
case CTLENDVAR: |
case CTLENDVAR: |
1394 |
str = "\"}" + !(quoted & 1); |
str = "\"}" + !(quoted & 1); |
1395 |
quoted >>= 1; |
quoted >>= 1; |
1398 |
case CTLBACKQ: |
case CTLBACKQ: |
1399 |
str = "$(...)"; |
str = "$(...)"; |
1400 |
goto dostr; |
goto dostr; |
|
case CTLBACKQ+CTLQUOTE: |
|
|
str = "\"$(...)\""; |
|
|
goto dostr; |
|
1401 |
case CTLARI: |
case CTLARI: |
1402 |
str = "$(("; |
str = "$(("; |
1403 |
goto dostr; |
goto dostr; |