Explorar o código

LibC: Add daemon(3) implementation to match behavior of Linux and BSDs

This helper that originally appeared in 4.4BSD helps to daemonize
a process by forking, setting itself as session leader, chdir to "/" and
closing stdin/stdout.
Andrew Kaster %!s(int64=3) %!d(string=hai) anos
pai
achega
b13846e688
Modificáronse 2 ficheiros con 34 adicións e 0 borrados
  1. 33 0
      Userland/Libraries/LibC/unistd.cpp
  2. 1 0
      Userland/Libraries/LibC/unistd.h

+ 33 - 0
Userland/Libraries/LibC/unistd.cpp

@@ -102,6 +102,39 @@ pid_t vfork()
     return fork();
     return fork();
 }
 }
 
 
+// Non-POSIX, but present in BSDs and Linux
+// https://man.openbsd.org/daemon.3
+int daemon(int nochdir, int noclose)
+{
+    pid_t pid = fork();
+    if (pid < 0)
+        return -1;
+
+    // exit parent, continue execution in child
+    if (pid > 0)
+        _exit(0);
+
+    pid = setsid();
+    if (pid < 0)
+        return -1;
+
+    if (nochdir == 0)
+        (void)chdir("/");
+
+    if (noclose == 0) {
+        // redirect stdout and stderr to /dev/null
+        int fd = open("/dev/null", O_WRONLY);
+        if (fd < 0)
+            return -1;
+        (void)close(STDOUT_FILENO);
+        (void)close(STDERR_FILENO);
+        (void)dup2(fd, STDOUT_FILENO);
+        (void)dup2(fd, STDERR_FILENO);
+        (void)close(fd);
+    }
+    return 0;
+}
+
 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/execv.html
 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/execv.html
 int execv(const char* path, char* const argv[])
 int execv(const char* path, char* const argv[])
 {
 {

+ 1 - 0
Userland/Libraries/LibC/unistd.h

@@ -39,6 +39,7 @@ int gettid(void);
 int getpagesize(void);
 int getpagesize(void);
 pid_t fork(void);
 pid_t fork(void);
 pid_t vfork(void);
 pid_t vfork(void);
+int daemon(int nochdir, int noclose);
 int execv(const char* path, char* const argv[]);
 int execv(const char* path, char* const argv[]);
 int execve(const char* filename, char* const argv[], char* const envp[]);
 int execve(const char* filename, char* const argv[], char* const envp[]);
 int execvpe(const char* filename, char* const argv[], char* const envp[]);
 int execvpe(const char* filename, char* const argv[], char* const envp[]);