roken_detach_prep() should return fd
This commit is contained in:
@@ -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)
|
||||
|
@@ -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) {
|
||||
|
@@ -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;
|
||||
|
@@ -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));
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -44,54 +44,57 @@
|
||||
|
||||
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
|
||||
|
||||
new_argv = calloc(argc + 3, sizeof(*new_argv));
|
||||
if (new_argv == NULL)
|
||||
err(1, "Out of memory");
|
||||
|
||||
#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", pipefds[1]) == -1 ||
|
||||
fildes == NULL)
|
||||
err(1, "failed to setup to detach daemon (_dup failed)");
|
||||
|
||||
new_argv[0] = argv[0];
|
||||
new_argv[1] = special_arg;
|
||||
new_argv[2] = fildes;
|
||||
for (i = 1; argv[i] != NULL; i++)
|
||||
new_argv[i + 2] = argv[i];
|
||||
new_argv[argc + 2] = NULL;
|
||||
|
||||
#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));
|
||||
if (new_argv == NULL)
|
||||
err(1, "Out of memory");
|
||||
|
||||
write_side = _dup(pipefds[1]); /* The new fd will be inherited */
|
||||
if (write_side == -1)
|
||||
err(1, "Out of memory");
|
||||
|
||||
if (asprintf(&fildes, "%d", write_side) == -1 ||
|
||||
fildes == NULL)
|
||||
err(1, "failed to setup to detach daemon (_dup failed)");
|
||||
|
||||
new_argv[0] = argv[0];
|
||||
new_argv[1] = special_arg;
|
||||
new_argv[2] = fildes;
|
||||
for (i = 1; argv[i] != NULL; i++)
|
||||
new_argv[i + 1] = argv[i];
|
||||
new_argv[argc + 2] = NULL;
|
||||
|
||||
_flushall();
|
||||
child_handle = spawnvp(_P_NOWAIT, argv[0], new_argv);
|
||||
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
Reference in New Issue
Block a user