diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet udev/udevd.c myudev/udevd.c --- udev/udevd.c Wed Feb 18 00:50:51 2004 +++ myudev/udevd.c Wed Feb 18 01:16:00 2004 @@ -232,6 +232,7 @@ struct iovec iov; struct ucred *cred; char cred_msg[CMSG_SPACE(sizeof(struct ucred))]; + struct sockaddr_un addr; msg = msg_create(); if (msg == NULL) { @@ -247,13 +248,21 @@ smsg.msg_iovlen = 1; smsg.msg_control = cred_msg; smsg.msg_controllen = sizeof(cred_msg); + smsg.msg_name = &addr; + smsg.msg_namelen = sizeof(addr); retval = recvmsg(sock, &smsg, 0); if (retval < 0) { if (errno != EINTR) dbg("unable to receive message"); - return; + goto skip; } + + if (retval != sizeof(struct hotplug_msg)) { + dbg("wrong message size"); + goto skip; + } + cmsg = CMSG_FIRSTHDR(&smsg); cred = (struct ucred *) CMSG_DATA(cmsg); @@ -271,7 +280,10 @@ dbg("message magic '%s' doesn't match, ignore it", msg->magic); goto skip; } - + + memcpy(&msg->addr, smsg.msg_name, smsg.msg_namelen); + msg->addrlen = smsg.msg_namelen; + /* if no seqnum is given, we move straight to exec queue */ if (msg->seqnum == -1) { list_add(&msg->list, &exec_list); @@ -304,7 +316,7 @@ } } -static void udev_done(int pid) +static void udev_done(int pid, int sock) { /* find msg associated with pid and delete it */ struct hotplug_msg *msg; @@ -312,6 +324,10 @@ list_for_each_entry(msg, &running_list, list) { if (msg->pid == pid) { dbg("<== exec seq %d came back", msg->seqnum); + + /* send ack back to udevsend */ + sendto(sock, msg, sizeof(struct hotplug_msg), 0, (struct sockaddr*) &msg->addr, msg->addrlen); + run_queue_delete(msg); return; } @@ -384,7 +400,7 @@ int pid = waitpid(-1, 0, WNOHANG); if ((pid == -1) || (pid == 0)) break; - udev_done(pid); + udev_done(pid, ssock); } } } diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet udev/udevd.h myudev/udevd.h --- udev/udevd.h Thu Feb 5 23:44:52 2004 +++ myudev/udevd.h Wed Feb 18 01:16:50 2004 @@ -28,13 +28,16 @@ #define EVENT_TIMEOUT_SEC 5 #define UDEVSEND_CONNECT_RETRY 20 /* x 100 millisec */ #define UDEVD_SOCK_PATH "udevd" +#define ACK_TIMEOUT_SEC (EVENT_TIMEOUT_SEC + 1) struct hotplug_msg { - char magic[20]; struct list_head list; pid_t pid; - int seqnum; time_t queue_time; + struct sockaddr_un addr; + socklen_t addrlen; + char magic[20]; + int seqnum; char action[8]; char devpath[128]; char subsystem[16]; diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet udev/udevsend.c myudev/udevsend.c --- udev/udevsend.c Wed Feb 18 00:50:51 2004 +++ myudev/udevsend.c Wed Feb 18 00:58:02 2004 @@ -22,6 +22,7 @@ * */ +#include #include #include #include @@ -180,6 +181,14 @@ memset(&saddr, 0x00, sizeof(saddr)); saddr.sun_family = AF_LOCAL; + sprintf(&saddr.sun_path[1], "%d", getpid()); + addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; + + if (bind(sock, (struct sockaddr*)&saddr, addrlen) < 0) { + dbg("error binding socket"); + goto exit; + } + /* use abstract namespace for socket path */ strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; @@ -188,11 +197,36 @@ /* If we can't send, try to start daemon and resend message */ loop = UDEVSEND_CONNECT_RETRY; +send_msg: while (loop--) { retval = sendto(sock, &msg, size, 0, (struct sockaddr *)&saddr, addrlen); if (retval != -1) { - retval = 0; - goto close_and_exit; + + /* wait for ack */ + fd_set rdset; + int rc; + struct timeval tv = {ACK_TIMEOUT_SEC, 0}; + + while(1) { + FD_ZERO(&rdset); + FD_SET(sock, &rdset); + rc = select(sock+1, &rdset, 0, 0, &tv); + + if (!rc) + goto send_msg; + + if (FD_ISSET(sock, &rdset)) { + struct hotplug_msg ack; + + retval = recv(sock, &ack, sizeof(ack), MSG_DONTWAIT); + if ((retval > 0) && + (strncmp(ack.magic, msg.magic, sizeof(UDEV_MAGIC)) == 0 ) && + (ack.seqnum == msg.seqnum)) { + retval = 0; + goto close_and_exit; + } + } + } } if (errno != ECONNREFUSED) { Binary files udev/udevtest and myudev/udevtest differ