• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 int daemon(int, int);
17 
main(void)18 int 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