Date: Tue, 3 Apr 2007 08:10:55 -0400 From: "Jason Carroll" <jcarroll@gmail.com> To: freebsd-hackers@freebsd.org Subject: kevent and unix dgram socket problem Message-ID: <da4a53d80704030510r32aa98eek4e7b01fb781ea205@mail.gmail.com>
next in thread | raw e-mail | index | archive | help
Hi everyone-- I'm working on an application that is attempting to use kqueues to detect data arriving at a unix domain datagram socket, but kevents don't appear to get delivered when a datagram arrives. Using poll() for the same purpose appears to work fine. Also, if I switch the socket to the AF_INET domain, I see the correct behavior with kevent(). I distilled the problem into two files that I included. listen.cc creates a unix socket and blocks for data on a kevent() call. write.cc sends a brief message to the same unix socket. I've seen the problem on 6-STABLE and 4.5-RELEASE. Anyone have any thoughts or comments? Thanks, Jason // ================ listen.cc ================= #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <sys/un.h> #include <arpa/inet.h> #include <errno.h> #include <fcntl.h> #include <netdb.h> #include <signal.h> #include <string.h> #include <sys/filio.h> #include <sys/event.h> #include <sys/types.h> #include <net/if.h> #include <sys/sockio.h> #include <stdio.h> #include <assert.h> #include <poll.h> #define LISTENQ 2 #define UN_PATH_LEN sizeof(((struct sockaddr_un*)0)->sun_path) int main(int argc, char *argv[]) { // new socket int fd = socket(AF_LOCAL, SOCK_DGRAM, 0); assert(fd >= 0); // make sure there isn't something in it's way unlink("usock"); // create the local address, bind & listen struct sockaddr_un addr; memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_LOCAL; strncpy(addr.sun_path, "usock", UN_PATH_LEN - 1); assert(bind(fd, (sockaddr*) &addr, sizeof(sockaddr_un)) == 0); assert(listen(fd, LISTENQ) == 0); char buf[1024]; int nread; // uncomment this line to prove my socket is set up correctly // nread = read(fd, buf, sizeof(buf)); // printf("read %d bytes\n", nread); int kqueueFD; kqueueFD = kqueue(); struct kevent event; EV_SET(&event, fd, EVFILT_READ, EV_ADD, 0, 0, 0); assert(kevent(kqueueFD, &event, 1, 0, 0, 0) == 0); struct pollfd pfd; pfd.fd = fd; pfd.events = POLLIN; pfd.revents = 0; int r; // uncomment the following two lines to see poll behavior // while ((r = poll(&pfd, 1, INFTIM)) >= 0) { // printf("poll returned %d\n", r); // uncomment the following two lines to see kqueue behavior while ((r = kevent(kqueueFD, 0, 0, &event, 1, 0)) >= 0) { printf("kevent returned %d\n", r); nread = read(fd, buf, sizeof(buf)); printf("read %d bytes\n", nread); } } // ================ write.cc ================= #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <sys/un.h> #include <arpa/inet.h> #include <errno.h> #include <fcntl.h> #include <netdb.h> #include <signal.h> #include <string.h> #include <sys/filio.h> #include <sys/event.h> #include <sys/types.h> #include <net/if.h> #include <sys/sockio.h> #include <stdio.h> #include <assert.h> #define LISTENQ 2 #define UN_PATH_LEN sizeof(((struct sockaddr_un*)0)->sun_path) int main(int argc, char *argv[]) { int fd = socket(AF_LOCAL, SOCK_DGRAM, 0); assert(fd >= 0); // create the local address & "connect" struct sockaddr_un addr; memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_LOCAL; strncpy(addr.sun_path, "usock", UN_PATH_LEN - 1); assert(connect(fd, (sockaddr*) &addr, sizeof(sockaddr_un)) == 0); const char *msg = "this is the message\n"; write(fd, msg, strlen(msg)); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?da4a53d80704030510r32aa98eek4e7b01fb781ea205>