From 4290f79748cb6b333ecf82808f53e557b8184728 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 18 Nov 2014 09:10:48 +0100 Subject: [PATCH] spawn: allow spawnv stdout/stderr redirection to logs --- src/config.c | 2 +- src/dvr/dvr_rec.c | 2 +- src/main.c | 3 +-- src/spawn.c | 38 ++++++++++++++++++++++++++++++++------ src/spawn.h | 4 +--- 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/config.c b/src/config.c index 914a4907..ea1e93f5 100644 --- a/src/config.c +++ b/src/config.c @@ -1147,7 +1147,7 @@ dobackup(const char *oldver) root, oldver); tvhinfo("config", "backup: running, output file %s", outfile); - spawnv(argv[0], (void *)argv); + spawnv(argv[0], (void *)argv, 1, 1); while ((code = spawn_reap(errtxt, sizeof(errtxt))) == -EAGAIN) usleep(20000); diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index 39be2d24..d80c0cd8 100644 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -679,7 +679,7 @@ dvr_spawn_postproc(dvr_entry_t *de, const char *dvr_postproc) args[i] = s; } - spawnv(args[0], (void *)args); + spawnv(args[0], (void *)args, 1, 1); htsstr_argsplit_free(args); } diff --git a/src/main.c b/src/main.c index b2eac04b..3420fcf9 100644 --- a/src/main.c +++ b/src/main.c @@ -787,14 +787,13 @@ main(int argc, char **argv) /* Initialise configuration */ uuid_init(); idnode_init(); + spawn_init(); config_init(opt_config, opt_nobackup == 0); /** * Initialize subsystems */ - spawn_init(); - dbus_server_init(opt_dbus, opt_dbus_session); intlconv_init(); diff --git a/src/spawn.c b/src/spawn.c index a686ab55..4cfb48a9 100644 --- a/src/spawn.c +++ b/src/spawn.c @@ -60,6 +60,8 @@ typedef struct spawn { const char *name; } spawn_t; +static void spawn_reaper(void); + /* * */ @@ -274,7 +276,7 @@ spawn_reap(char *stxt, size_t stxtlen) /** * The reaper is called once a second to finish of any pending spawns */ -void +static void spawn_reaper(void) { while (spawn_reap(NULL, 0) != -EAGAIN) ; @@ -343,12 +345,15 @@ spawn_and_give_stdout(const char *prog, char *argv[], int *rd, int redir_stderr) } close(0); + close(1); close(2); - close(fd[0]); - dup2(fd[1], 1); - close(fd[1]); + dup2(f, 0); + dup2(fd[1], 1); dup2(redir_stderr ? spawn_pipe_error.wr : f, 2); + + close(fd[0]); + close(fd[1]); close(f); spawn_info("Executing \"%s\"\n", prog); @@ -379,9 +384,9 @@ spawn_and_give_stdout(const char *prog, char *argv[], int *rd, int redir_stderr) * The function will return the size of the buffer */ int -spawnv(const char *prog, char *argv[]) +spawnv(const char *prog, char *argv[], int redir_stdout, int redir_stderr) { - pid_t p; + pid_t p, f, maxfd; char bin[256]; const char *local_argv[2] = { NULL, NULL }; @@ -393,6 +398,8 @@ spawnv(const char *prog, char *argv[]) if(!argv) argv = (void *)local_argv; if (!argv[0]) argv[0] = (char*)prog; + maxfd = sysconf(_SC_OPEN_MAX); + pthread_mutex_lock(&fork_lock); p = fork(); @@ -405,9 +412,28 @@ spawnv(const char *prog, char *argv[]) } if(p == 0) { + f = open("/dev/null", O_RDWR); + if(f == -1) { + spawn_error("pid %d cannot open /dev/null for redirect %s -- %s", + getpid(), prog, strerror(errno)); + exit(1); + } + close(0); + close(1); close(2); + + dup2(f, 0); + dup2(redir_stdout ? spawn_pipe_info.wr : f, 1); + dup2(redir_stderr ? spawn_pipe_error.wr : f, 2); + + close(f); + spawn_info("Executing \"%s\"\n", prog); + + for (f = 3; f < maxfd; f++) + close(f); + execve(prog, argv, environ); spawn_error("pid %d cannot execute %s -- %s\n", getpid(), prog, strerror(errno)); diff --git a/src/spawn.h b/src/spawn.h index 882d4c69..81b1951b 100644 --- a/src/spawn.h +++ b/src/spawn.h @@ -27,12 +27,10 @@ int find_exec ( const char *name, char *out, size_t len ); int spawn_and_give_stdout(const char *prog, char *argv[], int *rd, int redir_stderr); -int spawnv(const char *prog, char *argv[]); +int spawnv(const char *prog, char *argv[], int redir_stdout, int redir_stderr); int spawn_reap(char *stxt, size_t stxtlen); -void spawn_reaper(void); - void spawn_init(void); void spawn_done(void);