This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: S_ISCHR, S_ISFIFO, O_NONBLOCK, O_NOCTTY
- To: Zack Weinberg <zack at blastula dot phys dot columbia dot edu>
- Subject: Re: S_ISCHR, S_ISFIFO, O_NONBLOCK, O_NOCTTY
- From: "Melissa O'Neill" <oneill at cs dot sfu dot ca>
- Date: Sat, 6 Feb 1999 13:16:18 -0800
- cc: egcs-patches at egcs dot cygnus dot com
- References: <199902061939.OAA03289@blastula.phys.columbia.edu>
Zack wrote:
> Well, even if NEXTSTEP has S_IFIFO, we can't rely on all 4.x (x<4)
> derivatives to have it. So we do need to detect sockets some other
> way.
Right...
> I've appended a partial patch to do the detection. It has portability
> problems. One is easy: we need an S_ISSOCK() default definition in
> system.h now. Could you please add that to your patch? If there is no
> S_IFSOCK, don't define it at all (note the conditionals in my patch).
> Also, I've assumed that if S_ISSOCK or S_IFSOCK is available in
> <sys/stat.h> then fstat() on a socket will use those values.
I don't think that is a correct assumption. I think in a BSD 4.2 system,
stat on a Unix domain socket in the filesystem will set S_ISSOCK, but
fstat on a file descriptor will fail. Remember that `BUGS' line I quoted
from my NEXTSTEP system. While it doesn't appear to apply any more, I'd
guess that it used to apply in BSD 4.2 (and earlier?). The quote was:
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.
I'd probably just use something like:
else if (S_ISFIFO (st.st_mode)
#ifdef S_ISSOCK
|| S_ISSOCK (st.st_mode)
#endif
#ifdef SOCKET_FSTAT_BUG
|| (st.st_mode == 0 && st.st_size == 0 && st.st_nlink == 0)
/* socket/pipe in BSD 4.x (x < 4) */
#endif
|| (S_ISCHR (st.st_mode) && isatty (fd)))
An alternative would be to have a definition of S_ISSOCK that looks
like this:
/* Test if something is a socket. */
#ifndef S_ISSOCK
# ifdef S_IFSOCK
# ifdef SOCKET_FSTAT_BUG
# define S_ISSOCK(m) ((m) == 0 || ((m) & S_IFMT) == S_IFSOCK)
# else
# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
# endif
# else
# define S_ISSOCK(m) 0
# endif
#endif
but the above is only checking st.mode, rather than checking a few
other fields for being zero as well.
I think either of the above is probably a better solution than trying
to use shutdown, given what you said about shutdown's not being in some
early BSDs. (Of course, how you'd get to set SOCKET_FSTAT_BUG is an
exercise for the reader.)
Melissa.
P.S. Enclosed is my patch, with S_ISSOCK added (but without SOCKET_FSTAT_BUG).
Enc.
--- system.h.orig Wed Feb 3 23:16:17 1999
+++ system.h Sat Feb 6 13:10:19 1999
@@ -410,8 +410,41 @@
#ifndef S_ISDIR
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
+/* Test if something is a character special file. */
+#ifndef S_ISCHR
+#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#endif
+
+/* Test if something is a socket. */
+#ifndef S_ISSOCK
+# ifdef S_IFSOCK
+# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+# else
+# define S_ISSOCK(m) 0
+# endif
+#endif
+
+/* Test if something is a FIFO. */
+#ifndef S_ISFIFO
+# ifdef S_IFIFO
+# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+# else
+# define S_ISFIFO(m) 0
+# endif
+#endif
+
+/* Approximate O_NONBLOCK. */
+#ifndef O_NONBLOCK
+#define O_NONBLOCK O_NDELAY
+#endif
+
+/* Approximate O_NOCTTY. */
+#ifndef O_NOCTTY
+#define O_NOCTTY 0
+#endif
+
/* Get libiberty declarations. */
#include "libiberty.h"
#if defined (ANSI_PROTOTYPES)