S_ISCHR, S_ISFIFO, O_NONBLOCK, O_NOCTTY

Zack Weinberg zack@rabi.columbia.edu
Thu Feb 4 13:05:00 GMT 1999


On Thu, 4 Feb 1999 12:49:19 -0800, "Melissa O'Neill" wrote:
>I wrote:
>>>> cppfiles.c now tests file types using S_ISFIFO and S_ISCHR.  Some
>>>> Unix systems don't have FIFOs, and non-POSIX systems do not have
>>>> these macros.
>
>... and Zack Weinberg <zack@rabi.columbia.edu> replied:
>> On systems without FIFOs, what does fstat() return for stdin when
>> stdin is an anonymous pipe?  The check is applied to the main input,
>> so it's relevant.  We don't want to disallow piping to cpp by accident.
>
>On many older BSD systems, pipes are implemented using socketpair, so
>in theory, S_IFSOCK should be set. However, on my own system (NEXTSTEP 3.3)
>the manual page for fstat states:
>
>    BUGS
>	  Applying fstat to a socket (and thus to a pipe) returns a
>	  zeroed buffer, except for the blocksize field, and a unique
>	  device and inode number.

Either way, that's gonna hit the "not a file, pipe, or tty" case.  Can
you do `cat | ./cpp' on a nextstep box to confirm this?

I'm a little leery of accepting any kind of socket, but it's probably no
more dangerous than accepting any kind of terminal, so...

>P.S. Yesterday, I discovered that if you fstat an open AF_INET socket
>on Solaris 2.5, it tells you that it's a character special device
>(S_IFCHR) rather than telling you it is a socket (S_IFSOCK) as you might
>have expected  (Solaris 2.6 gets it right).  

Solaris <2.6 doesn't have real sockets, they're implemented with a
pseudo device, so technically it's not a bug.

>call shutdown(), but I just gave up.  With socket fstat bugs in NEXTSTEP
>and Solaris it was easier just to call shutdown and ignore any ENOTSOCK
>errors.

Hmm...  That's not a bad way to detect a socket when you only care
about reading, which describes cpplib pretty well.  My documentation
is inconsistent - what does shutdown do when asked to disallow sends
and sending is already shutdown?  I.e. if I do

{
  int fd = socket(...)
  shutdown(fd, 1);
  shutdown(fd, 1);
}

will the second call succeed or fail, and if it fails, what will errno
be?

zw


More information about the Gcc-patches mailing list