+ retval = fcntl(pipefds[0], F_SETFL, O_NONBLOCK);
+ if (retval < 0) {
+ err("error fcntl on read pipe: %s", strerror(errno));
+ goto exit;
+ }
+ retval = fcntl(pipefds[0], F_SETFD, FD_CLOEXEC);
+ if (retval < 0)
+ err("error fcntl on read pipe: %s", strerror(errno));
+
+ retval = fcntl(pipefds[1], F_SETFL, O_NONBLOCK);
+ if (retval < 0) {
+ err("error fcntl on write pipe: %s", strerror(errno));
+ goto exit;
+ }
+ retval = fcntl(pipefds[1], F_SETFD, FD_CLOEXEC);
+ if (retval < 0)
+ err("error fcntl on write pipe: %s", strerror(errno));
+
+ /* set signal handlers */
+ memset(&act, 0x00, sizeof(struct sigaction));
+ act.sa_handler = (void (*)(int)) sig_handler;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_RESTART;
+ sigaction(SIGINT, &act, NULL);
+ sigaction(SIGTERM, &act, NULL);
+ sigaction(SIGALRM, &act, NULL);
+ sigaction(SIGCHLD, &act, NULL);
+
+ if (init_udevsend_socket() < 0) {
+ if (errno == EADDRINUSE)
+ dbg("another udevd running, exit");
+ else
+ dbg("error initialising udevsend socket: %s", strerror(errno));
+
+ goto exit;
+ }
+
+ /* possible override of udev binary, used for testing */
+ udev_bin = getenv("UDEV_BIN");
+ if (udev_bin != NULL)
+ info("udev binary is set to '%s'", udev_bin);
+ else
+ udev_bin = UDEV_BIN;
+
+ /* possible init of expected_seqnum value */
+ udevd_expected_seqnum = getenv("UDEVD_EXPECTED_SEQNUM");
+ if (udevd_expected_seqnum != NULL) {
+ expected_seqnum = strtoull(udevd_expected_seqnum, NULL, 10);
+ info("initialize expected_seqnum to %llu", expected_seqnum);
+ }
+
+ /* get current time to provide shorter timeout on startup */
+ sysinfo(&info);
+ startup_time = info.uptime;
+
+ FD_ZERO(&readfds);
+ FD_SET(udevsendsock, &readfds);
+ FD_SET(pipefds[0], &readfds);
+ maxsockplus = udevsendsock+1;
+ while (1) {
+ struct hotplug_msg *msg;
+
+ fd_set workreadfds = readfds;
+ retval = select(maxsockplus, &workreadfds, NULL, NULL, NULL);
+
+ if (retval < 0) {
+ if (errno != EINTR)
+ dbg("error in select: %s", strerror(errno));
+ continue;
+ }
+
+ if (FD_ISSET(udevsendsock, &workreadfds)) {
+ msg = get_udevsend_msg();
+ if (msg)
+ msg_queue_insert(msg);
+ }
+
+ if (FD_ISSET(pipefds[0], &workreadfds))
+ user_sighandler();
+
+ if (sigchilds_waiting) {
+ sigchilds_waiting = 0;
+ reap_sigchilds();
+ }
+
+ if (run_msg_q) {
+ run_msg_q = 0;
+ msg_queue_manager();
+ }
+
+ if (run_exec_q) {
+ /* clean up running_list before calling exec_queue_manager() */
+ if (sigchilds_waiting) {
+ sigchilds_waiting = 0;
+ reap_sigchilds();
+ }
+
+ run_exec_q = 0;
+ exec_queue_manager();
+ }
+ }