improper 0 return from blocking read on unix domain socket

Scott Stevens <[email protected]> Thu, 17 Nov 2005 08:10:45 -0800 (PST)
Newsgroups gmane.linux.redhat.devel
Message-ID <[email protected]>
--0-409225780-1132243845=:4488
Content-Type: multipart/alternative; boundary="0-1379195060-1132243845=:4488"

--0-1379195060-1132243845=:4488
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

  We seem to be getting improper returns from blocking reads on unix doma=
in sockets.  We're getting a 0 return where we expect to block (and do on=
 all other platforms including redhat 8.0).  We've seen this issue on AS =
3 and 4 as well as other variants.
  =20
  Attached is a program that shows the problem.  Failure is indicated by =
"read returned 0."
  =20
  I haven't found a bug that seems to address this.  Inserting an additio=
nal select in front of the read corrects this behavior, but doesn't seem =
correct.
  =20
  Has anybody seen this behavior before?  Is there already a bug for it?
  =20
  Thanks,
  Scott


	=09
---------------------------------
 Yahoo! FareChase - Search multiple travel sites in one click. =20
--0-1379195060-1132243845=:4488
Content-Type: text/html; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

<DIV id=3DRTEContent>  <DIV id=3DRTEContent>We seem to be getting imprope=
r returns from blocking reads on unix domain sockets.&nbsp; We're getting=
 a 0 return where we expect to block (and do on all other platforms inclu=
ding redhat 8.0).&nbsp; We've seen this issue on AS 3 and 4 as well as ot=
her variants.</DIV>  <DIV>&nbsp;</DIV>  <DIV>Attached is a program that s=
hows the problem.&nbsp; Failure is indicated by "read returned 0."</DIV> =
 <DIV>&nbsp;</DIV>  <DIV>I haven't found a bug that seems to address this=
.&nbsp; Inserting an additional select in front of the read corrects this=
 behavior, but doesn't seem correct.</DIV>  <DIV>&nbsp;</DIV>  <DIV>Has a=
nybody seen this behavior before?&nbsp; Is there already a bug for it?</D=
IV>  <DIV>&nbsp;</DIV>  <DIV>Thanks,</DIV>  <DIV>Scott</DIV></DIV><p>
		<hr size=3D1> <a href=3D"http://us.lrd.yahoo.com/_ylc=3DX3oDMTFqODRtdXQ=
4BF9TAzMyOTc1MDIEX3MDOTY2ODgxNjkEcG9zAzEEc2VjA21haWwtZm9vdGVyBHNsawNmYw--=
/SIG=3D110oav78o/**http%3a//farechase.yahoo.com/">Yahoo! FareChase - Sear=
ch multiple travel sites in one click.</a>

=20

=20
--0-1379195060-1132243845=:4488--
--0-409225780-1132243845=:4488
Content-Type: text/plain; name="socketuit.c"
Content-Description: 1206183985-socketuit.c
Content-Disposition: inline; filename="socketuit.c"

#include <sys/types.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
#define BUFSIZE 340
char buf[BUFSIZE];
struct sockaddr_un sockaddr;
void parent(int do_select) {
    int fd, new_fd;
    int rc;
    ssize_t read_rc;
    struct sockaddr_un new_addr;
    struct timeval to;
    int attr_size;
    fd_set readfds;
    fd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (fd < 0) {
        perror("socket");
        exit(1);
    }
    if (bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) {
                perror("bind");
                exit(1);
    }
    if (listen(fd, 30)) {
      perror("listen");
      exit(1);
    }
    while (1) {
      FD_ZERO(&readfds);
      FD_SET(fd, &readfds);
      rc = select(FD_SETSIZE, &readfds, 0,0,0);
      if (rc == 1) {
	 attr_size = sizeof(new_addr);
         new_fd = accept(fd, (struct sockaddr *)&new_addr, &attr_size);
         if (new_fd < 0) {
            perror("accept");
            exit(1);
         }
         if (do_select) {
	         FD_ZERO(&readfds);
	         FD_SET(new_fd, &readfds);
	         to.tv_sec = 1;
	         to.tv_usec = 0;
	         while (select(FD_SETSIZE, &readfds, 0,0,&to) < 0) {
	             perror("select");
	            FD_ZERO(&readfds);
	            FD_SET(new_fd, &readfds);
	            to.tv_sec = 1;
	            to.tv_usec = 0;
	         }
         }
         read_rc = read(new_fd, &buf, sizeof(buf));
         if (read_rc <= 0) {
             if (read_rc < 0) {
                 perror("read");
             }
             fprintf(stderr, "read returned %d\n", read_rc);
         }
         close(new_fd);
      }
    }
}

void child() {
    int fd;
    int rc;
    int cycle = 0;
    ssize_t write_rc;
    sleep(2);
    while (1) {
       cycle++;
       fd = socket(AF_UNIX, SOCK_STREAM, 0);
       if (fd < 0) {
           perror("socket");
           exit(1);
       }
       if (connect(fd, (struct sockaddr *) &sockaddr, sizeof(sockaddr))) {
                   perror("connect");
                   fprintf(stderr, "cycle %d\n", cycle);
                   close(fd);
                   continue;
       }
       write_rc = write(fd, &buf, sizeof(buf));
       if (write_rc <= 0) {
          if (write_rc < 0) {
              perror("write");
          }
          fprintf(stderr, "write returned %d\n", write_rc);
       }
       close(fd);
    }
}
main (int argc, char *argv[]) {
    pid_t fork_rc;
    int opt;
    int do_select = 0;
    char dirbuf[1024];
    while ((opt = getopt(argc, argv, "s")) != -1) {
      if (opt == 's') {
         do_select = 1;
         continue;
      }
      else {
         fprintf(stderr, "unsupported option: %c\n", opt);
         exit(1);
      }
    }
    bzero(&sockaddr, sizeof(sockaddr));
    sockaddr.sun_family = AF_UNIX;
    getcwd(dirbuf, sizeof(dirbuf));
    sprintf(sockaddr.sun_path, "%s/sock%d", dirbuf, getpid());
    unlink(sockaddr.sun_path);
    fork_rc = fork();
    if (fork_rc < 0) {
        perror("fork");
        exit(1);
    }
    if (fork_rc) parent(do_select);
    else child();
}

--0-409225780-1132243845=:4488
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Redhat-devel-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/redhat-devel-list
--0-409225780-1132243845=:4488--