static void test_pty(void) { pid_t pid; Pty *pty; rcvsiz = 0; zero(rcvbuf); assert_se(sd_event_default(&event) >= 0); pid = pty_fork(&pty, event, pty_fn, NULL, 80, 25); assert_se(pid >= 0); if (pid == 0) { /* child */ run_child(pty); exit(0); } /* parent */ run_parent(pty); /* Make sure the PTY recycled the child; yeah, this is racy if the * PID was already reused; but that seems fine for a test. */ assert_se(waitpid(pid, NULL, WNOHANG) < 0 && errno == ECHILD); pty_unref(pty); sd_event_unref(event); }
static unsigned long doit(void *shm) { pid_t child; unsigned long res; int status; child = fork(); if (child == 0) { run_child(shm); _exit(0); } else { res = run_parent(shm); if (waitpid(child, &status, 0) != child) err(1, "waitpid"); if (WIFSIGNALED(status)) errx(1, "child died with signal %d", WTERMSIG(status)); if (!WIFEXITED(status)) errx(1, "child abnromal exit code 0x%x", status); if (WEXITSTATUS(status) != 0) errx(1, "child reported error %d", WEXITSTATUS(status)); *(unsigned *)shm = 0; return res; } }
/* chain fork a large number of children. */ int main(int argc, char **argv) { (void) argc; (void) argv; int ret; ret = fork(); CHECK(ret >= 0); if (ret) run_parent(); else run_child(); return 0; }
int main (void) { pid_t pid; struct sigaction sa; sigset_t sigSet; // setup signal handler sigemptyset (&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = signal_handler; if (sigaction (SIGUSR1, &sa, NULL) == -1) { perror ("sigaction()"); return 1; } // block SIGUSR1 to start if (sigemptyset (&sigSet) == -1) { perror ("sigemptyset()"); return 1; } if (sigaddset (&sigSet, SIGUSR1) == -1) { perror ("sigaddset()"); return 1; } if (sigprocmask (SIG_SETMASK, &sigSet, NULL) == -1) { perror ("sigprocmask()"); return 1; } pid = fork (); switch (pid) { case -1: // error perror ("fork()"); return 1; case 0: // child run_child (); break; default: // parent run_parent (pid); break; } return 0; }
int run_main (int argc, ACE_TCHAR *argv[]) { int c = 0; int handle_inherit = 0; /* Disable inheritance by default */ bool ischild = false; ACE_TString temp_file_name; ACE_Get_Opt getopt (argc, argv, ACE_TEXT ("ch:f:")); while ((c = getopt ()) != -1) switch ((char) c) { case 'c': ischild = true; break; case 'h': handle_inherit = ACE_OS::atoi (getopt.opt_arg ()); break; case 'f': temp_file_name = getopt.opt_arg (); break; default: // Don't forgive bad options ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("Bad option\n")), -1); break; } if (ischild) { ACE_TCHAR lognm[MAXPATHLEN]; int const mypid (ACE_OS::getpid ()); ACE_OS::snprintf (lognm, MAXPATHLEN, ACE_TEXT ("Process_Test-child-%d"), mypid); ACE_START_TEST (lognm); int result = check_temp_file (temp_file_name); // Check descriptor inheritance if (result == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("Could not retrieve open files\n")), -1); else if (result == handle_inherit) result = 0; else ACE_ERROR ((LM_ERROR, ACE_TEXT ("Handle inheritance test failed with ") ACE_TEXT ("%d, expected %d\n"), result, handle_inherit)); ACE_END_LOG; return result; } else { ACE_START_TEST (ACE_TEXT ("Process_Test")); int status = test_setenv (); // The rest of this test relies on the ability to get a list of open // files for a process and examine each file descriptor to see which // file is open, matching against an expected opened file name. // Although most systems provide some mechanism to do this, the code // in this test uses Linux-specific techniques. Thus, although it // is possible to add the code for the checks on, for example, // HP-UX (pstat_getproc, pstat_getpathname) and // AIX (/proc is available, but there's no self and the fds are not links // to the opened file names), the code isn't here at present. #if defined (ACE_LACKS_FORK) || defined (ACE_LACKS_READLINK) || !defined(ACE_LINUX) ACE_ERROR ((LM_INFO, ACE_TEXT ("The remainder of this test is not supported on this platform\n"))); #else // Test handle inheritance set to true if (!status) status = run_parent (true); // ... and set to false if (!status) run_parent (false); #endif /* ! ACE_LACKS_FORK */ ACE_END_TEST; return status; } }