2

Is anyone aware of an equivalent to setsockopt() that works on non-socket based file descriptors?

Specifically, consider this block of code:

int on = 1;
setsockopt(socketfd, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(int));

All fine and dandy, and now we can avoid SIGPIPE and refer to EPIPE when writing instead. But this only works on socket file descriptors opened with accept(), socket(), etc.

I'm trying to gain similar functionality for a file descriptor opened by a pipe() call, which setsockopt() promptly rejects as being a non-socket file descriptor.

Is there an equivalent to the above (setsockopt()) for descriptors opened by pipe() or open()?

SimplePanda
  • 2,311
  • 1
  • 15
  • 12
  • 1
    If you wish to avoid `SIGPIPE`, you can assign a signal handler. There is no equivalent for `setsockopt`on files I'm aware of. – Ishay Peled Jul 10 '16 at 07:03
  • Alas, I'm writing a library so I'm trying to avoid signal handling because I can never be sure what the implementers above me (using my library) are going to need, signal handling wise. If I just kill SIGPIPE process wide and some code above me isn't implemented properly (ignoring EPIPE) this can become an issue. Thanks for the suggestion though! – SimplePanda Jul 10 '16 at 07:04
  • This [answer](http://stackoverflow.com/a/108192/5781248) might be relevant if it is ok that SIGPIPE is always ignored. – J.J. Hakala Jul 10 '16 at 07:33
  • Ignoring SIGPIPE isn't really an option for a variety of reasons, unfortunately. Plus, if you're debugging an app in LLDB, signal handlers only receive signals once you've told LLDB to pass them and not stop (can be a hassle). – SimplePanda Jul 10 '16 at 07:38
  • Assigning a signal handler to SIGPIPE makes little sense Rather you need to _ignore it_ so that the signal is not even sent (the debugger doesn't get in the way) and the system call returns EPIPE. I suspect that any Unix program that is not "meant to be part of a pipeline" (i.e. that is not `grep` or `sed` or `cat` or similar) really should be ignoring SIGPIPE, but I understand you not wanting to impose this from a library. – Paolo Bonzini Jul 10 '16 at 10:47
  • When opening the file via `open()` or `pipe()`; the easiest way to modify is to use: `ioctl()`. – user3629249 Jul 10 '16 at 21:46

2 Answers2

2

There is no equivalent, but you could use socketpair to create a Unix socket instead.

Paolo Bonzini
  • 1,900
  • 15
  • 25
  • This both answers my question and presents a solution that took 5 minutes to implement while passing all my unit tests. Perfect! Thank you! – SimplePanda Jul 10 '16 at 07:34
0

If your ultimate goal is to avoid signals altogeather, you can use init and cleanup functions as described here

Also see good example here: Automatically executed functions when loading shared libraries

Just write an init function that handles the signals you wish to avoid and every program that loads your library will automatically have your handlers

I must say this is a strange necessity though, can you be more specific about the actual problem you're trying to solve?

Community
  • 1
  • 1
Ishay Peled
  • 2,783
  • 1
  • 23
  • 37
  • Per the description I'm trying to provide an API that potentially does a write() call on a file descriptor created from a pipe() call. In the event that the write file descriptor has been widowed (because the implementor closed the read side of the pipe), I want to avoid SIGPIPE and just handle this gracefully by detecting EPIPE. Plus, signal issues can be a problem if you're running unit tests on top of LLDB due to it's signal handling. – SimplePanda Jul 10 '16 at 07:28