diff --git a/src/io.c b/src/io.c
index 9734c9bee53887c7de265b2e287be813fd67b7e5..19820e8fa9c2f5fa28727a7db0b0f60cf7fb28c1 100644
--- a/src/io.c
+++ b/src/io.c
@@ -234,7 +234,7 @@ static int do_read(struct abstract_read **r, UINT32 length, UINT8 *buffer)
 	case EWOULDBLOCK:  /* aka EAGAIN */
 	  return 0;
 	case EPIPE:
-	  werror("io.c: read() returned EPIPE! Treating it as EOF.\n");
+	  wwrite("io.c: read() returned EPIPE! Treating it as EOF.\n");
 	  return A_EOF;
 	default:
 	  werror("io.c: do_read: read() failed (errno %d), %s\n",
@@ -358,7 +358,7 @@ static void listen_callback(struct lsh_fd *fd)
   res = FD_CALLBACK(self->callback, conn);
   if (LSH_ACTIONP(res))
     {
-      werror("Strange: Accepted a connection, "
+      wwrite("Strange: Accepted a connection, "
 	     "but failed before writing anything.\n");
       close_fd(fd, (LSH_FAILUREP(res)
 		    ? CLOSE_PROTOCOL_FAILURE
@@ -375,7 +375,7 @@ static void connect_callback(struct lsh_fd *fd)
 
   if (LSH_ACTIONP(res))
     {
-      werror("Strange: Connected, "
+      wwrite("Strange: Connected, "
 	     "but failed before writing anything.\n");
     }
   else
@@ -535,6 +535,70 @@ get_inaddr(struct sockaddr_in	* addr,
   return 1;
 }
 
+/* For fd:s in blocking mode. */
+int write_raw(int fd, UINT32 length, UINT8 *data)
+{
+  while(length)
+    {
+      int written = write(fd, data, length);
+
+      if (written < 0)
+	switch(errno)
+	  {
+	  case EINTR:
+	  case EAGAIN:
+	    continue;
+	  default:
+	    return 0;
+	  }
+      
+      length -= written;
+      data += written;
+    }
+  return 1;
+}
+
+int write_raw_with_poll(int fd, UINT32 length, UINT8 *data)
+{
+  while(length)
+    {
+      struct pollfd pfd;
+      int res;
+      int written;
+      
+      pfd.fd = fd;
+      pfd.events = POLLOUT;
+
+      res = poll(&pfd, 1, -1);
+
+      if (res < 0)
+	switch(errno)
+	  {
+	  case EINTR:
+	  case EAGAIN:
+	    continue;
+	  default:
+	    return 0;
+	  }
+      
+      written = write(fd, data, length);
+
+      if (written < 0)
+	switch(errno)
+	  {
+	  case EINTR:
+	  case EAGAIN:
+	    continue;
+	  default:
+	    return 0;
+	  }
+      
+      length -= written;
+      data += written;
+    }
+  return 1;
+}
+
 void io_set_nonblocking(int fd)
 {
   if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
diff --git a/src/io.h b/src/io.h
index b739d24e097d1961673474645094a8d405ece5f0..dcc3e66b8e6f52eba9c86f2ae7de2a844e90ceb3 100644
--- a/src/io.h
+++ b/src/io.h
@@ -159,6 +159,9 @@ int get_inaddr(struct sockaddr_in	* addr,
 	       const char		* service,
 	       const char		* protocol);
 
+int write_raw(int fd, UINT32 length, UINT8 *data);
+int write_raw_with_poll(int fd, UINT32 length, UINT8 *data);
+
 void io_set_nonblocking(int fd);
 void io_set_close_on_exec(int fd);
 void io_init_fd(int fd);