title: How to stop writing to socket (AF_LOCAL/UNIX, SOCK_STREAM) if client can't cope (buffer++)?
body: <p>I have a small application which uses Unix Domain Sockets to communicate data to a client.
  The type of the socket is SOCK_STREAM and it's set to blocking mode (default). I'm having a bit of a trouble with a particular case when the client is lazy and can't cope with the data I'm writing to the socket -- the buffer is tending to get full and I will block in write(), thing which I want to avoid.</p>
  
  <p>I have tried using select/pselect by calling this before a write() in order to see if I can do a write() or not. Things are working only half way, in the sense that I am notified that I cannot write() anymore (select returns 0 when the buffer reaches a certain size) but afterwards, when the client is able to read again, select/pselect doesn't notify this (I was expecting to return back 1 and then I could do write()).</p>
  
  <p>Do you have any ideas on this matter?</p>
  
  <p>Thank you!</p>
  
  <p>EDIT:</p>
  
  <p>server: </p>
  
  
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;sys/stat.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;sys/un.h&gt;
  #include &lt;sys/ioctl.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;errno.h&gt;
  #define SV_SOCK_PATH "/tmp/srv_sk_stream"
  #define BACKLOG 1
  #define MAXWRITE 1000
  #define TOMSEC 1000
  
  int main(int argc, char* argv[]) {
      struct sockaddr_un addr;
      int sfd, cfd = -1;
      ssize_t numRead;
      char buffer[30];
      int i = 0;
      ssize_t retValWrite = -1;
      numRead = sizeof(buffer);
      if(argc !=2 ) {printf("Give the sleep value argument (msec)!\n"); return EXIT_FAILURE;}
      int sleepTime = atoi(argv[1]) * TOMSEC;
      fd_set writeFdSet;
      struct timeval tv;
      tv.tv_sec = 0;
      tv.tv_usec = 0;
      struct timespec ts;
      ts.tv_sec = 0;
      ts.tv_nsec = 0;
  
      /* create socket */
      sfd = socket(AF_UNIX, SOCK_STREAM, 0);
      if (sfd == -1) {perror("FAILED creating a socket!"); return EXIT_FAILURE;}
      if (remove(SV_SOCK_PATH) == -1 &amp;&amp; errno != ENOENT) {perror("FAILED removing old socket fd! - "); return EXIT_FAILURE;}
  
      /* prepare it */
      memset(&amp;addr, 0, sizeof(struct sockaddr_un));
      addr.sun_family = AF_UNIX;
      strncpy(addr.sun_path, SV_SOCK_PATH, sizeof(addr.sun_path) - 1);
  
      /* bind it */
      if (bind(sfd, (struct sockaddr *) &amp;addr, sizeof(struct sockaddr_un)) == -1) {perror("FAILED bind! - "); return EXIT_FAILURE;}
  
      /* start to listen */
      if (listen(sfd, BACKLOG) == -1) {perror("FAILED listen! - "); return EXIT_FAILURE;}
  
      while(i&lt;MAXWRITE) {
          int bytesToRead = 0;
          retValWrite = -13;
  
  
          /* block in accept until a client connects (only one) */
          if (-1 == cfd) {
              cfd = accept(sfd, NULL, NULL);
              if (cfd == -1) {perror("FAILED accept! - "); return EXIT_FAILURE;}
              FD_ZERO(&amp;writeFdSet);
              FD_SET(cfd, &amp;writeFdSet);
          }
  
          //ioctl(cfd,FIONREAD,&amp;bytesToRead);
          //printf("---------&gt; SND_BUFF has %d bytes left to be read\n", bytesToRead);
  
          sprintf(buffer, "PING FROM SERVER %d", i);
          /* write to the client's socket */
          int retValSelect = 0;
          errno = 0;
          retValSelect = select(cfd+1, NULL, &amp;writeFdSet, NULL, &amp;tv);
          //perror("ERRNO from pselect: ");
          if (retValSelect &gt; 0) {
              int retValFdIsSet = 0;
              retValFdIsSet = FD_ISSET(cfd, &amp;writeFdSet);
              //perror("FD_ISSET - ");
              if(retValFdIsSet) {
                  retValWrite = write(cfd, buffer, numRead);
                  if (retValWrite == 0 ) {
                      printf("Written 0 bytes\n");
                  } else if (retValWrite &lt; 0) {
                      perror("Error writiing to socket!\n");
                  }
  
                  ++i;
                  printf("Written: %d \n", i);
  
                  usleep(sleepTime);
              }
          } else  {
              printf("Wait for it... %d\n", count);
          }
      }
  
      /* close client socket */
      if (close(cfd) == -1) {perror("FAILED close srv socket! - "); return EXIT_FAILURE;}
      if (remove(SV_SOCK_PATH) == -1 &amp;&amp; errno != ENOENT) {perror("FAILED removing old socket fd! - "); return EXIT_FAILURE;}
  
      return EXIT_SUCCESS;
  }
  </code></pre>
  
  <p>Client:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;sys/stat.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;sys/un.h&gt;
  #include &lt;sys/ioctl.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;errno.h&gt;
  #define SV_SOCK_PATH "/tmp/srv_sk_stream"
  #define MAXREAD 1000
  #define TOMSEC 1000
  
  int main(int argc, char** argv)
  {
      struct sockaddr_un addr;
      int sfd;
      ssize_t numRead;
      char pingStr[30];
      numRead = sizeof(pingStr);
      int readCount = 0;
      if(argc !=2 ) {printf("Give the sleep value argument (msec)!\n"); return EXIT_FAILURE;}
      int sleepTime = atoi(argv[1]) * TOMSEC;
  
      /* create socket */
      sfd = socket(AF_UNIX, SOCK_STREAM, 0);
  
      if(sfd == -1) {perror("FAILED creating a socket! - "); return EXIT_FAILURE;}
  
      /* prepare it */
      memset(&amp;addr, 0, sizeof(struct sockaddr_un));
      addr.sun_family = AF_UNIX;
      strncpy(addr.sun_path, SV_SOCK_PATH, sizeof(addr.sun_path) - 1);
  
      /* connect */
      if (connect(sfd, (struct sockaddr *) &amp;addr, sizeof(struct sockaddr_un)) == -1) {perror("FAILED connecting to socket! - "); return EXIT_FAILURE;}
  
      while (readCount &lt; MAXREAD) {
          char strRead[numRead];
          int bytesRead=0;
          int bytesToRead=0;
  
          ioctl(sfd,FIONREAD, &amp;bytesToRead);
          printf("---------&gt; RCV_BUFF has %d bytes left to be read\n", bytesToRead);
  
          /* read */
          bytesRead = read(sfd, &amp;strRead, numRead);
          if(bytesRead == 0) {
              perror("Read 0 bytes from socket! - ");
          }
          else if (bytesRead &lt; 0) {
              perror("FAILED reading from socket! - ");
          }
          ++readCount;
          printf("%d - READ: %s\n", readCount, strRead);
          usleep(sleepTime);
      }
  
      /* close */
      if (close(sfd) == -1) {perror("FAILED close clt socket! - "); return EXIT_FAILURE;}
  
      return EXIT_SUCCESS;
  }
  </code></pre>
  
  <p>Output for server (writing at 100 msec)</p>
  
  <pre><code>./srvstream 100
  Written: 1 
  Written: 2 
  Written: 3 
  Written: 4 
  Written: 5 
  Written: 6 
  Written: 7 
  Written: 8 
  Written: 9 
  Written: 10 
  Written: 11 
  Written: 12 
  Written: 13 
  Written: 14 
  Written: 15 
  Written: 16 
  Written: 17 
  Written: 18 
  Written: 19 
  Written: 20 
  Written: 21 
  Written: 22 
  Written: 23 
  Written: 24 
  Written: 25 
  Written: 26 
  Written: 27 
  Written: 28 
  Written: 29 
  Written: 30 
  Written: 31 
  Written: 32 
  Written: 33 
  Written: 34 
  Written: 35 
  Written: 36 
  Written: 37 
  Written: 38 
  Written: 39 
  Written: 40 
  Written: 41 
  Written: 42 
  Written: 43 
  Written: 44 
  Written: 45 
  Written: 46 
  Written: 47 
  Written: 48 
  Written: 49 
  Written: 50 
  Written: 51 
  Written: 52 
  Written: 53 
  Written: 54 
  Written: 55 
  Written: 56 
  Written: 57 
  Written: 58 
  Written: 59 
  Written: 60 
  Written: 61 
  Written: 62 
  Written: 63 
  Written: 64 
  Written: 65 
  Written: 66 
  Written: 67 
  Written: 68 
  Written: 69 
  Written: 70 
  Written: 71 
  Written: 72 
  Written: 73 
  Written: 74 
  Written: 75 
  Written: 76 
  Written: 77 
  Written: 78 
  Wait for it... 0
  Wait for it... 0
  Wait for it... 0
  Wait for it... 0
  Wait for it... 0
  -------&gt;8-------- stays this way even after the client reports consumes the whole buffer
  </code></pre>
  
  <p>client (reading at 1 sec.):</p>
  
  <pre><code>./cltstream 1000
  ---------&gt; RCV_BUFF has 0 bytes left to be read
  1 - READ: PING FROM SERVER 0
  ---------&gt; RCV_BUFF has 270 bytes left to be read
  2 - READ: PING FROM SERVER 1
  ---------&gt; RCV_BUFF has 540 bytes left to be read
  3 - READ: PING FROM SERVER 2
  ---------&gt; RCV_BUFF has 810 bytes left to be read
  4 - READ: PING FROM SERVER 3
  ---------&gt; RCV_BUFF has 1080 bytes left to be read
  5 - READ: PING FROM SERVER 4
  ---------&gt; RCV_BUFF has 1350 bytes left to be read
  6 - READ: PING FROM SERVER 5
  ---------&gt; RCV_BUFF has 1620 bytes left to be read
  7 - READ: PING FROM SERVER 6
  ---------&gt; RCV_BUFF has 1890 bytes left to be read
  8 - READ: PING FROM SERVER 7
  ---------&gt; RCV_BUFF has 2100 bytes left to be read
  9 - READ: PING FROM SERVER 8
  ---------&gt; RCV_BUFF has 2070 bytes left to be read
  10 - READ: PING FROM SERVER 9
  ---------&gt; RCV_BUFF has 2040 bytes left to be read
  11 - READ: PING FROM SERVER 10
  ---------&gt; RCV_BUFF has 2010 bytes left to be read
  12 - READ: PING FROM SERVER 11
  ---------&gt; RCV_BUFF has 1980 bytes left to be read
  13 - READ: PING FROM SERVER 12
  ---------&gt; RCV_BUFF has 1950 bytes left to be read
  14 - READ: PING FROM SERVER 13
  ---------&gt; RCV_BUFF has 1920 bytes left to be read
  15 - READ: PING FROM SERVER 14
  ---------&gt; RCV_BUFF has 1890 bytes left to be read
  16 - READ: PING FROM SERVER 15
  ---------&gt; RCV_BUFF has 1860 bytes left to be read
  17 - READ: PING FROM SERVER 16
  ---------&gt; RCV_BUFF has 1830 bytes left to be read
  18 - READ: PING FROM SERVER 17
  ---------&gt; RCV_BUFF has 1800 bytes left to be read
  19 - READ: PING FROM SERVER 18
  ---------&gt; RCV_BUFF has 1770 bytes left to be read
  20 - READ: PING FROM SERVER 19
  ---------&gt; RCV_BUFF has 1740 bytes left to be read
  21 - READ: PING FROM SERVER 20
  ---------&gt; RCV_BUFF has 1710 bytes left to be read
  22 - READ: PING FROM SERVER 21
  ---------&gt; RCV_BUFF has 1680 bytes left to be read
  23 - READ: PING FROM SERVER 22
  ---------&gt; RCV_BUFF has 1650 bytes left to be read
  24 - READ: PING FROM SERVER 23
  ---------&gt; RCV_BUFF has 1620 bytes left to be read
  25 - READ: PING FROM SERVER 24
  ---------&gt; RCV_BUFF has 1590 bytes left to be read
  26 - READ: PING FROM SERVER 25
  ---------&gt; RCV_BUFF has 1560 bytes left to be read
  27 - READ: PING FROM SERVER 26
  ---------&gt; RCV_BUFF has 1530 bytes left to be read
  28 - READ: PING FROM SERVER 27
  ---------&gt; RCV_BUFF has 1500 bytes left to be read
  29 - READ: PING FROM SERVER 28
  -----------8&lt;------------ -- continues this way until RCV_BUFF has 0 bytes left and then blocks
  </code></pre>