summaryrefslogtreecommitdiffstats
path: root/bin/sh/jobs.c
diff options
context:
space:
mode:
Diffstat (limited to 'bin/sh/jobs.c')
-rw-r--r--bin/sh/jobs.c159
1 files changed, 101 insertions, 58 deletions
diff --git a/bin/sh/jobs.c b/bin/sh/jobs.c
index 93553c1..765e6a2 100644
--- a/bin/sh/jobs.c
+++ b/bin/sh/jobs.c
@@ -118,6 +118,24 @@ static void showjob(struct job *, int);
static int jobctl;
#if JOBS
+static void
+jobctl_notty(void)
+{
+ if (ttyfd >= 0) {
+ close(ttyfd);
+ ttyfd = -1;
+ }
+ if (!iflag) {
+ setsignal(SIGTSTP);
+ setsignal(SIGTTOU);
+ setsignal(SIGTTIN);
+ jobctl = 1;
+ return;
+ }
+ out2fmt_flush("sh: can't access tty; job control turned off\n");
+ mflag = 0;
+}
+
void
setjobctl(int on)
{
@@ -133,8 +151,10 @@ setjobctl(int on)
while (i <= 2 && !isatty(i))
i++;
if (i > 2 ||
- (ttyfd = fcntl(i, F_DUPFD_CLOEXEC, 10)) < 0)
- goto out;
+ (ttyfd = fcntl(i, F_DUPFD_CLOEXEC, 10)) < 0) {
+ jobctl_notty();
+ return;
+ }
}
if (ttyfd < 10) {
/*
@@ -142,9 +162,8 @@ setjobctl(int on)
* the user's redirections.
*/
if ((i = fcntl(ttyfd, F_DUPFD_CLOEXEC, 10)) < 0) {
- close(ttyfd);
- ttyfd = -1;
- goto out;
+ jobctl_notty();
+ return;
}
close(ttyfd);
ttyfd = i;
@@ -152,11 +171,15 @@ setjobctl(int on)
do { /* while we are in the background */
initialpgrp = tcgetpgrp(ttyfd);
if (initialpgrp < 0) {
-out: out2fmt_flush("sh: can't access tty; job control turned off\n");
- mflag = 0;
+ jobctl_notty();
return;
}
if (initialpgrp != getpgrp()) {
+ if (!iflag) {
+ initialpgrp = -1;
+ jobctl_notty();
+ return;
+ }
kill(0, SIGTTIN);
continue;
}
@@ -168,9 +191,11 @@ out: out2fmt_flush("sh: can't access tty; job control turned off\n");
tcsetpgrp(ttyfd, rootpid);
} else { /* turning job control off */
setpgid(0, initialpgrp);
- tcsetpgrp(ttyfd, initialpgrp);
- close(ttyfd);
- ttyfd = -1;
+ if (ttyfd >= 0) {
+ tcsetpgrp(ttyfd, initialpgrp);
+ close(ttyfd);
+ ttyfd = -1;
+ }
setsignal(SIGTSTP);
setsignal(SIGTTOU);
setsignal(SIGTTIN);
@@ -195,7 +220,8 @@ fgcmd(int argc __unused, char **argv __unused)
printjobcmd(jp);
flushout(&output);
pgrp = jp->ps[0].pid;
- tcsetpgrp(ttyfd, pgrp);
+ if (ttyfd >= 0)
+ tcsetpgrp(ttyfd, pgrp);
restartjob(jp);
jp->foreground = 1;
INTOFF;
@@ -347,13 +373,13 @@ showjob(struct job *jp, int mode)
strcat(statestr, " (core dumped)");
}
- for (ps = jp->ps ; ; ps++) { /* for each process */
+ for (ps = jp->ps ; procno > 0 ; ps++, procno--) { /* for each process */
if (mode == SHOWJOBS_PIDS || mode == SHOWJOBS_PGIDS) {
out1fmt("%d\n", (int)ps->pid);
- goto skip;
+ continue;
}
if (mode != SHOWJOBS_VERBOSE && ps != jp->ps)
- goto skip;
+ continue;
if (jobno == curr && ps == jp->ps)
c = '+';
else if (jobno == prev && ps == jp->ps)
@@ -384,8 +410,6 @@ showjob(struct job *jp, int mode)
out1c('\n');
} else
printjobcmd(jp);
-skip: if (--procno <= 0)
- break;
}
}
@@ -568,23 +592,23 @@ getjob_nonotfound(const char *name)
if (name == NULL) {
#if JOBS
-currentjob: if ((jp = getcurjob(NULL)) == NULL)
- error("No current job");
- return (jp);
+ name = "%+";
#else
error("No current job");
#endif
- } else if (name[0] == '%') {
+ }
+ if (name[0] == '%') {
if (is_digit(name[1])) {
jobno = number(name + 1);
if (jobno > 0 && jobno <= njobs
&& jobtab[jobno - 1].used != 0)
return &jobtab[jobno - 1];
#if JOBS
- } else if (name[1] == '%' && name[2] == '\0') {
- goto currentjob;
- } else if (name[1] == '+' && name[2] == '\0') {
- goto currentjob;
+ } else if ((name[1] == '%' || name[1] == '+') &&
+ name[2] == '\0') {
+ if ((jp = getcurjob(NULL)) == NULL)
+ error("No current job");
+ return (jp);
} else if (name[1] == '-' && name[2] == '\0') {
if ((jp = getcurjob(NULL)) == NULL ||
(jp = getcurjob(jp)) == NULL)
@@ -847,7 +871,8 @@ forkshell(struct job *jp, union node *n, int mode)
pgrp = getpid();
else
pgrp = jp->ps[0].pid;
- if (setpgid(0, pgrp) == 0 && mode == FORK_FG) {
+ if (setpgid(0, pgrp) == 0 && mode == FORK_FG &&
+ ttyfd >= 0) {
/*** this causes superfluous TIOCSPGRPS ***/
if (tcsetpgrp(ttyfd, pgrp) < 0)
error("tcsetpgrp failed, errno=%d", errno);
@@ -1007,7 +1032,7 @@ waitforjob(struct job *jp, int *origstatus)
dotrap();
#if JOBS
if (jp->jobctl) {
- if (tcsetpgrp(ttyfd, rootpid) < 0)
+ if (ttyfd >= 0 && tcsetpgrp(ttyfd, rootpid) < 0)
error("tcsetpgrp failed, errno=%d\n", errno);
}
if (jp->state == JOBSTOPPED)
@@ -1263,13 +1288,43 @@ commandtext(union node *n)
static void
+cmdtxtdogroup(union node *n)
+{
+ cmdputs("; do ");
+ cmdtxt(n);
+ cmdputs("; done");
+}
+
+
+static void
+cmdtxtredir(union node *n, const char *op, int deffd)
+{
+ char s[2];
+
+ if (n->nfile.fd != deffd) {
+ s[0] = n->nfile.fd + '0';
+ s[1] = '\0';
+ cmdputs(s);
+ }
+ cmdputs(op);
+ if (n->type == NTOFD || n->type == NFROMFD) {
+ if (n->ndup.dupfd >= 0)
+ s[0] = n->ndup.dupfd + '0';
+ else
+ s[0] = '-';
+ s[1] = '\0';
+ cmdputs(s);
+ } else {
+ cmdtxt(n->nfile.fname);
+ }
+}
+
+
+static void
cmdtxt(union node *n)
{
union node *np;
struct nodelist *lp;
- const char *p;
- int i;
- char s[2];
if (n == NULL)
return;
@@ -1314,14 +1369,13 @@ cmdtxt(union node *n)
break;
case NWHILE:
cmdputs("while ");
- goto until;
+ cmdtxt(n->nbinary.ch1);
+ cmdtxtdogroup(n->nbinary.ch2);
+ break;
case NUNTIL:
cmdputs("until ");
-until:
cmdtxt(n->nbinary.ch1);
- cmdputs("; do ");
- cmdtxt(n->nbinary.ch2);
- cmdputs("; done");
+ cmdtxtdogroup(n->nbinary.ch2);
break;
case NFOR:
cmdputs("for ");
@@ -1356,36 +1410,25 @@ until:
cmdputs(n->narg.text);
break;
case NTO:
- p = ">"; i = 1; goto redir;
+ cmdtxtredir(n, ">", 1);
+ break;
case NAPPEND:
- p = ">>"; i = 1; goto redir;
+ cmdtxtredir(n, ">>", 1);
+ break;
case NTOFD:
- p = ">&"; i = 1; goto redir;
+ cmdtxtredir(n, ">&", 1);
+ break;
case NCLOBBER:
- p = ">|"; i = 1; goto redir;
+ cmdtxtredir(n, ">|", 1);
+ break;
case NFROM:
- p = "<"; i = 0; goto redir;
+ cmdtxtredir(n, "<", 0);
+ break;
case NFROMTO:
- p = "<>"; i = 0; goto redir;
+ cmdtxtredir(n, "<>", 0);
+ break;
case NFROMFD:
- p = "<&"; i = 0; goto redir;
-redir:
- if (n->nfile.fd != i) {
- s[0] = n->nfile.fd + '0';
- s[1] = '\0';
- cmdputs(s);
- }
- cmdputs(p);
- if (n->type == NTOFD || n->type == NFROMFD) {
- if (n->ndup.dupfd >= 0)
- s[0] = n->ndup.dupfd + '0';
- else
- s[0] = '-';
- s[1] = '\0';
- cmdputs(s);
- } else {
- cmdtxt(n->nfile.fname);
- }
+ cmdtxtredir(n, "<&", 0);
break;
case NHERE:
case NXHERE:
OpenPOWER on IntegriCloud