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)
|
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);
|
ret = krb5_init_context(&context);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@@ -87,7 +87,7 @@ main(int argc, char **argv)
|
|||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
#endif
|
#endif
|
||||||
if (detach_from_console && !launchd_flag && daemon_child == -1)
|
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);
|
rk_pidfile(NULL);
|
||||||
|
|
||||||
if (launchd_flag) {
|
if (launchd_flag) {
|
||||||
|
@@ -189,7 +189,7 @@ configure(krb5_context context, int argc, char **argv, int *optidx)
|
|||||||
"detach", NULL);
|
"detach", NULL);
|
||||||
|
|
||||||
if (detach_from_console && daemon_child == -1)
|
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;
|
char **files;
|
||||||
|
@@ -798,7 +798,7 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (detach_from_console > 0 && daemon_child == -1)
|
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) {
|
if (config_file == NULL) {
|
||||||
aret = asprintf(&config_file, "%s/kdc.conf", hdb_db_dir(context));
|
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)
|
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);
|
rk_pidfile(NULL);
|
||||||
|
|
||||||
ret = krb5_init_context(&context);
|
ret = krb5_init_context(&context);
|
||||||
|
@@ -719,7 +719,7 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (detach_from_console && daemon_child == -1)
|
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);
|
rk_pidfile(NULL);
|
||||||
|
|
||||||
ret = krb5_init_context(&context);
|
ret = krb5_init_context(&context);
|
||||||
|
@@ -44,54 +44,57 @@
|
|||||||
|
|
||||||
static int pipefds[2] = {-1, -1};
|
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)
|
roken_detach_prep(int argc, char **argv, char *special_arg)
|
||||||
{
|
{
|
||||||
pid_t child;
|
|
||||||
char buf[1];
|
|
||||||
ssize_t bytes;
|
ssize_t bytes;
|
||||||
|
size_t i;
|
||||||
|
pid_t child;
|
||||||
|
char **new_argv;
|
||||||
|
char buf[1];
|
||||||
|
char *fildes;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
pipefds[0] = -1;
|
pipefds[0] = -1;
|
||||||
pipefds[1] = -1;
|
pipefds[1] = -1;
|
||||||
|
|
||||||
#ifdef WIN32
|
#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)");
|
err(1, "failed to setup to detach daemon (_pipe failed)");
|
||||||
#else
|
#else
|
||||||
if (pipe(pipefds) == -1)
|
if (pipe(pipefds) == -1)
|
||||||
err(1, "failed to setup to detach daemon (pipe failed)");
|
err(1, "failed to setup to detach daemon (pipe failed)");
|
||||||
#endif
|
#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
|
#ifndef WIN32
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
child = fork();
|
child = fork();
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
intptr_t child_handle;
|
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();
|
_flushall();
|
||||||
child_handle = spawnvp(_P_NOWAIT, argv[0], new_argv);
|
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);
|
(void) dup2(fd, STDIN_FILENO);
|
||||||
if (fd > STDERR_FILENO)
|
if (fd > STDERR_FILENO)
|
||||||
(void) close(fd);
|
(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
|
#endif
|
||||||
|
|
||||||
|
/* Parent */
|
||||||
(void) close(pipefds[1]);
|
(void) close(pipefds[1]);
|
||||||
pipefds[1] = -1;
|
pipefds[1] = -1;
|
||||||
do {
|
do {
|
||||||
@@ -149,6 +157,8 @@ roken_detach_prep(int argc, char **argv, char *special_arg)
|
|||||||
"daemon child preparation failed (child exited)");
|
"daemon child preparation failed (child exited)");
|
||||||
}
|
}
|
||||||
_exit(0);
|
_exit(0);
|
||||||
|
/* NOTREACHED */
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#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_LIB_FUNCTION size_t ROKEN_LIB_CALL
|
||||||
roken_vmconcat (char **, size_t, va_list);
|
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 void ROKEN_LIB_CALL roken_detach_finish(const char *, int);
|
||||||
|
|
||||||
ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL
|
ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL
|
||||||
|
@@ -53,11 +53,13 @@ int main(int argc, char **argv)
|
|||||||
char *ends;
|
char *ends;
|
||||||
long n;
|
long n;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
|
pid_t parent = getpid();
|
||||||
|
pid_t child;
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc == 2 && strcmp(argv[1], "--reexec"))
|
||||||
if (argc != 3)
|
errx(1, "Usage: test-detach [--reexec] [--daemon-child FD]");
|
||||||
errx(1, "Usage: test-detach [--daemon-child fd]");
|
if (argc == 3 || argc == 4) {
|
||||||
fprintf(stderr, "Child started (argv[1] = %s, argv[2] = %s)!\n", argv[1], argv[2]);
|
parent = getppid();
|
||||||
errno = 0;
|
errno = 0;
|
||||||
n = strtol(argv[2], &ends, 10);
|
n = strtol(argv[2], &ends, 10);
|
||||||
fd = n;
|
fd = n;
|
||||||
@@ -66,11 +68,19 @@ int main(int argc, char **argv)
|
|||||||
if (n < 0 || ends == NULL || *ends != '\0' || n != fd)
|
if (n < 0 || ends == NULL || *ends != '\0' || n != fd)
|
||||||
errx(1, "Usage: test-detach [--daemon-child fd]");
|
errx(1, "Usage: test-detach [--daemon-child fd]");
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Parent started as %ld\n", (long)getpid());
|
if (argc == 2)
|
||||||
roken_detach_prep(argc, argv, "--daemon-child");
|
/* 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);
|
roken_detach_finish(NULL, fd);
|
||||||
|
if (child != getpid())
|
||||||
|
errx(1, "detach finish failed");
|
||||||
/*
|
/*
|
||||||
* These printfs will not appear: stderr will have been replaced
|
* These printfs will not appear: stderr will have been replaced
|
||||||
* with /dev/null.
|
* with /dev/null.
|
||||||
|
Reference in New Issue
Block a user