Re: Problem with socketpair , AF_UNIX and select call - can anybody through any light on this!



Luciano Rocha wrote:
......
Is there a reason for using SOCK_DGRAM instead of the usual SOCK_STREAM?
The latter will make the recv return 0, indicating the other end closed
the connection, as it did happen, as one peers exits before the other
select(2)s:

$ ./socketpair server - Socket is ready to write
server - Socket is not ready to read
exited: 14520
master - Socket is ready to write
master - Socket is ready to read
master - recv - Resource temporarily unavailable(11)

This could be a bug, or standard behaviour for disconnected datagram
sockets (I don't know enough of the standards).

I attach a slightly improved version. This sleeps for an hour on both sides. I have tried removing the MSG_DONTWAIT but still get the same response.

The SOCK_DGRAM is because I have small packets flowing that I do not want fragmented but do not mind if they get lost, .... but then inside a machine that does not matter. However with SOCK_STREAM I get zero length messages but still ready to read continuously!!! See attached!

--

Howard Wilkinson



Phone:



+44(20)76907075

Coherent Technology Limited



Fax:





23 Northampton Square,



Mobile:



+44(7980)639379

United Kingdom, EC1V 0HL



Email:



howard@xxxxxxxxxxx



#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

int socktest(int fd, char *prefix) {
fd_set rfd, wfd, efd;
int rv;
char buf[1024];
struct timeval timeout = { 10, 0 };

while (1) {
FD_ZERO(&rfd);
FD_ZERO(&wfd);
FD_ZERO(&efd);
FD_SET(fd, &rfd);
FD_SET(fd, &wfd);
FD_SET(fd, &efd);

rv = select(fd+1, &rfd, &wfd, &efd, &timeout);
if (rv < 0) {
printf("%s - select %s", prefix, strerror(errno));
exit(1);
}

if (FD_ISSET(fd, &wfd)) printf("%s - Socket is ready to write\n", prefix);
if (FD_ISSET(fd, &efd)) printf("%s - Socket is in except\n", prefix);

if (FD_ISSET(fd, &rfd)) {
printf("%s - Socket is ready to read\n", prefix);
rv = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
if (rv < 0) {
printf("%s - recv - %s(%d)\n", prefix, strerror(errno), errno);
sleep (10);
exit (1);
}

printf("%s - Socket returned %d bytes\n", prefix, rv);
} else {
printf("%s - Socket is not ready to read\n", prefix);
}

sleep(10);
}
exit (0);
}

int main() {
int fd[2] = { -1, -1 };
int rv;
pid_t pid;

rv = socketpair(PF_UNIX, SOCK_STREAM, 0, fd);
if (rv < 0) printf("socketpair");

fcntl(fd[0], F_SETFL, fcntl(fd[0], F_GETFL, 0) | O_NONBLOCK);
fcntl(fd[1], F_SETFL, fcntl(fd[1], F_GETFL, 0) | O_NONBLOCK);

if ((pid = fork()) > 0) {
shutdown(fd[1], 2);
close(fd[1]);
socktest(fd[0], "master");
} else {
shutdown(fd[0], 2);
close(fd[0]);
socktest(fd[1], "server");
}
}

--
fedora-list mailing list
fedora-list@xxxxxxxxxx
To unsubscribe: https://www.redhat.com/mailman/listinfo/fedora-list

Relevant Pages