+ 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_uevent_netlink_sock() < 0) {
+ dbg("uevent socket not available");
+ }
+
+ if (init_udevd_socket() < 0) {
+ if (errno == EADDRINUSE)
+ dbg("another udevd running, exit");
+ else
+ dbg("error initialising udevd socket: %s", strerror(errno));
+
+ goto exit;
+ }
+
+ /* override of forked 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;
+
+ /* init of expected_seqnum value */
+ value = getenv("UDEVD_EXPECTED_SEQNUM");
+ if (value) {
+ expected_seqnum = strtoull(value, NULL, 10);
+ info("initialize expected_seqnum to %llu", expected_seqnum);
+ }
+
+ /* timeout to wait for missing events */
+ value = getenv("UDEVD_EVENT_TIMEOUT");
+ if (value)
+ event_timeout = strtoul(value, NULL, 10);
+ else
+ event_timeout = UDEVD_EVENT_TIMEOUT;
+ info("initialize event_timeout to %u", event_timeout);
+
+ /* maximum limit of forked childs */
+ value = getenv("UDEVD_MAX_CHILDS");
+ if (value)
+ max_childs = strtoul(value, NULL, 10);
+ else
+ max_childs = UDEVD_MAX_CHILDS;
+ info("initialize max_childs to %u", max_childs);
+
+ /* start to throttle forking if maximum number of _running_ childs is reached */
+ value = getenv("UDEVD_MAX_CHILDS_RUNNING");
+ if (value)
+ max_childs_running = strtoull(value, NULL, 10);
+ else
+ max_childs_running = UDEVD_MAX_CHILDS_RUNNING;
+ info("initialize max_childs_running to %u", max_childs_running);
+
+ FD_ZERO(&readfds);
+ FD_SET(udevd_sock, &readfds);
+ if (uevent_netlink_sock != -1)
+ FD_SET(uevent_netlink_sock, &readfds);
+ FD_SET(pipefds[0], &readfds);
+ maxsockplus = udevd_sock+1;