NetBSD-Bugs archive

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

bin/46021: xargs should keep still



>Number:         46021
>Category:       bin
>Synopsis:       xargs should keep still
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Feb 14 04:50:00 +0000 2012
>Originator:     jklowden%schemamania.org@localhost
>Release:        NetBSD 5.0.2
>Organization:
        
>Environment:
        
        
System: NetBSD oak.schemamania.org 5.0.2 NetBSD 5.0.2 (GENERIC) #0: Sat Feb 6 
13:44:19 UTC 2010 
builds%b8.netbsd.org@localhost:/home/builds/ab/netbsd-5-0-2-RELEASE/amd64/201002061851Z-obj/home/builds/ab/netbsd-5-0-2-RELEASE/src/sys/arch/amd64/compile/GENERIC
 amd64
Architecture: x86_64
Machine: amd64
>Description:
        xargs writes error messages to standard error if the utility 
        it's executing exits with an error or on a signal.  E.g.:
        
        $ find /usr | xargs ls | head -1
        /usr/X11R7/bin/X
        xargs: ls terminated by SIGPIPE
        
        As the above example shows, the message is unwelcome and unnecessary.  
        If the *utility* needs to produce a message, it can, as can the shell
        (or other caller).  But xargs is mere plumbing in the works, made 
        neccessary only by the accident that e.g. ls(1) doesn't read from
        standard input.  
        
        Note also that in most cases the shell captures (in $?, say) the 
        exit status only of the last command in a pipeline.  As such, the
        a shell script using a pipeline as above would (correctly) deem
        the pipeline successful.  If the author of the script wishes to
        suppress the superfluous message, he can of course redirect
        standard error, but in so doing he'll supress genuine messages from
        ls.  
        
        $ echo nonesuch /usr/* | xargs ls | head -3
        ls: nonesuch: No such file or directory
        /usr/X11R6:
        bin
        include
        xargs: ls terminated by SIGPIPE
        
        $ echo nonesuch /usr/* | xargs ls 2>/dev/null | head -3
        /usr/X11R6:
        bin
        include

        It is illustrative that although find and ls in the first example
        were terminated by SIGPIPE, only xargs complained.  Most netbsd
        utilities do not write to standard error for SIGPIPE.  That is by
        design.  The reader of a pipe cannot signal the writer that it has
        what it needs except by closing the pipe.  Therefore pipe closure
        is expected and not an error condition.  I have phrased this
        observation as 
        
                "Failure to read is not an error".  
        
        In the case of xargs, the crime is more eggregious.  xargs has no
        business remarking on the exit status of its client, period.  It
        does not matter what the signal is.  In a perfect world xargs would
        disappear.  In ours, it should hold its tongue.  
        
>How-To-Repeat:
        See above. 
>Fix:

Index: xargs.c
===================================================================
RCS file: /cvsroot/src/usr.bin/xargs/xargs.c,v
retrieving revision 1.20
diff -u -r1.20 xargs.c
--- xargs.c     17 Dec 2010 11:32:57 -0000      1.20
+++ xargs.c     14 Feb 2012 02:21:05 -0000
@@ -593,19 +593,11 @@
                 */
                if (WIFEXITED(status)) {
                        if (WEXITSTATUS (status) == 255) {
-                               warnx ("%s exited with status 255", name);
                                exit(124);
                        } else if (WEXITSTATUS (status) != 0) {
                                rval = 123;
                        }
                } else if (WIFSIGNALED (status)) {
-                       if (WTERMSIG(status) < NSIG) {
-                               warnx("%s terminated by SIG%s", name,
-                                   sys_signame[WTERMSIG(status)]);
-                       } else {
-                               warnx("%s terminated by signal %d", name,
-                                   WTERMSIG(status));
-                       }
                        exit(125);
                }
        }

>Unformatted:
        
        


Home | Main Index | Thread Index | Old Index