diff options
Diffstat (limited to 'src/c_fork.c')
-rw-r--r-- | src/c_fork.c | 100 |
1 files changed, 72 insertions, 28 deletions
diff --git a/src/c_fork.c b/src/c_fork.c index 7709bd6..b74d8bc 100644 --- a/src/c_fork.c +++ b/src/c_fork.c @@ -39,12 +39,17 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * bsdsetsid: src/c_fork.c - * Thu Nov 26 22:12:40 CET 2020 + * Thu Nov 26 23:40:15 CET 2020 * Joe * * The program's main fork(2). */ +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/time.h> +#include <sys/resource.h> + #include <errno.h> #include <stdlib.h> #include <stdio.h> @@ -52,54 +57,93 @@ #include <unistd.h> #include "c_bsdsetsid.h" +#include "c_fork.h" -void -c_fork +static void +c_fork_child (const char* argv[], const char* envp[], bool_t wopt) { - int sets_ret; - int exec_ret; - pid_t pid; + union ret_u u; - pid = fork(); - if (pid == -1) { + u.pid = setsid(); + if (u.pid == -1) { dprintf( STDERR_FILENO, - "%s: fork: %s\n", + "%s: setsid: %s\n", C_PROGNAME, strerror(errno) ); exit(EXIT_FAILURE); } - else if (pid == 0) { - sets_ret = setsid(); - if (sets_ret == -1) { - dprintf( - STDERR_FILENO, - "%s: setsid: %s\n", - C_PROGNAME, - strerror(errno) - ); - exit(EXIT_FAILURE); - } - exec_ret = execve( - argv[1 + wopt], - (char* const*)argv + (1 + wopt), - (char* const*)envp + u.ret = execve( + argv[1 + wopt], + (char* const*)argv + (1 + wopt), + (char* const*)envp + ); + if (u.ret == -1) { + dprintf( + STDERR_FILENO, + "%s: execve: %s\n", + C_PROGNAME, + strerror(errno) ); - if (exec_ret == -1) { + exit(EXIT_FAILURE); + } +} + +static void +c_fork_parent +(bool_t wopt, + pid_t pid) +{ + union ret_u u; + int status; + + if (wopt == TRUE) { + u.pid = wait4(pid, &status, 0, NULL); + if (u.pid < 0) { dprintf( STDERR_FILENO, - "%s: execve: %s\n", + "%s: wait4: %s\n", C_PROGNAME, strerror(errno) ); - exit(EXIT_FAILURE); } + exit(WEXITSTATUS(status)); + } + exit(EXIT_SUCCESS); +} + +static void +c_fork_error(void) +{ + dprintf( + STDERR_FILENO, + "%s: fork: %s\n", + C_PROGNAME, + strerror(errno) + ); + exit(EXIT_FAILURE); +} + +void +c_fork +(const char* argv[], + const char* envp[], + bool_t wopt) +{ + pid_t pid; + + pid = fork(); + if (pid == -1) { + c_fork_error(); + } + else if (pid == 0) { + c_fork_child(argv, envp, wopt); } else { - exit(EXIT_SUCCESS); + c_fork_parent(wopt, pid); } } |