From: Eric Hodel Date: 2004-04-27T08:48:25-07:00 Subject: Re: ignores SIGPIPE, why ruby --gblAvmLjk8yGG9If Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Zsban Ambrus (ambrus@math.bme.hu) wrote: > Ruby ignores SIGPIPE. In this mail, I'll argue against the usefulness of > this decision. No, Ruby does not ignore SIGPIPE. It traps it just fine. > When you type something like >=20 > ruby -we 'n=3D 1; puts n+=3D1 while 1;' | head >=20 > then after the 10th line the puts function raises Errno::EPIPE (cause tha= t's > what syscalls return when they raise an EPIPE signal) and ruby dies with = an > ugly annoying message like >=20 > -e:1:in `write': Broken pipe (Errno::EPIPE) > from -e:1:in `puts' > from -e:1 >=20 > I think that ruby should either silently die from the EPIPE signal (or el= se > raise an Errno::EPIPE exception that you can catch but if you don't catch= it > ruby should just exit silently just like when you call Kernel.exit()) Ruby did not recive a SIGPIPE, puts raised an Errno::EPIPE. See errno(2) vs signal(3). You can close or redirect STDERR to avoid the error message. > What makes the situation even worse is that when I try to change tshi > behaiviour like this: >=20 > ruby -we 'trap "PIPE" do exit end; n=3D 1; puts n+=3D1 while 1;' | head >=20 > the trap function does not do anything, it does not catch the SIGPIPE. The > trap function should at least raise an error because it does not catch the > signal. That code never recieves a SIGPIPE signal, it raises an Errno::EPIPE. trap "PIPE" works just fine: $ cat x.rb pid =3D fork do trap 'PIPE' do puts "caught SIGPIPE"; exit end File.open '/dev/null', 'a' do |fp| loop do fp.puts end end end sleep 1 Process.kill 'PIPE', pid $ ruby x.rb caught SIGPIPE > The only way to silence the error message is to wrap the whole script > in a begin .... rescue Errno::EPIPE; end; def main # ... rescue Errno::EPIPE exit end main if $0 =3D=3D __FILE__ > If ruby would just leave the signal as is, you could probabyl still > have the old behaiviour by adding a trap for SIGPIPE that raises an > Errno::EPIPE exception, or just by ignoring the signal and supposing > that the syscall that raised SIGPIPE will get an EPIPE error anyway > thus raise the exception. No signal sent. --=20 Eric Hodel - drbrain@segment7.net - http://segment7.net All messages signed with fingerprint: FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04 --gblAvmLjk8yGG9If Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.2 (FreeBSD) iD8DBQFAjoDJMypVHHlsnwQRAtjPAKDNI47H7IuNxmiK1my39m8rXpse2wCdGhNw 0zJaM4YiAasG7Lz98zkpOp0= =iPNr -----END PGP SIGNATURE----- --gblAvmLjk8yGG9If--