diff --git a/CHANGES b/CHANGES
index df3ae2b..f1efbcc 100644
--- a/CHANGES
+++ b/CHANGES
@@ -20,6 +20,8 @@ Corrections:
 
 	Do not log simple successful write with NOTICE level.
 
+	On partial write to not poll with sleep() but use select()/poll().
+
 Building:
 	Disabling certain features during configure could break build process.
 
diff --git a/sysutils.c b/sysutils.c
index 777388f..a581a53 100644
--- a/sysutils.c
+++ b/sysutils.c
@@ -35,6 +35,9 @@ const int one = 1;
 ssize_t writefull(int fd, const void *buff, size_t bytes) {
    size_t writt = 0;
    ssize_t chk;
+   struct pollfd pfd;
+   int rc;
+
    while (1) {
       chk = Write(fd, (const char *)buff + writt, bytes - writt);
       if (chk < 0) {
@@ -45,10 +48,22 @@ ssize_t writefull(int fd, const void *buff, size_t bytes) {
 	 case EWOULDBLOCK:
 #endif
 	    Warn4("write(%d, %p, "F_Zu"): %s", fd, (const char *)buff+writt, bytes-writt, strerror(errno));
-	    Sleep(1);
+	    pfd.fd      = fd;
+	    pfd.events  = POLLOUT;
+	    pfd.revents = 0;
+	    rc = xiopoll(&pfd, 1, NULL);
+	    if (rc == 0) {
+	       Notice("inactivity timeout triggered");
+	       errno = ETIMEDOUT;
+	       return -1;
+	    }
 	    continue;
-	 default: return -1;
+	 default:
+	    return -1;
 	 }
+      } else if (chk == bytes) {
+	 /* First attempt, complete write */
+	 return chk;
       } else if (writt+chk < bytes) {
 	 Warn4("write(%d, %p, "F_Zu"): only wrote "F_Zu" bytes, trying to continue (meanwhile, other direction is blocked)",
 	       fd, (const char *)buff+writt, bytes-writt, chk);
@@ -56,6 +71,8 @@ ssize_t writefull(int fd, const void *buff, size_t bytes) {
       } else if (writt == 0) {
 	 /* First attempt, write complete - no extra message */
 	 return chk;
+      } else { 	/* write completed */
+	 break;
       }
    }
    Notice3("write(%d, %p, "F_Zu") completed", fd, (const char *)buff, bytes);