Renaming all folders
This commit is contained in:
73
05_ProcessManagement/README.md
Normal file
73
05_ProcessManagement/README.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# 📘 Chapter 5 – Process Management (Summary)
|
||||
**Based on _Linux System Programming_ by Robert Love**
|
||||
|
||||
This chapter covers how Linux manages processes, including their creation, execution, and termination. It introduces key system calls and concepts that underpin multitasking and process control in Unix-like systems.
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Core Concepts
|
||||
- A **process** is an independent program with its own memory and execution context.
|
||||
- The kernel provides **process abstraction** to manage concurrency.
|
||||
- Processes are scheduled and isolated using virtual memory and process control blocks (PCBs).
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Process Creation & Termination
|
||||
- `fork()` creates a new process (child) by duplicating the calling (parent) process using **copy-on-write**.
|
||||
- `exec()` replaces the current process image with a new program.
|
||||
- `wait()` and `waitpid()` allow the parent to wait for and collect the child’s exit status.
|
||||
- `exit()` performs cleanup and exits the process gracefully.
|
||||
- `_exit()` exits immediately without flushing stdio buffers.
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Signals & Zombies
|
||||
- **Zombie processes** occur when a child exits but the parent doesn’t read its status with `wait()`.
|
||||
- `SIGCHLD` is sent to the parent when a child terminates.
|
||||
- The `init` process (PID 1) will adopt and clean up orphaned children.
|
||||
|
||||
---
|
||||
|
||||
## 👥 Process Hierarchies
|
||||
- Every process has a unique **PID** and a **PPID** (parent PID).
|
||||
- Together they form a **process tree**, starting from `init`.
|
||||
- Tools like `ps`, `pstree`, and `/proc` are useful for visualizing process hierarchies.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Process Identifiers & Groups
|
||||
- `getpid()` returns the process’s ID.
|
||||
- `getppid()` returns the parent’s ID.
|
||||
- **Process groups** and **sessions** enable job control, allowing signals to be sent to multiple related processes.
|
||||
|
||||
---
|
||||
|
||||
## 🧩 Resource Cleanup
|
||||
- On termination, the kernel reclaims:
|
||||
- Memory
|
||||
- Open file descriptors
|
||||
- IPC resources
|
||||
- `exit()` also triggers:
|
||||
- `atexit()` handlers
|
||||
- Standard I/O flushes
|
||||
- Potential creation of core dumps (if enabled)
|
||||
|
||||
---
|
||||
|
||||
## ✅ Why This Matters
|
||||
A strong understanding of process control is essential for:
|
||||
- Writing daemons
|
||||
- Managing background jobs
|
||||
- Building shells or supervisors
|
||||
- Avoiding resource leaks and zombie processes
|
||||
|
||||
---
|
||||
|
||||
## 📚 References
|
||||
- _Linux System Programming_, 2nd Edition by Robert Love (O'Reilly)
|
||||
- `man 2 fork`, `man 2 execve`, `man 2 wait`, `man 2 exit`, `man 7 signal`
|
||||
|
||||
---
|
||||
|
||||
*This summary is for educational purposes.*
|
||||
|
||||
22
05_ProcessManagement/atexit.c
Normal file
22
05_ProcessManagement/atexit.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
* Copyright (c) 2025 Fabio Scotto di Santolo
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void out(void)
|
||||
{
|
||||
printf("atexit() succeeded!\n");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (atexit(out)) {
|
||||
fprintf(stderr, "atexit() failed\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
52
05_ProcessManagement/daemon.c
Normal file
52
05_ProcessManagement/daemon.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
* Copyright (c) 2025 Fabio Scotto di Santolo
|
||||
*/
|
||||
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
16
05_ProcessManagement/session.c
Normal file
16
05_ProcessManagement/session.c
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
* Copyright (c) 2025 Fabio Scotto di Santolo
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <unistd.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("My session id=%d\n", getsid(0));
|
||||
printf("My process group id=%d\n", getpgid(0));
|
||||
return 0;
|
||||
}
|
||||
71
05_ProcessManagement/system.c
Normal file
71
05_ProcessManagement/system.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
* Copyright (c) 2025 Fabio Scotto di Santolo
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#define _XOPEN_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* my_system - synchronously spawns and waits for the command
|
||||
* "/bin/sh -c <cmd>".
|
||||
*
|
||||
* 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 <command>", 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;
|
||||
}
|
||||
40
05_ProcessManagement/wait.c
Normal file
40
05_ProcessManagement/wait.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
* Copyright (c) 2025 Fabio Scotto di Santolo
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user