From 2bea38d7fcc68653942c1f33f3aa1e7e90386acb Mon Sep 17 00:00:00 2001 From: Fabio Scotto di Santolo Date: Tue, 1 Jul 2025 16:33:16 +0200 Subject: [PATCH] Chapter 5 - Process Management --- chp5/atexit.c | 15 ++++++++++++ chp5/daemon.c | 43 ++++++++++++++++++++++++++++++++++ chp5/session.c | 9 ++++++++ chp5/system.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ chp5/wait.c | 31 +++++++++++++++++++++++++ 5 files changed, 161 insertions(+) create mode 100644 chp5/atexit.c create mode 100644 chp5/daemon.c create mode 100644 chp5/session.c create mode 100644 chp5/system.c create mode 100644 chp5/wait.c diff --git a/chp5/atexit.c b/chp5/atexit.c new file mode 100644 index 0000000..2b064c2 --- /dev/null +++ b/chp5/atexit.c @@ -0,0 +1,15 @@ +#include +#include + +void out(void) { + printf("atexit() succeeded!\n"); +} + + +int main(void) { + if (atexit(out)) { + fprintf(stderr, "atexit() failed\n"); + return 1; + } + return 0; +} diff --git a/chp5/daemon.c b/chp5/daemon.c new file mode 100644 index 0000000..57df951 --- /dev/null +++ b/chp5/daemon.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include +#include + +#define NR_OPEN 1048576 + +int main(void) { + // create new process + pid_t pid = fork(); + if (pid == -1) { + return -1; + } else if (pid != 0) { + printf("Running daemon with pid %d\n", pid); + exit(EXIT_SUCCESS); + } + + // create a new session and process group + if (setsid() == -1) return -1; + + // set the working directory to the root directory + if (chdir("/") == -1) return -1; + + // close all open files--NR_OPEN is overkill, but works + for (int i = 0; i < NR_OPEN; i++) { + close(i); + } + + // redirect fd's 0,1,2 to /dev/null + open("/dev/null", O_RDWR); // stdin + dup(0); // stdout + dup(0); // stderr + + // do its daemon thing + for (int i = 0; i < 10; i++) { + printf("Hello from daemon %d\n", getpid()); + sleep(1000); + } + + return 0; +} diff --git a/chp5/session.c b/chp5/session.c new file mode 100644 index 0000000..e092c2d --- /dev/null +++ b/chp5/session.c @@ -0,0 +1,9 @@ +#include +#define _XOPEN_SOURCE 500 +#include + +int main(void) { + printf("My session id=%d\n", getsid(0)); + printf("My process group id=%d\n", getpgid(0)); + return 0; +} diff --git a/chp5/system.c b/chp5/system.c new file mode 100644 index 0000000..822de21 --- /dev/null +++ b/chp5/system.c @@ -0,0 +1,63 @@ +#include +#define _XOPEN_SOURCE +#include +#include +#include +#include + +/* my_system - synchronously spawns and waits for the command + * "/bin/sh -c ". + * + * Returns -1 on error of any sort, or the exit code from the + * launched process. Does not block or ignore any signals. + */ +int my_system(const char *); + +int main(int argc, char *argv[]) { + if (argc < 2) { + fprintf(stderr, "usage: %s ", argv[0]); + return EXIT_FAILURE; + } + + const char *command = argv[1]; + pid_t pid = fork(); + if (pid == -1) { + perror("fork"); + return EXIT_FAILURE; + } else if (pid > 0) { + int ret = my_system(command); + if (ret == -1) { + fprintf(stderr, "command: \"%s\" error", command); + return EXIT_FAILURE; + } + return ret; + } + + int status; + wait(&status); + return status; +} + +int my_system(const char *cmd) { + pid_t pid = fork(); + if (pid == -1) { + return -1; + } else if (pid == 0) { + const char *argv[4]; + argv[0] = "sh"; + argv[1] = "-c"; + argv[2] = cmd; + argv[3] = NULL; + + execv("/bin/sh", argv); + exit(-1); + } + + int status; + if (waitpid(pid, &status, 0) == -1) { + return -1; + } else if (WIFEXITED(status)) { + return WEXITSTATUS(status); + } + return -1; +} diff --git a/chp5/wait.c b/chp5/wait.c new file mode 100644 index 0000000..990cb45 --- /dev/null +++ b/chp5/wait.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include + +int main(void) { + if (!fork()) + return 1; + + int status; + pid_t pid = wait(&status); + if (pid == -1) { + perror("wait"); + } + + printf("pid=%d\n", pid); + + if (WIFEXITED(status)) + printf("Normal termination with exit status=%d\n", WEXITSTATUS(status)); + + if (WIFSIGNALED(status)) + printf("Killed by signal=%d%s\n", WTERMSIG(status), WCOREDUMP(status) ? " (dumped core)" : ""); + + if (WIFSTOPPED(status)) + printf("Stopped by signal=%d\n", WSTOPSIG(status)); + + if (WIFCONTINUED(status)) + printf("Continued\n"); + + return 0; +}