[Commit] nickle file.c,1.54,1.55

Keith Packard commit at keithp.com
Mon Oct 13 12:14:53 PDT 2003


Committed by: keithp

Update of /local/src/CVS/nickle
In directory home.keithp.com:/tmp/cvs-serv7862

Modified Files:
	file.c 
Log Message:
Leave file descriptors blocking. Check with select before read/write.  This
allows nickle files to be shared with subprocesses cleanly.  It does
introduce a minor race if nickle and another application attempt to read at
the same time, nickle may select and then try to read which may in fact
block.  It's a small window, so I'm not going to worry about it, the benefit
of leaving fds blocking is too great.


Index: file.c
===================================================================
RCS file: /local/src/CVS/nickle/file.c,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -d -r1.54 -r1.55
--- file.c	13 Oct 2003 05:08:41 -0000	1.54
+++ file.c	13 Oct 2003 18:14:51 -0000	1.55
@@ -19,12 +19,6 @@
 #include	"ref.h"
 #include	"gram.h"
 
-#ifdef O_NONBLOCK
-#define NOBLOCK	O_NONBLOCK
-#else
-#define NOBLOCK O_NDELAY
-#endif
-
 #ifdef O_ASYNC
 #define ASYNC O_ASYNC
 #else
@@ -595,7 +589,7 @@
     
     fcntl (fd, F_SETOWN, getpid());
     flags = fcntl (fd, F_GETFL);
-    flags |= ASYNC|NOBLOCK;
+    flags |= ASYNC;
     (void) fcntl (fd, F_SETFL, flags);
 #ifdef USE_STREAMS_ASYNC
     (void) ioctl(fd, I_SETSIG, S_INPUT | S_OUTPUT | S_ERROR | S_HANGUP);
@@ -608,7 +602,7 @@
     int	flags;
 
     flags = fcntl (fd, F_GETFL);
-    flags &= ~(ASYNC|NOBLOCK);
+    flags &= ~ASYNC;
     (void) fcntl (fd, F_SETFL, flags);
 #ifdef  USE_STREAMS_ASYNC
     (void) ioctl(fd, I_SETSIG, 0);
@@ -941,6 +935,44 @@
 
 #define DontBlockIO	(runnable && running)
 
+static Bool
+FileIsReadable (int fd)
+{
+    fd_set	    bits;
+    int		    n;
+    struct timeval  tv;
+
+    if (fd < 3 && !ownTty[fd])
+	return False;
+    do
+    {
+	FD_ZERO (&bits);
+	FD_SET (fd, &bits);
+	tv.tv_usec = 0;
+	tv.tv_sec = 0;
+	n = select (fd + 1, &bits, 0, 0, &tv);
+    } while (n < 0 && errno == EINTR);
+    return n > 0;
+}
+
+static Bool
+FileIsWritable (int fd)
+{
+    fd_set	    bits;
+    int		    n;
+    struct timeval  tv;
+
+    do
+    {
+	FD_ZERO (&bits);
+	FD_SET (fd, &bits);
+	tv.tv_usec = 0;
+	tv.tv_sec = 0;
+	n = select (fd + 1, 0, &bits, 0, &tv);
+    } while (n < 0 && errno == EINTR);
+    return n > 0;
+}
+
 int
 FileInput (Value file)
 {
@@ -993,12 +1025,7 @@
 	    else
 	    {
 		buf = FileBuffer (ic);
-		if (file->file.fd < 3 && !ownTty[file->file.fd])
-		{
-		    n = -1;
-		    err = EWOULDBLOCK;
-		}
-		else
+		if (FileIsReadable (file->file.fd))
 		{
 		    n = ic->size;
 		    if (file->file.flags & FileUnBuf)
@@ -1007,6 +1034,11 @@
 		    err = errno;
 		    file->file.flags &= ~FileEnd;
 		}
+		else
+		{
+		    n = -1;
+		    err = EWOULDBLOCK;
+		}
 		if (n <= 0)
 		{
 		    if (n == 0)
@@ -1076,8 +1108,16 @@
 
     while (ic->ptr < ic->used)
     {
-	n = write (file->file.fd, &FileBuffer(ic)[ic->ptr], ic->used - ic->ptr);
-	err = errno;
+	if (FileIsWritable (file->file.fd))
+	{
+	    n = write (file->file.fd, &FileBuffer(ic)[ic->ptr], ic->used - ic->ptr);
+	    err = errno;
+	}
+	else
+	{
+	    n = -1;
+	    err = EWOULDBLOCK;
+	}
 	if (n > 0)
 	    ic->ptr += n;
 	else




More information about the Commit mailing list