[v2 PATCH] jobs: Allow monitor mode without a tty in non-interactive mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Jan 30, 2023 at 10:15:40PM +0100, Steffen Nurpmeso wrote:
> This is a take-over of the FreeBSD bin/sh
> 
>   commit cd60e2c67d52e1f957841af19128c7227880743a
>   Author:     Jilles Tjoelker <jilles@xxxxxxxxxxx>
>   AuthorDate: 2014-09-04 21:48:33 +0000
>   Commit:     Jilles Tjoelker <jilles@xxxxxxxxxxx>
>   CommitDate: 2014-09-04 21:48:33 +0000
> 
>       sh: Allow enabling job control without a tty in non-interactive mode.
> 
>       If no tty is available, 'set -m' is still useful to put jobs in their own
>       process groups.
> ---
> 
> Dear Ganael, it seems it requires an inline patch?
> Let me try this -- thanks!!
> Ciao.
> 
>  src/jobs.c | 114 +++++++++++++++++++++++++++++++----------------------
>  1 file changed, 67 insertions(+), 47 deletions(-)

Thanks for the patch.  I've rewritten it to minimise the impact.
However, the end result should be fairly similar.

Please test this and let me know if there are any issues.

---8<---
When a tty is unavailable, or the shell is in the background,
job control could still be used for the purpose of setting
process groups.

This is based on work by Jilles Tjoelker from FreeBSD and Steffen
Nurpmeso.

Reported-by: Steffen Nurpmeso <steffen@xxxxxxxxxx>
Reported-by: Ganael Laplanche <ganael.laplanche@xxxxxxxxxxxx>
Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>

diff --git a/src/jobs.c b/src/jobs.c
index a0f4d47..2a2fe22 100644
--- a/src/jobs.c
+++ b/src/jobs.c
@@ -187,11 +187,21 @@ set_curjob(struct job *jp, unsigned mode)
 
 int jobctl;
 
+static void xxtcsetpgrp(pid_t pgrp)
+{
+	int fd = ttyfd;
+
+	if (fd < 0)
+		return;
+
+	xtcsetpgrp(fd, pgrp);
+}
+
 void
 setjobctl(int on)
 {
+	int pgrp = -1;
 	int fd;
-	int pgrp;
 
 	if (on == jobctl || rootshell == 0)
 		return;
@@ -207,36 +217,43 @@ setjobctl(int on)
 		fd = savefd(fd, ofd);
 		do { /* while we are in the background */
 			if ((pgrp = tcgetpgrp(fd)) < 0) {
+close:
+				close(fd);
+				fd = -1;
 out:
+				if (!iflag)
+					break;
 				sh_warnx("can't access tty; job control turned off");
 				mflag = on = 0;
-				goto close;
+				return;
 			}
 			if (pgrp == getpgrp())
 				break;
+			if (!iflag)
+				goto close;
 			killpg(0, SIGTTIN);
 		} while (1);
 		initialpgrp = pgrp;
-
-		setsignal(SIGTSTP);
-		setsignal(SIGTTOU);
-		setsignal(SIGTTIN);
 		pgrp = rootpid;
-		setpgid(0, pgrp);
-		xtcsetpgrp(fd, pgrp);
 	} else {
 		/* turning job control off */
 		fd = ttyfd;
 		pgrp = initialpgrp;
-		xtcsetpgrp(fd, pgrp);
-		setpgid(0, pgrp);
-		setsignal(SIGTSTP);
-		setsignal(SIGTTOU);
-		setsignal(SIGTTIN);
-close:
-		close(fd);
-		fd = -1;
 	}
+
+	setsignal(SIGTSTP);
+	setsignal(SIGTTOU);
+	setsignal(SIGTTIN);
+	if (fd >= 0) {
+		setpgid(0, pgrp);
+		xtcsetpgrp(fd, pgrp);
+
+		if (!on) {
+			close(fd);
+			fd = -1;
+		}
+	}
+
 	ttyfd = fd;
 	jobctl = on;
 }
@@ -391,7 +408,7 @@ restartjob(struct job *jp, int mode)
 	jp->state = JOBRUNNING;
 	pgid = jp->ps->pid;
 	if (mode == FORK_FG)
-		xtcsetpgrp(ttyfd, pgid);
+		xxtcsetpgrp(pgid);
 	killpg(pgid, SIGCONT);
 	ps = jp->ps;
 	i = jp->nprocs;
@@ -874,7 +891,7 @@ static void forkchild(struct job *jp, union node *n, int mode)
 		/* This can fail because we are doing it in the parent also */
 		(void)setpgid(0, pgrp);
 		if (mode == FORK_FG)
-			xtcsetpgrp(ttyfd, pgrp);
+			xxtcsetpgrp(pgrp);
 		setsignal(SIGTSTP);
 		setsignal(SIGTTOU);
 	} else
@@ -1014,7 +1031,7 @@ waitforjob(struct job *jp)
 	st = getstatus(jp);
 #if JOBS
 	if (jp->jobctl) {
-		xtcsetpgrp(ttyfd, rootpid);
+		xxtcsetpgrp(rootpid);
 		/*
 		 * This is truly gross.
 		 * If we're doing job control, then we did a TIOCSPGRP which
-- 
Email: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt




[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]     [Photo]

  Powered by Linux