From 2a476d30f44c4ce90f1bbc72d4be1485e9d6fc47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se>
Date: Tue, 1 Sep 1998 19:45:03 +0200
Subject: [PATCH] New conventions for the return values from
 abstract_read-functions.

Use the same list for input- and output-fd:s.

Rev: src/io.c:1.3
Rev: src/io.h:1.3
---
 src/io.c | 117 ++++++++++++++++++++++++++++++-------------------------
 src/io.h |  18 ++++-----
 2 files changed, 72 insertions(+), 63 deletions(-)

diff --git a/src/io.c b/src/io.c
index 1c68ad1b9..9eaa45dc8 100644
--- a/src/io.c
+++ b/src/io.c
@@ -22,14 +22,25 @@ struct fd_read
 
 static int do_read(struct fd_read *closure, UINT8 *buffer, UINT32 length)
 {
-  int res;
-  do
-    res = read(closure->fd, buffer, length);
-  while ( (res < 0)
-	  && ( (errno == EINTR)
-	       || (errno == EAGAIN) ) );
-  return res;
-};
+  while(1)
+    {
+      int res = read(closure->fd, buffer, length);
+      if (!res)
+	return A_EOF;
+      if (res > 0)
+	return res;
+      
+      switch(errno)
+	{
+	case EINTR:
+	  continue;
+	case EWOULDBLOCK:  /* aka EAGAIN */
+	  return 0;
+	default:
+	  return A_FAIL;
+	}
+    }
+}
 
 #define FOR_FDS(type, fd, list, extra)				\
 {								\
@@ -51,7 +62,7 @@ void io_run(struct io_backend *b)
       int timeout;
       int res;
       
-      nfds = b->ninput + b->noutput + b->nlisten + n->nconnect;
+      nfds = b->nio + b->nlisten + n->nconnect;
 
       if (b->callouts)
 	{
@@ -79,10 +90,14 @@ void io_run(struct io_backend *b)
       /* Handle fds in order: read, accept, connect, write, */
       i = 0;
 
-      FOR_FDS(struct input_fd, fd, b->input, i++)
+      FOR_FDS(struct io_fd, fd, b->io, i++)
 	{
 	  fds[i]->fd = fd->hold_on ? -1 : fd->fd;
-	  fds[i]->events = POLLIN;
+	  fds[i]->events =
+	    (fd->hold_on ? 0 : POLLIN)
+	    /* pre_write returns 0 if the buffer is empty */
+	    | (write_buffer_pre_write(fd->buffer)
+	       ? POLLOUT : 0);
 	}
       END_FOR_FDS;
 
@@ -100,15 +115,6 @@ void io_run(struct io_backend *b)
 	}
       END_FOR_FDS;
 
-      FOR_FDS(struct output_fd, fd, b->output, i++)
-	{
-	  /* pre_write returns 0 if the buffer is empty */
-	  fds[i]->fd = write_buffer_pre_write(fd->buffer)
-	    ? fd->fd : -1
-	    fds[i]->events = POLLOUT;
-	}
-      END_FOR_FDS;
-
       res = poll(fds, nfds, timeout);
 
       if (!res)
@@ -136,14 +142,50 @@ void io_run(struct io_backend *b)
 	{ /* Process files */
 	  i = 0;
 
-	  FOR_FDS(struct input_fd, fd, b->input, i++)
+	  /* Handle writing first */
+	  FOR_FDS(struct io_fd, fd, b->io, i++)
+	    {
+	      if (fds[i]->revents & POLLOUT)
+		{
+		  UINT32 size = MIN(fd->buffer->end - fd->buffer->start,
+				    fd->buffer->block_size);
+		  int res = write(fd->fd, fd->buffer->data + fd->buffer->start,
+				  size);
+		  if (!res)
+		    fatal("Closed?");
+		  if (res < 0)
+		    switch(errno)
+		      {
+		      case EINTR:
+		      case EAGAIN:
+			break;
+		      default:
+			CALLBACK(fd->close_callback);
+			/* FIXME: Must do this later. Perhaps add a
+			 * closed flag to th io_fd struct? */
+#if 0
+			UNLINK_FD;
+			free(fd->write_buffer);
+			free(fd);
+#endif
+			break;
+		      }
+		  else
+		    fd->buffer->start += res;
+		}
+	    }
+	  END_FOR_FDS;
+
+	  /* Handle reading */
+	  i = 0; /* Start over */
+	  FOR_FDS(struct io_fd, fd, b->io, i++)
 	    {
 	      if (fds[i]->revents & POLLIN)
 		{
 		  struct fd_read r =
-		  { { (abstract_read_f) do_read }, fd->fd };
+		  { { (abstract_read_f) do_read }, fd->fd, 0 };
 
-		  /* The handler function returns a ew handler for the
+		  /* The handler function returns a new handler for the
 		   * file, or NULL. */
 		  if (!(fd->handler = READ_HANDLER(fd->handler, &r)))
 		    {
@@ -187,35 +229,6 @@ void io_run(struct io_backend *b)
 		}
 	    }
 	  END_FOR_FDS;
-
-	  FOR_FDS(struct output_fd, fd, b->output, i++)
-	    {
-	      if (fds[i]->revents & POLLOUT)
-		{
-		  UINT32 size = MIN(fd->buffer->end - fd->buffer->start,
-				    fd->buffer->block_size);
-		  int res = write(fd->fd, fd->buffer->data + fd->buffer->start,
-				  size);
-		  if (!res)
-		    fatal("Closed?");
-		  if (res < 0)
-		    switch(errno)
-		      {
-		      case EINTR:
-		      case EAGAIN:
-			break;
-		      default:
-			CALLBACK(fd->close_Callback);
-			UNLINK_FD;
-			free(fd->write_buffer);
-			free(fd);
-			break;
-		      }
-		  else
-		    fd->buffer->start += res;
-		}
-	    }
-	  END_FOR_FDS;
 	}
     }
 }
diff --git a/src/io.h b/src/io.h
index f2cc79467..48a91dc37 100644
--- a/src/io.h
+++ b/src/io.h
@@ -8,18 +8,16 @@
 #include "abstract_io.h"
 #include "write_buffer.h"
 
-struct input_fd
+struct io_fd
 {
-  struct input_fd *next;
+  struct io_fd *next;
   int fd;
+
+  /* Reading */
   struct read_handler *handler;
   int on_hold; /* For flow control */
-};
 
-struct output_fd
-{
-  struct output_fd *next;
-  int fd;
+  /* Writing */
   struct write_buffer *buffer;
   struct callback *close_callback;
 };
@@ -59,10 +57,8 @@ struct callout
 
 struct io_backend
 {
-  unsigned ninput;
-  struct input_fd *input;
-  unsigned noutput;
-  struct output_fd *output;
+  unsigned nio;
+  struct io_fd *io;
   unsigned nlisten;
   struct listen_fd *listen;
   unsigned nconnect;
-- 
GitLab