1// commit: 19e35c500bd2b5e6146e42705ab9b69c155a2006 2011-02-17 2// commit: 187fe29d5b89644b68cade75a34257a1c32a75f6 2011-02-17 3// non-standard musl specific behaviour 4// daemon should not fork in case of failure of chdir or open, but 5// since setsid and fork may still fail after fork this behaviour 6// is not very useful 7#define _DEFAULT_SOURCE 1 8#define _BSD_SOURCE 1 9#include <string.h> 10#include <errno.h> 11#include <sys/wait.h> 12#include <fcntl.h> 13#include <unistd.h> 14#include "test.h" 15 16int daemon(int, int); 17 18int main(void) 19{ 20 int r, pid, fd[2], fdout, s; 21 char c; 22 23 r = pipe(fd); 24 if (r == -1) { 25 t_error("pipe failed: %s\n", strerror(errno)); 26 return 1; 27 } 28 fdout = dup(1); 29 if (fdout == -1) { 30 t_error("dup(1) failed: %s\n", strerror(errno)); 31 return 1; 32 } 33 r = fork(); 34 if (r == -1) { 35 t_error("fork failed: %s\n", strerror(errno)); 36 return 1; 37 } 38 39 if (r == 0) { 40 /* exhausting all fds makes open("/dev/null") fail in daemon */ 41 t_fdfill(); 42 pid = getpid(); 43 errno = 0; 44 r = daemon(0, 0); 45 if (dup2(fdout,1) == -1) { 46 write(fdout, "ERROR:\n", 7); 47 t_error("failed to dup pipe fd for communicating results: %s\n", strerror(errno)); 48 } 49 if (r != -1) 50 t_error("daemon should have failed\n"); 51 if (errno != EMFILE) 52 t_error("daemon should have failed with %d [EMFILE] got %d [%s]\n", EMFILE, errno, strerror(errno)); 53 if (getpid() != pid || getppid() == 1) 54 t_error("daemon forked despite failure: ppid is %d, pid is %d, old pid is %d\n", 55 getppid(), getpid(), pid); 56 if (write(fd[1], "1" + !t_status, 1) != 1) 57 t_error("write failed: %s\n", strerror(errno)); 58 return t_status; 59 } 60 close(fd[1]); 61 if (waitpid(r, &s, 0) != r) 62 t_error("waitpid failed: %s\n", strerror(errno)); 63 else if (!WIFEXITED(s)) 64 t_error("child exited abnormally (signal %d)\n", WIFSIGNALED(s) ? WTERMSIG(s) : 0); 65 else if (WEXITSTATUS(s)) 66 t_error("child exited with %d\n", WEXITSTATUS(s)); 67 r = read(fd[0], &c, 1); 68 if (r == -1) 69 t_error("read failed: %s\n", strerror(errno)); 70 else if (r == 0) 71 t_error("read failed: child did not send its exit status\n"); 72 else if (c != 0) 73 t_error("child failed\n"); 74 75 return t_status; 76} 77