|
Szabolcs Nagy |
cfa23c |
// commit: 19e35c500bd2b5e6146e42705ab9b69c155a2006 2011-02-17
|
|
Szabolcs Nagy |
cfa23c |
// commit: 187fe29d5b89644b68cade75a34257a1c32a75f6 2011-02-17
|
|
Szabolcs Nagy |
cfa23c |
// non-standard musl specific behaviour
|
|
Szabolcs Nagy |
cfa23c |
// daemon should not fork in case of failure of chdir or open, but
|
|
Szabolcs Nagy |
cfa23c |
// since setsid and fork may still fail after fork this behaviour
|
|
Szabolcs Nagy |
cfa23c |
// is not very useful
|
|
Szabolcs Nagy |
cfa23c |
#define _BSD_SOURCE 1
|
|
Szabolcs Nagy |
cfa23c |
#include <string.h>
|
|
Szabolcs Nagy |
cfa23c |
#include <errno.h>
|
|
Szabolcs Nagy |
cfa23c |
#include <sys/wait.h>
|
|
Szabolcs Nagy |
cfa23c |
#include <fcntl.h>
|
|
Szabolcs Nagy |
cfa23c |
#include <unistd.h>
|
|
Szabolcs Nagy |
cfa23c |
#include "test.h"
|
|
Szabolcs Nagy |
cfa23c |
|
|
Szabolcs Nagy |
cfa23c |
int daemon(int, int);
|
|
Szabolcs Nagy |
cfa23c |
|
|
Szabolcs Nagy |
cfa23c |
int main(void)
|
|
Szabolcs Nagy |
cfa23c |
{
|
|
Szabolcs Nagy |
cfa23c |
int r, pid, fd[2], fdout, s;
|
|
Szabolcs Nagy |
cfa23c |
char c;
|
|
Szabolcs Nagy |
cfa23c |
|
|
Szabolcs Nagy |
cfa23c |
r = pipe(fd);
|
|
Szabolcs Nagy |
cfa23c |
if (r == -1) {
|
|
Szabolcs Nagy |
cfa23c |
t_error("pipe failed: %s\n", strerror(errno));
|
|
Szabolcs Nagy |
cfa23c |
return 1;
|
|
Szabolcs Nagy |
cfa23c |
}
|
|
Szabolcs Nagy |
cfa23c |
fdout = dup(1);
|
|
Szabolcs Nagy |
cfa23c |
if (fdout == -1) {
|
|
Szabolcs Nagy |
cfa23c |
t_error("dup(1) failed: %s\n", strerror(errno));
|
|
Szabolcs Nagy |
cfa23c |
return 1;
|
|
Szabolcs Nagy |
cfa23c |
}
|
|
Szabolcs Nagy |
cfa23c |
r = fork();
|
|
Szabolcs Nagy |
cfa23c |
if (r == -1) {
|
|
Szabolcs Nagy |
cfa23c |
t_error("fork failed: %s\n", strerror(errno));
|
|
Szabolcs Nagy |
cfa23c |
return 1;
|
|
Szabolcs Nagy |
cfa23c |
}
|
|
Szabolcs Nagy |
cfa23c |
|
|
Szabolcs Nagy |
cfa23c |
if (r == 0) {
|
|
Szabolcs Nagy |
cfa23c |
/* exhausting all fds makes open("/dev/null") fail in daemon */
|
|
Szabolcs Nagy |
cfa23c |
t_fdfill();
|
|
Szabolcs Nagy |
cfa23c |
pid = getpid();
|
|
Szabolcs Nagy |
cfa23c |
errno = 0;
|
|
Szabolcs Nagy |
cfa23c |
r = daemon(0, 0);
|
|
Szabolcs Nagy |
cfa23c |
if (dup2(fdout,1) == -1) {
|
|
Szabolcs Nagy |
cfa23c |
write(fdout, "ERROR:\n", 7);
|
|
Szabolcs Nagy |
cfa23c |
t_error("failed to dup pipe fd for communicating results: %s\n", strerror(errno));
|
|
Szabolcs Nagy |
cfa23c |
}
|
|
Szabolcs Nagy |
cfa23c |
if (r != -1)
|
|
Szabolcs Nagy |
cfa23c |
t_error("daemon should have failed\n");
|
|
Szabolcs Nagy |
cfa23c |
if (errno != EMFILE)
|
|
Szabolcs Nagy |
cfa23c |
t_error("daemon should have failed with %d [EMFILE] got %d [%s]\n", EMFILE, errno, strerror(errno));
|
|
Szabolcs Nagy |
cfa23c |
if (getpid() != pid || getppid() == 1)
|
|
Szabolcs Nagy |
cfa23c |
t_error("daemon forked despite failure: ppid is %d, pid is %d, old pid is %d\n",
|
|
Szabolcs Nagy |
cfa23c |
getppid(), getpid(), pid);
|
|
Szabolcs Nagy |
cfa23c |
if (write(fd[1], "1" + !t_status, 1) != 1)
|
|
Szabolcs Nagy |
cfa23c |
t_error("write failed: %s\n", strerror(errno));
|
|
Szabolcs Nagy |
cfa23c |
return t_status;
|
|
Szabolcs Nagy |
cfa23c |
}
|
|
Szabolcs Nagy |
cfa23c |
close(fd[1]);
|
|
Szabolcs Nagy |
cfa23c |
if (waitpid(r, &s, 0) != r)
|
|
Szabolcs Nagy |
cfa23c |
t_error("waitpid failed: %s\n", strerror(errno));
|
|
Szabolcs Nagy |
cfa23c |
else if (!WIFEXITED(s))
|
|
Szabolcs Nagy |
cfa23c |
t_error("child exited abnormally (signal %d)\n", WIFSIGNALED(s) ? WTERMSIG(s) : 0);
|
|
Szabolcs Nagy |
cfa23c |
else if (WEXITSTATUS(s))
|
|
Szabolcs Nagy |
cfa23c |
t_error("child exited with %d\n", WEXITSTATUS(s));
|
|
Szabolcs Nagy |
cfa23c |
r = read(fd[0], &c, 1);
|
|
Szabolcs Nagy |
cfa23c |
if (r == -1)
|
|
Szabolcs Nagy |
cfa23c |
t_error("read failed: %s\n", strerror(errno));
|
|
Szabolcs Nagy |
cfa23c |
else if (r == 0)
|
|
Szabolcs Nagy |
cfa23c |
t_error("read failed: child did not send its exit status\n");
|
|
Szabolcs Nagy |
cfa23c |
else if (c != 0)
|
|
Szabolcs Nagy |
cfa23c |
t_error("child failed\n");
|
|
Szabolcs Nagy |
cfa23c |
|
|
Szabolcs Nagy |
cfa23c |
return t_status;
|
|
Szabolcs Nagy |
cfa23c |
}
|