improper 0 return from blocking read on unix domain socket

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We seem to be getting improper returns from blocking reads on unix domain 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.
 
Attached is a program that shows the problem.  Failure is indicated by "read returned 0."
 
I haven't found a bug that seems to address this.  Inserting an additional select in front of the read corrects this behavior, but doesn't seem correct.
 
Has anybody seen this behavior before?  Is there already a bug for it?
 
Thanks,
Scott


Yahoo! FareChase - Search multiple travel sites in one click.
#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();
}
_______________________________________________
Redhat-devel-list mailing list
Redhat-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/redhat-devel-list

[Index of Archives]     [Kernel Newbies]     [Red Hat General]     [Fedora]     [Red Hat Install]     [Linux Kernel Development]     [Yosemite News]

  Powered by Linux