tech-userlevel archive

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

Re: the zen of SIGPIPE



On Tue, Jan 08, 2013 at 02:43:25AM -0500, Mouse wrote:
>

> > I think that it would be more useful for xargs to raise(2) certain
> > signals which terminated its child rather than write to stderr.
> 
> Um.  Wow.  I hadn't thought of that, but it superficially makes a whole
> lot of sense.  I want to think about it a bit.
> 
> Of course, figuring out exactly which signals should get this treatment
> is likely to be a bikeshed.  SIGPIPE, yes, but beyond that?  I'm not
> sure.

Yes, I would also want to think about it for a bit.  This was just the
first solution that popped into my head which appears to satisfy the
basic criteria.

As for signals, well, it probably makes sense to also propagate SIGINT
this way.

Also note that at least for me /bin/ksh:

$ for i in $(jot 10); do xargs /tmp/foo < /tmp/adsf; done
foo bar baz
^Zfoo bar baz
foo bar baz
foo bar baz
foo bar baz
foo bar baz
foo bar baz
foo bar baz
foo bar baz
foo bar baz
[2] + Stopped              xargs /tmp/foo < /tmp/adsf 
$ fg
xargs /tmp/foo < /tmp/adsf 

That is, if I ^Z it appears to stop the xargs only at the end of
the loop rather than when I suspended it.  There is likely a
reasonable way to stop this behaviour.

And in /bin/sh:

$ for i in $(jot 10); do xargs /tmp/foo < /tmp/adsf; done
foo bar baz
foo bar baz
^Z[1] + Suspended               xargs /tmp/foo </tmp/adsf
foo bar baz
foo bar baz
^Z[2] - Suspended               xargs /tmp/foo </tmp/adsf
foo bar baz
foo bar baz
^Z[3]   Suspended               xargs /tmp/foo </tmp/adsf
foo bar baz
^Z[4]   Suspended               xargs /tmp/foo </tmp/adsf
foo bar baz
^Z[5]   Suspended               xargs /tmp/foo </tmp/adsf
foo bar baz
^Z[6]   Suspended               xargs /tmp/foo </tmp/adsf
foo bar baz
^Z[7]   Suspended               xargs /tmp/foo </tmp/adsf

Each xargs is put into the background but the loop continues to run.

> > This is coincidentally how some shells deal with receiving SIGINT to
> > ensure that it propagates to parent shells so that they can, e.g.
> > terminate loops.
> 
> > $ cat /tmp/foo
> > #!/bin/sh
> > 
> > echo "$@"
> > kill -2 $$
> > sleep 1
> 
> > $ for i in $(jot 3); do /tmp/foo foo bar baz; done             
> > foo bar baz
> 
> That's not what I see (NetBSD/sparc 1.4T and NetBSD/i386 4.0.1); I get
> three "foo bar baz" lines.  What shell do you see this with?  Have you
> checked (eg, ktrace) that it really is the shell passing on the signal
> rather than something else?

I'm running NetBSD/amd64 6.99.3 using /bin/ksh, mostly.  I think
that in a couple of examples, I used /bin/sh to demonstrate that
the behaviour is different when using a different shell but that
is called out in the original e-mail.  The script, though, is
/bin/sh.

> I'll have to think about the "push signals upwards" suggestion;
> currently my xargs completely ignores child exit status.  I'm inclined
> to implement it, but want to give it a day or two to percolate and see
> if anything comes to mind I haven't thought of immediately.

Let me know if you think of any catches.  I like the idea because it
makes:

        echo arg1 arg2 | xargs foo

behave quite similarly to

        foo arg1 arg2

w.r.t. signals which in a few cases like SIGINT, SIGSTOP, SIGTSTP,
and so on may be quite important for allowing interactive use to
proceed the way that you expect.

--
    Roland Dowdeswell                      http://Imrryr.ORG/~elric/


Home | Main Index | Thread Index | Old Index