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