/*
 * Copyright ©2026 Soham Pardeshi. All rights reserved.
 * Permission is hereby granted to students registered for University of
 * Washington CSE 333 for use solely during Summer Quarter 2026 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 <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main(void) {
  int x = 0;

  pid_t pid = fork();
  if (pid < 0) {
    perror("fork");  // fork() failed; sets errno; no child exists
    return EXIT_FAILURE;
  }

  if (pid == 0) {
    // Child process: this x is a private copy in the child's own
    // address space. Changing it here does not change the parent's x.
    x = 1;
    printf("child:  pid=%d x=%d\n", getpid(), x);
    _exit(EXIT_SUCCESS);  // skip flushing stdio buffers copied at fork
  }

  // Parent process: this x is the original, in a separate address
  // space from the child's copy.
  x = 2;
  printf("parent: pid=%d child_pid=%d x=%d\n", getpid(), pid, x);

  // Without waitpid, the child would become a zombie: it has exited,
  // but its exit status stays in the process table until we collect it.
  int status;
  waitpid(pid, &status, 0);
  if (WIFEXITED(status)) {
    printf("parent: child exited with status %d\n", WEXITSTATUS(status));
  }
  return EXIT_SUCCESS;
}