Operating Systems Level 13
PART 4 • SYSTEMS & CAREER

Observe OS Concepts through Linux Interfaces

Use process tools, file descriptors, fork, exec, wait, pipes and signals to connect textbook state transitions with real system behavior.

Level 13 of 15 Applied 120–150 minutes C system-programming lab
BY THE END, YOU CAN

Explain a mini shell pipeline

  • Inspect processes and resources.
  • Distinguish fork and exec.
  • Reap children with wait.
  • Redirect and connect descriptors.
  • Handle signals and failures safely.
01 • OBSERVE BEFORE MODIFYING

Linux Exposes Kernel State through Commands and Pseudo-Files

PROCESS

ps, top, pstree

Inspect PID, parent, state, CPU/memory use and hierarchy. A snapshot and a live monitor answer different questions.

FILES

ls -l, stat, lsof

View permissions/metadata and discover which process holds an open descriptor.

SYSTEM CALLS

strace

Observe the kernel interface and error codes; avoid exposing secrets in traced arguments.

stdin=0 stdout=1 stderr=2 every call: check return value
02 • BUILD A PROCESS PIPELINE

fork() Duplicates; exec() Replaces

1

Create a pipe

Two descriptors represent read and write ends. Create it before fork so both children inherit them.

2

Fork producer and consumer

Each fork returns zero in the child and the child PID in the parent; failure returns −1.

3

Redirect with dup2

Connect producer stdout to pipe write and consumer stdin to pipe read.

4

Close unused ends

Leaked write descriptors can prevent the reader from ever receiving EOF.

5

Exec and wait

Children replace their images; parent reaps both and interprets exit status.

03 • INTERACTIVE SYSTEM-CALL LAB

Choose an Operation and Follow Its Boundary

READY

Select an operation

The user–kernel transition will appear here.

04 • COMPLETE C EXAMPLE

Create a Child and Report Its Exit Status

#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    pid_t pid = fork();
    if (pid < 0) { perror("fork"); return EXIT_FAILURE; }
    if (pid == 0) {
        execlp("printf", "printf", "Hello from child\\n", NULL);
        perror("exec"); _exit(127);
    }
    int status;
    if (waitpid(pid, &status, 0) < 0) { perror("waitpid"); return EXIT_FAILURE; }
    if (WIFEXITED(status)) printf("child exit=%d\\n", WEXITSTATUS(status));
    return EXIT_SUCCESS;
}

The child uses _exit after failed exec to avoid flushing inherited buffered streams incorrectly. The parent distinguishes normal exit from signal termination in a fuller program.

05 • PROGRAM TRACING

Trace ls | wc -l

PIPELINE ·

06 • CHECK & PREPARE

Ten Linux Questions

Answered correctly: 0 of 10
UNIVERSITY
  1. Explain fork and exec.
  2. Describe pipe communication.
  3. Explain descriptors.
  4. Process signal lifecycle.
  5. Zombie and orphan.
INTERVIEW
  1. Why close pipe ends?
  2. What survives exec?
  3. Why wait?
  4. What is SIGKILL?
  5. Why async-signal-safe?
PRACTICE
  1. Build two-command shell.
  2. Add redirection.
  3. Handle Ctrl+C.
  4. Report exit status.
  5. Test failed commands.
LEVEL 13 SUMMARY

You Can Connect Commands to Kernel Mechanisms

  • Descriptors are process-local handles to open objects.
  • fork creates a process; exec replaces its image.
  • wait reaps child status and prevents zombies.
  • Pipes connect byte streams through inherited descriptors.
  • Robust system code checks every return value.
COURSE CHECKPOINT

Mark complete after explaining a two-process pipeline.

Saved in this browser.