Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 13 Mar 2013 12:18:24 GMT
From:      "Vadim S. Goncharov" <vadim_nuclight@mail.ru>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   standards/176916: [patch] sh(1): implement multiple arguments to wait builtin
Message-ID:  <201303131218.r2DCIO9u048934@red.freebsd.org>
Resent-Message-ID: <201303131220.r2DCK1hV054690@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         176916
>Category:       standards
>Synopsis:       [patch] sh(1): implement multiple arguments to wait builtin
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-standards
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Mar 13 12:20:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator:     Vadim S. Goncharov
>Release:        FreeBSD 9.0-RELEASE amd64
>Organization:
RU-CENTER (www.nic.ru)
>Environment:
FreeBSD noc-42.nic.ru 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Tue Jan  3 07:46:30 UTC 2012     root@farrell.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  amd64
>Description:
POSIX.2 requires that wait(1) built-in in sh(1) shall support multiple arguments, and that unknown (e.g. errorneous) job specification be treated as known with exit status 127 (it is currently 2), see http://pubs.opengroup.org/onlinepubs/009695399/utilities/wait.html

The patch attached implements this functionality which was absent in our shell.

This feature is essential for implementing e.g. parallel execution of rc.d scripts, so please commit/MFC it as soon as possible :)
>How-To-Repeat:
Try to do

  sleep 33 & sleep 44 &
  wait %2 %1
  echo $?

other args are ignored.
>Fix:
Patch attached.

Patch attached with submission follows:

Index: bin/sh/sh.1
===================================================================
--- bin/sh/sh.1	(revision 248189)
+++ bin/sh/sh.1	(working copy)
@@ -2598,12 +2598,17 @@
 option is specified, the
 .Ar name
 arguments are treated as function names.
-.It Ic wait Op Ar job
-Wait for the specified
+.It Ic wait Op Ar job ...
+Wait for each specified
 .Ar job
 to complete and return the exit status of the last process in the
+last specified
 .Ar job .
-If the argument is omitted, wait for all jobs to complete
+If any
+.Ar job
+specified is incorrect or unknown to shell, it is treated as if it
+were known job that exited with exit status 127.
+If arguments are omitted, wait for all jobs to complete
 and return an exit status of zero.
 .El
 .Ss Commandline Editing
Index: bin/sh/jobs.c
===================================================================
--- bin/sh/jobs.c	(revision 248189)
+++ bin/sh/jobs.c	(working copy)
@@ -95,6 +95,7 @@
 static void restartjob(struct job *);
 #endif
 static void freejob(struct job *);
+static int waitcmdloop(struct job *);
 static struct job *getjob(char *);
 pid_t getjobpgrp(char *);
 static pid_t dowait(int, struct job *);
@@ -461,15 +462,35 @@
 waitcmd(int argc, char **argv)
 {
 	struct job *job;
+	struct jmploc jmploc;
+	struct jmploc *const savehandler = handler;
+	int retval = 0;
+
+	if (argc <= 1)
+		return waitcmdloop(NULL);
+
+	do {
+		if (setjmp(jmploc.loc)) {
+			retval = 127;		/* Posix.2, section 4.70.2 */
+			handler = savehandler;
+			continue;
+		} else {
+			handler = &jmploc;
+			job = getjob(*++argv);
+		}
+		handler = savehandler;
+		retval = waitcmdloop(job);
+	} while (--argc > 1);
+
+	return (retval);
+}
+
+static int
+waitcmdloop(struct job *job)
+{
 	int status, retval;
 	struct job *jp;
 
-	if (argc > 1) {
-		job = getjob(argv[1]);
-	} else {
-		job = NULL;
-	}
-
 	/*
 	 * Loop until a process is terminated or stopped, or a SIGINT is
 	 * received.


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201303131218.r2DCIO9u048934>