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