Networking Forums

Networking Forums > Computer Networking > Linux Networking > linux improper 0 return from read on blocking unix domain socket

Reply
Thread Tools Display Modes

linux improper 0 return from read on blocking unix domain socket

 
 
tx_scott_stevens@yahoo.com
Guest
Posts: n/a

 
      11-18-2005, 10:11 PM
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

#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();
}

 
Reply With Quote
 
 
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Unix domain socket: can't test for blocking before sendto Poluekt Linux Networking 2 11-22-2010 07:27 PM
linux c socket read html problem step Linux Networking 2 06-13-2007 11:59 AM
Sniff local IPC via Unix Domain Socket sjhesse@gmail.com Linux Networking 0 06-02-2007 08:21 PM
Telnet equivalent to Unix domain socket? hobinyoon@gmail.com Linux Networking 1 01-30-2007 11:57 AM
Tool to Dump Unix Domain Socket Traffic? Hokousha Linux Networking 0 05-26-2004 02:09 AM



1 2 3 4 5 6 7 8 9 10 11