diff --git a/src/io.c b/src/io.c
index 2132654436077da0c388399ea95f2f7749ebbfb6..a65acbe89c2273916c504dd749888318a49e01a0 100644
--- a/src/io.c
+++ b/src/io.c
@@ -102,7 +102,9 @@ static void really_close_fd(struct io_fd *fd)
    * to choose an exit code. */
   if (fd->close_callback && fd->close_reason)
     (void) CLOSE_CALLBACK(fd->close_callback, fd->close_reason);
-  
+
+  debug("Closing fd %d.\n", fd->fd);
+
   close(fd->fd);
 
   /* Make sure writing to the buffer fails. */
@@ -124,6 +126,8 @@ static void really_close_fd(struct io_fd *fd)
 #endif
 }
 
+/* FIXME: This code breaks horribly if new files are created by a
+ * callback function. */
 int io_iter(struct io_backend *b)
 {
   struct pollfd *fds;
@@ -132,6 +136,31 @@ int io_iter(struct io_backend *b)
   int timeout;
   int res;
 
+  /* We must first look at the write descriptors, to see if any of
+   * them should be closed. */
+
+  i = 0;
+  FOR_FDS(struct io_fd, fd, b->io, i++)
+    {
+      /* pre_write returns 0 if the buffer is empty */
+      if (fd->buffer)
+	{
+	  /* Ignores return value. Look at the empty attribute instead- */
+	  (void) write_buffer_pre_write(fd->buffer);
+
+	  if (fd->buffer->empty && fd->buffer->closed)
+	    {
+	      really_close_fd(fd);
+	    
+	      UNLINK_FD;
+	    
+	      b->nio--;
+	      continue;
+	    }
+	}
+    }
+  END_FOR_FDS;
+  
   nfds = b->nio + b->nlisten + b->nconnect;
 
   if (b->callouts)
@@ -167,18 +196,8 @@ int io_iter(struct io_backend *b)
       if (fd->handler && !fd->on_hold)
 	fds[i].events |= POLLIN;
 
-      /* pre_write returns 0 if the buffer is empty */
-      if (fd->buffer)
-	{
-	  if (write_buffer_pre_write(fd->buffer))
-	    fds[i].events |= POLLOUT;
-	  else
-	    /* Buffer is empty. Should we close? */
-	    if (fd->buffer->closed)
-	      {
-		fd->close_now = 1;
-	      }
-	}
+      if (fd->buffer && !fd->buffer->empty)
+	fds[i].events |= POLLOUT;
     }
   END_FOR_FDS;
 
@@ -314,7 +333,12 @@ int io_iter(struct io_backend *b)
 	      else if (res & LSH_CLOSE)
 		{
 		  if (fd->buffer)
-		    write_buffer_close(fd->buffer);
+		    {
+		      write_buffer_close(fd->buffer);
+		      /* Don't attempt to read any further. */
+		      /* FIXME: Is it safe to free the handler here? */
+		      fd->handler = NULL;
+		    }
 		  else
 		    fd->close_now = 1;
 		  
@@ -795,5 +819,7 @@ struct io_fd *io_write(struct io_backend *b,
 
 void close_fd(struct io_fd *fd)
 {
+  debug("Marking fd %d for closing.\n", fd->fd);
+  
   fd->close_now = 1;
 }