Ver código fonte

daemonize: instead of just closing STD*_FILENO replace them by /dev/null

When there are not valid standard file descriptors then strange things
can happen. When new file descriptors are opened, they will take the
place of the former standard file descriptors and when e.g. somebody
calls printf() they will write to some file descriptor that is not
prepared for it. This would already happen during PLOG_MSG() in
gamemoded.

Actually this also causes a SIGABRT when calling gamemoded like this:

```bash
gamemoded -d
```

This is due to a bug [1] in systemd that causes an assertion to be
triggered. This shows that file descriptor zero is in this case being
replaced by a UNIX domain socket representing the connection to the
D-Bus session bus.

Therefore instead of just closing the standard file descriptors, replace
them by appropriate file descriptors refering to /dev/null.

[1]: https://github.com/systemd/systemd/issues/8080
Matthias Gerstner 6 anos atrás
pai
commit
17241deccb
1 arquivos alterados com 10 adições e 3 exclusões
  1. 10 3
      daemon/daemonize.c

+ 10 - 3
daemon/daemonize.c

@@ -31,6 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #include "daemonize.h"
 #include "logging.h"
 
+#include <fcntl.h>
 #include <stdlib.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -68,7 +69,13 @@ void daemonize(const char *name)
 	if (chdir("/") < 0) {
 		FATAL_ERRORNO("Failed to change to root directory\n");
 	}
-	close(STDIN_FILENO);
-	close(STDOUT_FILENO);
-	close(STDERR_FILENO);
+
+	/* replace standard file descriptors by /dev/null */
+	int devnull_r = open("/dev/null", O_RDONLY);
+	int devnull_w = open("/dev/null", O_WRONLY);
+	dup2(devnull_r, STDIN_FILENO);
+	dup2(devnull_w, STDOUT_FILENO);
+	dup2(devnull_w, STDERR_FILENO);
+	close(devnull_r);
+	close(devnull_w);
 }