Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 24 Feb 2012 22:01:41 +0100
From:      Jilles Tjoelker <jilles@stack.nl>
To:        Bruce Evans <brde@optusnet.com.au>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r232108 - head/usr.bin/xargs
Message-ID:  <20120224210141.GA3223@stack.nl>
In-Reply-To: <20120225024051.C1150@besplex.bde.org>
References:  <201202241235.q1OCZH2U059017@svn.freebsd.org> <20120225024051.C1150@besplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, Feb 25, 2012 at 04:27:35AM +1100, Bruce Evans wrote:
> On Fri, 24 Feb 2012, Jilles Tjoelker wrote:
> > Log:
> >  xargs: If a utility exits with 255 or a signal, write an error message.

> >  If a utility called by xargs exits with status 255 or because of a signal,
> >  POSIX requires writing an error message.

> Is an exit status of 255 really possible?  I thought that there was
> magic for the top bit.

exit() takes 8 bits of exit status which are all returned by wait4().

> But testing reminded me that at the level of a single exit(), the
> magic in the top bit is for signals, and showed that WIFSIGNALED() is
> broken for signal 127:

> [snip]

> This prints SIGNALED = 0 and STOPPED = 1, when it should print
> SIGNALED = 1 and STOPPED = 0.  This is because the special _WSTATUS()
> of 127 is _WSTOPPED and this cannot be distinguished from an actual
> signal 127.  Probably this signal should be disallowed.  (The magic
> in the top bit is just the core dump flag.  Signals 128-255 are
> already disallowed, so they don't give ambiguity.)

PR kern/19402 describes this problem. Changeset r152973 (November 2005)
changed SIGRTMAX so portable programs cannot know about signals 127 and
128 anymore. Programs compiled before that change may use them (but only
after r151306 (October 2005)), since it is common to use the first few
or the last few realtime signals.

Perhaps these signals can now be forbidden by the kernel, or replaced by
a harmless value for old binaries.

> Utilities are quite broken near here too:
> - under -current:
>    - utilities still don't support signals >= 32, but give better error
>      messages.

kill(1) (both /bin/kill and the 9.x/10.x sh builtin) has passed
arbitrary signal numbers to kill(2) for quite a while.

> > Modified: head/usr.bin/xargs/xargs.c
> > ==============================================================================
> > --- head/usr.bin/xargs/xargs.c	Fri Feb 24 12:32:50 2012	(r232107)
> > +++ head/usr.bin/xargs/xargs.c	Fri Feb 24 12:35:17 2012	(r232108)
> > @@ -608,8 +608,11 @@ waitchildren(const char *name, int waita
> > 		 * If utility signaled or exited with a value of 255,
> > 		 * exit 1-125.
> > 		 */

> This comment didn't match the code before (the code always exited with
> status 1), and is now further from matching the code.

> This comment is hard to parse.

It seems to repeat a POSIX requirement. I suppose it can go away as it
doesn't really say anything the code doesn't say.

> > -		if (WIFSIGNALED(status) || WEXITSTATUS(status) == 255)
> > -			exit(1);
> > +		if (WIFSIGNALED(status))
> > +			errx(1, "%s: terminated with signal %d, aborting",
> > +			    name, WTERMSIG(status));

> This misclassifies signal 127 due to the above bug.

> > +		if (WEXITSTATUS(status) == 255)
> > +			errx(1, "%s: exited with status 255, aborting", name);
> > 		if (WEXITSTATUS(status))
> > 			rval = 1;

> Neither WIFSTOPPED() nor WIFEXITED() are tested, so the result of the
> misclassification is turning signal 127 into a normal exit with status
> 0.  A normal WIFSTOPPED() should not get here, else job control would
> just break xargs, so the bug can probably be worked around by turning
> WIFSTOPPED() into WIFSIGNALED() here, or just blindly using WTERMSIG()
> != 0 to classify signals.

I don't think xargs should work around that bug, particularly not by
introducing unspecified behaviour (the value of WTERMSIG(x) when
!WIFSIGNALED(x)).

> The messages have a grammar error (comma splice).

GNU xargs has a semicolon instead of a comma. Is that better?

> > 	}
> >

> The magic for the top bit is when exit statuses are combined with
> signal statuses and bits are lost by forcing them through an 8-bit
> filter (perhaps another exit()).  Shells report signal n as $? =
> (0x80 | n).  When n is 127, shells are not quite confused enough to
> turn the status into 0 -- they just turn n into 0, giving status 0x80.

In fact, POSIX only requires that $? be greater than 128 and kill -l $?
return the name of the signal without "SIG".

-- 
Jilles Tjoelker



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