/* * Copyright ©2025 Hannah C. Tang. All rights reserved. * * Permission is hereby granted to students registered for University * of Washington CSE 351 for purposes of the course. No other use, copying, * distribution, or modification is permitted without prior written * consent. Copyrights for third-party components of this work must be * honored. Instructors interested in reusing these course materials * should contact the author. */ #include #include #include #include static const int kDefaultSleepSecs = 10; int main(int argc, char **argv) { // If we want to to `ps aux` in a separate terminal to show the process // tree, then we should use a relatively generous sleep threshold. A // "straight-shot" demo would benefit from passing in a value of "1". int sleep_secs = kDefaultSleepSecs; if (argc == 2) { if ((sleep_secs = atoi(argv[1])) < 0) { sleep_secs = kDefaultSleepSecs; } } pid_t parent_pid = getpid(); printf("[parent:%d] about to fork...\n\n", parent_pid); sleep(sleep_secs); pid_t child_pid = fork(); if (child_pid == 0) { // Child. Its job is to wait a little bit, then exit. child_pid = getpid(); printf("[child:%d] I'm alive!\n", child_pid); sleep(sleep_secs); printf("[child:%d] Exiting ... I'm becoming a zombie.\n", child_pid); return EXIT_SUCCESS; } else if (child_pid < 0) { // Parent (fork failed). fprintf(stderr, "[parent:%d] fork failed :(\n", parent_pid); return EXIT_FAILURE; } else { // Parent (fork succeeded). Its job is to print the pid of the // child process, call waitpid() to ensure that the child has exited (per // its algorithm, described above), then exit. printf("[parent:%d] Child process (%d) is running!\n", parent_pid, child_pid); sleep(1.5 * sleep_secs); printf("\n[parent:%d] Waiting for child process to finish...\n", parent_pid); waitpid(child_pid, NULL, 0); printf("[parent:%d] Child process is done.\n", parent_pid); sleep(0.5 * sleep_secs); return EXIT_SUCCESS; } }