chiark / gitweb /
udevd: cleanup std{in,our,err} on startup
authorMatthias Schwarzott <zzam@gentoo.org>
Tue, 13 Mar 2007 21:27:21 +0000 (22:27 +0100)
committerKay Sievers <kay.sievers@vrfy.org>
Tue, 13 Mar 2007 21:27:21 +0000 (22:27 +0100)
It occurs, when root-partition has no /dev/console, meaning that kernel
could not open it, and such udevd is started without open filedescriptors
0 1 2. In that case udevd openes its sockets (netlink and control). They
get fds between 0 and 2. Later duping /dev/null to 0 1 2 closes the sockets
and replaces them with /dev/null.

The error condition can also be reproduced by starting udevd with this
command-line:
  udevd --daemon <&- >&- 2>&-

udevd.c

diff --git a/udevd.c b/udevd.c
index 23f5fd6980183a2cf56481b3ee903914f6b85512..961ceb587ac8e974f564ca08e67680a72fa58e84 100644 (file)
--- a/udevd.c
+++ b/udevd.c
@@ -989,6 +989,19 @@ int main(int argc, char *argv[], char *envp[])
                goto exit;
        }
 
+       /* make sure std{in,out,err} fd's are in a sane state */
+       fd = open("/dev/null", O_RDWR);
+       if (fd < 0) {
+               fprintf(stderr, "cannot open /dev/null\n");
+               err("cannot open /dev/null");
+       }
+       if (fd > STDIN_FILENO)
+               dup2(fd, STDIN_FILENO);
+       if (write(STDOUT_FILENO, 0, 0) < 0)
+               dup2(fd, STDOUT_FILENO);
+       if (write(STDERR_FILENO, 0, 0) < 0)
+               dup2(fd, STDERR_FILENO);
+
        /* init sockets to receive events */
        if (init_udevd_socket() < 0) {
                if (errno == EADDRINUSE) {
@@ -1064,17 +1077,12 @@ int main(int argc, char *argv[], char *envp[])
                }
        }
 
-       /* redirect std fd's */
-       fd = open("/dev/null", O_RDWR);
-       if (fd >= 0) {
-               dup2(fd, STDIN_FILENO);
-               if (!verbose)
-                       dup2(fd, STDOUT_FILENO);
-               dup2(fd, STDERR_FILENO);
-               if (fd > STDERR_FILENO)
-                       close(fd);
-       } else
-               err("error opening /dev/null: %s", strerror(errno));
+       /* redirect std{out,err} fd's */
+       if (!verbose)
+               dup2(fd, STDOUT_FILENO);
+       dup2(fd, STDERR_FILENO);
+       if (fd > STDERR_FILENO)
+               close(fd);
 
        /* set scheduling priority for the daemon */
        setpriority(PRIO_PROCESS, 0, UDEVD_PRIORITY);