Both sessiond and consumerd support the option "-d" to run as daemon. In
some specific cases, e.g. when launched from dpkg installation scripts,
file descriptors 3, 4, 5 are left open and don't seem to have O_CLOEXEC
flag set, so the install script hangs because the sessiond still holds a
reference to them. daemon(3) only closes standard FD 0, 1, 2.
Fix this issue by closing all file descriptors after calling daemon(3).
Note: we make sure no file descriptor is opened before calling daemon(3)
by moving the init_thread_quit_pipe() call after the FD close.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
/* Daemonize */
if (opt_daemon) {
+ int i;
+
+ /*
+ * fork
+ * child: setsid, close FD 0, 1, 2, chdir /
+ * parent: exit (if fork is successful)
+ */
ret = daemon(0, 0);
if (ret < 0) {
- perror("daemon");
+ PERROR("daemon");
goto error;
}
+ /*
+ * We are in the child. Make sure all other file
+ * descriptors are closed, in case we are called with
+ * more opened file descriptors than the standard ones.
+ */
+ for (i = 3; i < sysconf(_SC_OPEN_MAX); i++) {
+ (void) close(i);
+ }
}
if (strlen(command_sock_path) == 0) {
rcu_register_thread();
- /* Create thread quit pipe */
- if ((ret = init_thread_quit_pipe()) < 0) {
- goto error;
- }
-
setup_consumerd_path();
/* Parse arguments */
/* Daemonize */
if (opt_daemon) {
+ int i;
+
+ /*
+ * fork
+ * child: setsid, close FD 0, 1, 2, chdir /
+ * parent: exit (if fork is successful)
+ */
ret = daemon(0, 0);
if (ret < 0) {
PERROR("daemon");
goto error;
}
+ /*
+ * We are in the child. Make sure all other file
+ * descriptors are closed, in case we are called with
+ * more opened file descriptors than the standard ones.
+ */
+ for (i = 3; i < sysconf(_SC_OPEN_MAX); i++) {
+ (void) close(i);
+ }
+ }
+
+ /* Create thread quit pipe */
+ if ((ret = init_thread_quit_pipe()) < 0) {
+ goto error;
}
/* Check if daemon is UID = 0 */