diff --git a/process.c b/process.c index 75cb2c3..bab2fa7 100644 --- a/process.c +++ b/process.c @@ -58,8 +58,10 @@ struct child_process * childproc_alloc(char *const argv[], const char *pwd) int childproc_free(struct child_process *child) { /* child already running, return error */ - if (child->pid != 0) + if (child->pid != 0) { + log_print(LOG_ERROR, "childproc_free(): process [pid:%d] already running", child->pid); return -1; + } int i; for (i = 0; child->argv[i] != NULL; i++) @@ -76,12 +78,12 @@ pid_t childproc_fork(struct child_process *child, void (*exit_cb)(struct child_p { struct stat stat_buf; if (stat(child->argv[0], &stat_buf) != 0) { - log_print(LOG_ERROR, "spawn_child(): stat()"); + log_print(LOG_ERROR, "childproc_fork(): stat()"); return -1; /* not a regular file, or not executable */ } else if (!S_ISREG(stat_buf.st_mode) || !(stat_buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) { - log_print(LOG_ERROR, "spawn_child(): stat()"); + log_print(LOG_ERROR, "childproc_fork(): stat()"); return -1; } @@ -100,7 +102,7 @@ pid_t childproc_fork(struct child_process *child, void (*exit_cb)(struct child_p int child_pipes[3][2]; if (child->fd[STDIN_FILENO] == -1) { if (pipe(child_pipes[STDIN_FILENO]) < 0) { - log_print(LOG_ERROR, "spawn_child(): pipe(STDIN_FILENO)"); + log_print(LOG_ERROR, "childproc_fork(): pipe(STDIN_FILENO)"); return -1; } @@ -111,7 +113,7 @@ pid_t childproc_fork(struct child_process *child, void (*exit_cb)(struct child_p if (child->fd[STDOUT_FILENO] == -1) { if (pipe(child_pipes[STDOUT_FILENO]) < 0) { - log_print(LOG_ERROR, "spawn_child(): pipe(STDOUT_FILENO)"); + log_print(LOG_ERROR, "childproc_fork(): pipe(STDOUT_FILENO)"); return -1; } @@ -122,7 +124,7 @@ pid_t childproc_fork(struct child_process *child, void (*exit_cb)(struct child_p if (child->fd[STDERR_FILENO] == -1) { if (pipe(child_pipes[STDERR_FILENO]) < 0) { - log_print(LOG_ERROR, "spawn_child(): pipe(STDERR_FILENO)"); + log_print(LOG_ERROR, "childproc_fork(): pipe(STDERR_FILENO)"); return -1; } @@ -169,7 +171,7 @@ pid_t childproc_fork(struct child_process *child, void (*exit_cb)(struct child_p exit(1); } else if (child->pid < 0) { /* fork error */ - log_print(LOG_ERROR, "spawn_child(): fork()"); + log_print(LOG_ERROR, "childproc_fork(): fork()"); return -1; } else { /* parent */ @@ -199,7 +201,7 @@ void childproc_cleanup(void) int status = 0; int ret = waitpid(child->pid, &status, WNOHANG); if (ret == -1) { - log_print(LOG_WARN, "sigchld_handler(): waitpid(%d)", child->pid); + log_print(LOG_WARN, "childproc_cleanup(): waitpid(%d)", child->pid); continue; } else if (ret != 0 && WIFEXITED(status)) { diff --git a/torrentfile.c b/torrentfile.c index 3875a92..ca61d8e 100644 --- a/torrentfile.c +++ b/torrentfile.c @@ -80,10 +80,12 @@ int destroy_torrent(struct torrent_file *torrent) /* remove us from list */ list_del(&torrent->list); - /* check if we're seeding, destroy after sigchld */ + /* check if we're still seeding, and deferr the destroy after sigchld */ if (torrent->child != NULL) { torrent->destroy = 1; - kill(SIGTERM, torrent->child->pid); + if (kill(SIGTERM, torrent->child->pid) < 0) + log_print(LOG_WARN, "failed to kill ctorrent [pid:%d]", torrent->child->pid); + return 0; } @@ -102,6 +104,7 @@ static void child_exit(struct child_process *child, int exit_code, void *privdat close(child->fd[STDOUT_FILENO]); close(child->fd[STDERR_FILENO]); + /* destroy was deferred until our child died, so do it now */ if (torrent->destroy) destroy_torrent(torrent); } @@ -132,6 +135,9 @@ int seed_torrent(struct torrent_file *torrent) char *const args[] = { (char *)ctorrent_bin, "-S", (char *)statserv, "-f", buf, NULL }; torrent->child = childproc_alloc(args, searchpath); + if (torrent->child == NULL) + return -1; + if (childproc_fork(torrent->child, child_exit, torrent) < 0) { log_print(LOG_ERROR, "spawn_child(%s)", args[0]); childproc_free(torrent->child);