diff --git a/Userland/Libraries/LibC/unistd.cpp b/Userland/Libraries/LibC/unistd.cpp index 5510e5487d..9e4d863e8f 100644 --- a/Userland/Libraries/LibC/unistd.cpp +++ b/Userland/Libraries/LibC/unistd.cpp @@ -102,6 +102,39 @@ pid_t vfork() 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 int execv(const char* path, char* const argv[]) { diff --git a/Userland/Libraries/LibC/unistd.h b/Userland/Libraries/LibC/unistd.h index 141ae5e517..24f6c48e08 100644 --- a/Userland/Libraries/LibC/unistd.h +++ b/Userland/Libraries/LibC/unistd.h @@ -39,6 +39,7 @@ int gettid(void); int getpagesize(void); pid_t fork(void); pid_t vfork(void); +int daemon(int nochdir, int noclose); int execv(const char* path, char* const argv[]); int execve(const char* filename, char* const argv[], char* const envp[]); int execvpe(const char* filename, char* const argv[], char* const envp[]);