⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fork.c

📁 《CODE READING》配套书源代码 《CODE READING》配套书源代码
💻 C
字号:
// Fork.C -*- C++ -*- socket library// Copyright (C) 1992-1996 Gnanasekaran Swaminathan <gs4t@virginia.edu>//// Permission is granted to use at your own risk and distribute this software// in source and  binary forms provided  the above copyright notice and  this// paragraph are  preserved on all copies.  This software is provided "as is"// with no express or implied warranty.//// Version: 12Jan97 1.11#include <config.h>#include <iostream.h>#include <stdio.h> // perror in solaris2.3 is declared here#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <signal.h>#include <sys/wait.h>#include <Fork.h>Fork::ForkProcess* Fork::ForkProcess::list = 0;Fork::KillForks Fork::killall;Fork::~Fork (){  if (process->pid <= 0)    delete process;}Fork::KillForks::~KillForks ()  // First, kill all children whose kill_child flag is set.  // Second, wait for other children to die.{  for (ForkProcess* cur = Fork::ForkProcess::list; cur; cur = cur->next)    if (cur->kill_child)      delete cur;  while (Fork::ForkProcess::list && wait (0) > 0);}Fork::ForkProcess::ForkProcess (bool kill, bool give_reason)  : kill_child (kill), reason (give_reason), next (0){  if (list == 0) {    struct sigaction sa;    sa.sa_handler = sighnd (&Fork::ForkProcess::reaper_nohang);    sigemptyset (&sa.sa_mask);    sa.sa_flags = SA_RESTART;    sigaction (SIGCHLD, &sa, 0);  }  pid = fork ();  if (pid > 0) {    next = list;    list = this;  } else if (pid == 0) {    // child process. clear list    ForkProcess* p = list;    while (p) {      ForkProcess* nxt = p->next;      p->pid = 0;      delete p;      p = nxt;    }    list = 0;    if (kill_child) {      struct sigaction sa;      sa.sa_handler = sighnd (&Fork::ForkProcess::commit_suicide);      sigemptyset (&sa.sa_mask);      sa.sa_flags = SA_RESTART;      sigaction (SIGTERM, &sa, 0);    }  }}Fork::ForkProcess::~ForkProcess (){  if (pid > 0) {    if (kill_child)      kill (pid, SIGTERM);    reap_child ();    // I remove myself from list    if (list == this)      list = list->next;    else {      for (ForkProcess* p = list; p; p = p->next)	if (p->next == this) {	  p->next = next;	  break;	}    }  }}void Fork::ForkProcess::kill_process () const{  if (pid > 0) {    kill (pid, SIGKILL);    reap_child ();  }}void Fork::ForkProcess::reap_child () const{  int status;  if (pid > 0 && waitpid (pid, &status, 0) == pid && reason)    infanticide_reason (pid, status);}void Fork::ForkProcess::infanticide_reason (pid_t pid, int status){  if (pid <= 0)    return;  if (WIFSTOPPED (status))    cerr << "process " << pid << " gets "      << SYS_SIGLIST [WSTOPSIG (status)] << endl;  else if (WIFEXITED (status))    cerr << "process " << pid << " exited with status "      << WEXITSTATUS (status) << endl;  else if (WIFSIGNALED (status))    cerr << "process " << pid << " got "      << SYS_SIGLIST [WTERMSIG (status)] << endl;}void Fork::ForkProcess::reaper_nohang (int signo){  if (signo != SIGCHLD)    return;  int status;  pid_t wpid;  if ((wpid = waitpid (-1, &status, WNOHANG)) > 0) {    ForkProcess* prev = 0;    ForkProcess* cur  = list;    while (cur) {      if (cur->pid == wpid) {	cur->pid = -1;	if (prev)	  prev->next = cur->next;	else	  list = list->next;		if (cur->reason)	  infanticide_reason (wpid, status);	delete cur;	break;      }      prev = cur;      cur  = cur->next;    }  }}void Fork::ForkProcess::commit_suicide (int){  // if this process has any children we kill them.  ForkProcess* p = list;  while (p) {    ForkProcess* next = p->next;    if (!p->kill_child) // otherwise ForkProcess::~ForkProcess will take care      kill (p->pid, SIGKILL);    delete p; // ForkProcess::~ForkProcess will call reap_child ().    p = next;  }  exit (0x0f); }void Fork::suicide_signal (int signo)     // commit suicide at the signal signo{  struct sigaction sa;  sa.sa_handler = sighnd (&Fork::ForkProcess::commit_suicide);  sigemptyset (&sa.sa_mask);  sa.sa_flags = 0;  if (sigaction (signo, &sa, 0) == -1)    perror ("Fork: Cannot commit suicide with the specified signal");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -