Conversation
Created using spr 1.3.6-beta.1
andrewjstone
left a comment
There was a problem hiding this comment.
Thanks @sunshowers!
If I understand this correctly, the problem is that when we output to something like head, oxlog is the write side of the pipe, and head is the read side. head only reads a subset of data and then exits, but oxlog continues to write which causes an EPIPE. This handler instead makes oxlog exit cleanly, right?
Yes, that's right. When you fail to write to a pipe, two things happen:
If you're a C program, then both 1 and 2 happen -- though 1 happens before 2 does. With SIGPIPE, the default signal disposition is for the program to terminate -- this is why CLI tools written in C exit cleanly. But by default, Rust programs ignore the The whole situation isn't great, but it also is tremendously hard to change at this point. I made a much more minor change in rust-lang/rust#101077 to make it so that the signal mask was inherited rather than reset, and just that change broke a few downstream users. |
We have a number of CLI tools that panic when piped to things like
headinstead of quietly exiting. There's a long history about this within the Rust
community (see rust-lang/rust#62569), but the long
and short of it is that SIGPIPE really should be set to its default handler
(
SIG_DFL, terminate the process) for CLI tools.Because oxlog doesn't make any network requests, reset the SIGPIPE handler to
SIG_DFL.I looked at also potentially doing this for some of our other CLI tools that
wait on network services. This should be fine to do if and only if whenever we
send data over a socket, the
MSG_NOSIGNALflag is set. (This causes anEPIPEerror to be returned, but noSIGPIPEsignal to be generated.)Rust does set this flag here. However, as of Rust 1.77 this flag is not
set on illumos. That's a bug and I'll fix it in Rust upstream.