static int wait_parent(void) { pid_t mypid, childpid, rv; int x; int result; report_begin("wait for parent"); report_hassubs(); mypid = getpid(); childpid = fork(); if (childpid<0) { report_warn("can't fork"); report_aborted(&result); return result; } if (childpid==0) { /* Child. Wait for parent. */ rv = waitpid(mypid, &x, 0); report_beginsub("from child:"); report_survival(rv, errno, &result); _exit(0); } rv = waitpid(mypid, &x, 0); report_beginsub("from parent:"); report_survival(rv, errno, &result); return result; }
static int wait_unaligned(void) { pid_t pid, rv; int x; int status[2]; /* will have integer alignment */ char *ptr; int result; report_begin("wait with unaligned status"); pid = fork(); if (pid<0) { report_warn("fork failed"); report_aborted(&result); return result; } if (pid==0) { exit(0); } /* start with proper integer alignment */ ptr = (char *)(&status[0]); /* generate improper alignment on platforms with restrictions */ ptr++; rv = waitpid(pid, (int *)ptr, 0); report_survival(rv, errno, &result); if (rv<0) { waitpid(pid, &x, 0); } return result; }
static void wait_unaligned(void) { int rv, pid, x; int status[2]; /* will have integer alignment */ char *ptr; pid = fork(); if (pid<0) { warn("UH-OH: fork failed"); return; } if (pid==0) { exit(0); } /* start with proper integer alignment */ ptr = (char *)(&status[0]); /* generate improper alignment on platforms with restrictions*/ ptr++; rv = waitpid(pid, (int *)ptr, 0); report_survival(rv, errno, "wait with unaligned status"); if (rv<0) { waitpid(pid, &x, 0); } }
static void wait_self(void) { int rv, x; rv = waitpid(getpid(), &x, 0); report_survival(rv, errno, "wait for self"); }
static void wait_parent(void) { int mypid, childpid, rv, x; mypid = getpid(); childpid = fork(); if (childpid<0) { warn("UH-OH: can't fork"); return; } if (childpid==0) { /* Child. Wait for parent. */ rv = waitpid(mypid, &x, 0); report_survival(rv, errno, "wait for parent (from child)"); _exit(0); } rv = waitpid(childpid, &x, 0); report_survival(rv, errno, "wait for parent test (from parent)"); }
static void wait_siblings_child(void) { int pids[2], mypid, otherpid, fd, rv, x; mypid = getpid(); fd = open(TESTFILE, O_RDONLY); if (fd<0) { warn("UH-OH: child process (pid %d) can't open %s", mypid, TESTFILE); return; } /* * Busy-wait until the parent writes the pids into the file. * This sucks, but there's not a whole lot else we can do. */ do { rv = lseek(fd, 0, SEEK_SET); if (rv<0) { warn("UH-OH: child process (pid %d) lseek error", mypid); return; } rv = read(fd, pids, sizeof(pids)); if (rv<0) { warn("UH-OH: child process (pid %d) read error", mypid); return; } } while (rv < (int)sizeof(pids)); if (mypid==pids[0]) { otherpid = pids[1]; } else if (mypid==pids[1]) { otherpid = pids[0]; } else { warn("UH-OH: child process (pid %d) got garbage in comm file", mypid); return; } close(fd); rv = waitpid(otherpid, &x, 0); report_survival(rv, errno, "sibling wait"); }
static void pipe_unaligned(void) { int fds[3], rv; char *ptr; ptr = (char *)&fds[0]; ptr++; rv = pipe((int *)ptr); report_survival(rv, errno, "pipe with unaligned pointer"); }
static int wait_self(void) { pid_t rv; int x; int result; report_begin("wait for self"); rv = waitpid(getpid(), &x, 0); report_survival(rv, errno, &result); return result; }
static int wait_siblings_child(const char *semname) { pid_t pids[2], mypid, otherpid; int rv, fd, semfd, x; char c; int result; mypid = getpid(); /* * Get our own handle for the semaphore, in case naive * file-level synchronization causes concurrent use to * deadlock. */ semfd = open(semname, O_RDONLY); if (semfd < 0) { report_warn("child process (pid %d) can't open %s", mypid, semname); } else { if (read(semfd, &c, 1) < 0) { report_warn("in pid %d: %s: read", mypid, semname); } close(semfd); } fd = open(TESTFILE, O_RDONLY); if (fd<0) { report_warn("child process (pid %d) can't open %s", mypid, TESTFILE); return FAILED; } /* * In case the semaphore above didn't work, as a backup * busy-wait until the parent writes the pids into the * file. If the semaphore did work, this shouldn't loop. */ do { rv = lseek(fd, 0, SEEK_SET); if (rv<0) { report_warn("child process (pid %d) lseek error", mypid); return FAILED; } rv = read(fd, pids, sizeof(pids)); if (rv<0) { report_warn("child process (pid %d) read error", mypid); return FAILED; } } while (rv < (int)sizeof(pids)); if (mypid==pids[0]) { otherpid = pids[1]; } else if (mypid==pids[1]) { otherpid = pids[0]; } else { report_warn("child process (pid %d) got garbage in comm file", mypid); return FAILED; } close(fd); rv = waitpid(otherpid, &x, 0); report_beginsub("sibling (pid %d)", mypid); report_survival(rv, errno, &result); return result; }