roken_detach_prep() should return fd

This commit is contained in:
Nicolas Williams
2019-08-14 17:37:31 -05:00
parent 5859bc3bdf
commit 1ae941af9b
9 changed files with 62 additions and 42 deletions

View File

@@ -123,7 +123,7 @@ main(int argc, char **argv)
}
if (detach_from_console > 0 && daemon_child == -1)
roken_detach_prep(argc, argv, "--daemon-child");
daemon_child = roken_detach_prep(argc, argv, "--daemon-child");
ret = krb5_init_context(&context);
if (ret)

View File

@@ -87,7 +87,7 @@ main(int argc, char **argv)
signal(SIGPIPE, SIG_IGN);
#endif
if (detach_from_console && !launchd_flag && daemon_child == -1)
roken_detach_prep(argc, argv, "--daemon-child");
daemon_child = roken_detach_prep(argc, argv, "--daemon-child");
rk_pidfile(NULL);
if (launchd_flag) {

View File

@@ -189,7 +189,7 @@ configure(krb5_context context, int argc, char **argv, int *optidx)
"detach", NULL);
if (detach_from_console && daemon_child == -1)
roken_detach_prep(argc, argv, "--daemon-child");
daemon_child = roken_detach_prep(argc, argv, "--daemon-child");
{
char **files;

View File

@@ -798,7 +798,7 @@ main(int argc, char **argv)
}
if (detach_from_console > 0 && daemon_child == -1)
roken_detach_prep(argc, argv, "--daemon-child");
daemon_child = roken_detach_prep(argc, argv, "--daemon-child");
if (config_file == NULL) {
aret = asprintf(&config_file, "%s/kdc.conf", hdb_db_dir(context));

View File

@@ -1152,7 +1152,7 @@ main(int argc, char **argv)
}
if (detach_from_console && daemon_child == -1)
roken_detach_prep(argc, argv, "--daemon-child");
daemon_child = roken_detach_prep(argc, argv, "--daemon-child");
rk_pidfile(NULL);
ret = krb5_init_context(&context);

View File

@@ -719,7 +719,7 @@ main(int argc, char **argv)
}
if (detach_from_console && daemon_child == -1)
roken_detach_prep(argc, argv, "--daemon-child");
daemon_child = roken_detach_prep(argc, argv, "--daemon-child");
rk_pidfile(NULL);
ret = krb5_init_context(&context);

View File

@@ -44,45 +44,41 @@
static int pipefds[2] = {-1, -1};
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
roken_detach_prep(int argc, char **argv, char *special_arg)
{
pid_t child;
char buf[1];
ssize_t bytes;
size_t i;
pid_t child;
char **new_argv;
char buf[1];
char *fildes;
int status;
pipefds[0] = -1;
pipefds[1] = -1;
#ifdef WIN32
if (_pipe(pipefds, 4, O_BINARY) == -1)
if (_pipe(pipefds, 4, _O_NOINHERIT | O_BINARY) == -1)
err(1, "failed to setup to detach daemon (_pipe failed)");
#else
if (pipe(pipefds) == -1)
err(1, "failed to setup to detach daemon (pipe failed)");
#endif
#ifndef WIN32
fflush(stdout);
child = fork();
#else
{
intptr_t child_handle;
int write_side;
size_t i;
char *fildes;
char **new_argv;
new_argv = calloc(argc + 2, sizeof(*new_argv));
new_argv = calloc(argc + 3, sizeof(*new_argv));
if (new_argv == NULL)
err(1, "Out of memory");
write_side = _dup(pipefds[1]); /* The new fd will be inherited */
if (write_side == -1)
#ifdef WIN32
pipefds[1] = _dup(pipefds[1]); /* The new fd will be inherited */
if (pipefds[1] == -1)
err(1, "Out of memory");
#else
fcntl(pipefds[1], F_SETFD, fcntl(pipefds[1], F_GETFD & ~(O_CLOEXEC)));
#endif
if (asprintf(&fildes, "%d", write_side) == -1 ||
if (asprintf(&fildes, "%d", pipefds[1]) == -1 ||
fildes == NULL)
err(1, "failed to setup to detach daemon (_dup failed)");
@@ -90,9 +86,16 @@ roken_detach_prep(int argc, char **argv, char *special_arg)
new_argv[1] = special_arg;
new_argv[2] = fildes;
for (i = 1; argv[i] != NULL; i++)
new_argv[i + 1] = argv[i];
new_argv[i + 2] = argv[i];
new_argv[argc + 2] = NULL;
#ifndef WIN32
fflush(stdout);
child = fork();
#else
{
intptr_t child_handle;
_flushall();
child_handle = spawnvp(_P_NOWAIT, argv[0], new_argv);
if (child_handle == -1)
@@ -120,10 +123,15 @@ roken_detach_prep(int argc, char **argv, char *special_arg)
(void) dup2(fd, STDIN_FILENO);
if (fd > STDERR_FILENO)
(void) close(fd);
return;
if (getenv("ROKEN_DETACH_USE_EXEC")) {
(void) execvp(argv[0], new_argv);
err(1, "failed to self-re-exec");
}
return pipefds[1];
}
#endif
/* Parent */
(void) close(pipefds[1]);
pipefds[1] = -1;
do {
@@ -149,6 +157,8 @@ roken_detach_prep(int argc, char **argv, char *special_arg)
"daemon child preparation failed (child exited)");
}
_exit(0);
/* NOTREACHED */
return -1;
}
#ifdef WIN32

View File

@@ -836,7 +836,7 @@ ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL roken_vconcat (char *, size_t, va_list);
ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL
roken_vmconcat (char **, size_t, va_list);
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL roken_detach_prep(int, char **, char *);
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL roken_detach_prep(int, char **, char *);
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL roken_detach_finish(const char *, int);
ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL

View File

@@ -53,11 +53,13 @@ int main(int argc, char **argv)
char *ends;
long n;
int fd = -1;
pid_t parent = getpid();
pid_t child;
if (argc > 1) {
if (argc != 3)
errx(1, "Usage: test-detach [--daemon-child fd]");
fprintf(stderr, "Child started (argv[1] = %s, argv[2] = %s)!\n", argv[1], argv[2]);
if (argc == 2 && strcmp(argv[1], "--reexec"))
errx(1, "Usage: test-detach [--reexec] [--daemon-child FD]");
if (argc == 3 || argc == 4) {
parent = getppid();
errno = 0;
n = strtol(argv[2], &ends, 10);
fd = n;
@@ -66,11 +68,19 @@ int main(int argc, char **argv)
if (n < 0 || ends == NULL || *ends != '\0' || n != fd)
errx(1, "Usage: test-detach [--daemon-child fd]");
} else {
fprintf(stderr, "Parent started as %ld\n", (long)getpid());
roken_detach_prep(argc, argv, "--daemon-child");
if (argc == 2)
/* Make sure we re-exec on the child-side of fork() (not WIN32) */
putenv("ROKEN_DETACH_USE_EXEC=1");
fd = roken_detach_prep(argc, argv, "--daemon-child");
if (fd == -1)
errx(1, "bad");
}
fprintf(stderr, "Now should be the child: %ld\n", (long)getpid());
if (parent == getpid())
errx(1, "detach prep failed");
child = getpid();
roken_detach_finish(NULL, fd);
if (child != getpid())
errx(1, "detach finish failed");
/*
* These printfs will not appear: stderr will have been replaced
* with /dev/null.