NetBSD-Bugs archive

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

bin/55605: [PATCH] script(1): does not wait on child pid when stdin is not a tty



>Number:         55605
>Category:       bin
>Synopsis:       [PATCH] script(1): does not wait on child pid when stdin is not a tty
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Aug 24 22:55:00 +0000 2020
>Originator:     Soumendra Ganguly
>Release:        9.0
>Organization:
Texas A&M University
>Environment:
NetBSD localhost 9.0 NetBSD 9.0 (GENERIC) #0: Fri Feb 14 00:06:28 UTC 2020  mkrepro%mkrepro.NetBSD.org@localhost:/usr/src/sys/arch/amd64/compile/GENERIC amd64
>Description:
Parent process does not call SIGCHLD handler when stdin is not a tty. It does not wait on the child pid. It simply calls done() and exits. This leads to strange output on screen. See the "how to repeat the problem" section for more details. Patch is included.
>How-To-Repeat:
Create regular file "~/tmp" with following contents:

ls
exit
<newline at end of file >

Now, call script < ~/tmp to notice the following:

"Script done, output file is typescript" comes right after the message
"Script started, output file is typescript" and before the pty echo and the data written to stdout. Add a "printf("SIGCHLD\n");" to finish() and run again to notice that actually finish() [ the SIGCHLD handler ] is never called by the parent. It is called by the child when it receives SIGCHLD when the subchild exits.

>Fix:
--- src/usr.bin/script/script.c	2020-08-24 17:27:30.907579625 -0500
+++ script.c	2020-08-24 17:29:00.950890312 -0500
@@ -204,7 +204,7 @@
 			record(fscript, ibuf, cc, 'i');
 		(void)write(master, ibuf, cc);
 	}
-	done();
+	waitpid(-1, NULL, 0); /* Dummy wait. wait3() called upon SIGCHLD. */
 	/* NOTREACHED */
 	return EXIT_SUCCESS;
 }
@@ -249,7 +249,7 @@
 		if (scc <= 0)
 			break;
 		cc = (size_t)scc;
-		(void)write(1, obuf, cc);
+		(void)write(STDOUT_FILENO, obuf, cc);
 		if (rawout)
 			record(fscript, obuf, cc, 'o');
 		else
@@ -258,7 +258,7 @@
 		if (flush)
 			(void)fflush(fscript);
 	}
-	done();
+	waitpid(-1, NULL, 0); /* Dummy wait. wait3() called upon SIGCHLD. */
 }
 
 static void



Home | Main Index | Thread Index | Old Index