1*670b568eSEd Maste // Tests for the process descriptor API for Linux.
2*670b568eSEd Maste #include <sys/types.h>
3*670b568eSEd Maste #include <sys/resource.h>
4*670b568eSEd Maste #include <sys/select.h>
5*670b568eSEd Maste #include <sys/socket.h>
6*670b568eSEd Maste #include <sys/stat.h>
7*670b568eSEd Maste #include <sys/time.h>
8*670b568eSEd Maste #include <sys/wait.h>
9*670b568eSEd Maste #include <fcntl.h>
10*670b568eSEd Maste #include <poll.h>
11*670b568eSEd Maste #include <pthread.h>
12*670b568eSEd Maste #include <signal.h>
13*670b568eSEd Maste #include <stdlib.h>
14*670b568eSEd Maste #include <unistd.h>
15*670b568eSEd Maste
16*670b568eSEd Maste #include <iomanip>
17*670b568eSEd Maste #include <map>
18*670b568eSEd Maste
19*670b568eSEd Maste #include "capsicum.h"
20*670b568eSEd Maste #include "syscalls.h"
21*670b568eSEd Maste #include "capsicum-test.h"
22*670b568eSEd Maste
23*670b568eSEd Maste #ifndef __WALL
24*670b568eSEd Maste // Linux requires __WALL in order for waitpid(specific_pid,...) to
25*670b568eSEd Maste // see and reap any specific pid. Define this to nothing for platforms
26*670b568eSEd Maste // (FreeBSD) where it doesn't exist, to reduce macroing.
27*670b568eSEd Maste #define __WALL 0
28*670b568eSEd Maste #endif
29*670b568eSEd Maste
30*670b568eSEd Maste //------------------------------------------------
31*670b568eSEd Maste // Utilities for the tests.
32*670b568eSEd Maste
pdwait4_(int pd,int * status,int options,struct rusage * ru)33*670b568eSEd Maste static pid_t pdwait4_(int pd, int *status, int options, struct rusage *ru) {
34*670b568eSEd Maste #ifdef HAVE_PDWAIT4
35*670b568eSEd Maste return pdwait4(pd, status, options, ru);
36*670b568eSEd Maste #else
37*670b568eSEd Maste // Simulate pdwait4() with wait4(pdgetpid()); this won't work in capability mode.
38*670b568eSEd Maste pid_t pid = -1;
39*670b568eSEd Maste int rc = pdgetpid(pd, &pid);
40*670b568eSEd Maste if (rc < 0) {
41*670b568eSEd Maste return rc;
42*670b568eSEd Maste }
43*670b568eSEd Maste options |= __WALL;
44*670b568eSEd Maste return wait4(pid, status, options, ru);
45*670b568eSEd Maste #endif
46*670b568eSEd Maste }
47*670b568eSEd Maste
print_rusage(FILE * f,struct rusage * ru)48*670b568eSEd Maste static void print_rusage(FILE *f, struct rusage *ru) {
49*670b568eSEd Maste fprintf(f, " User CPU time=%ld.%06ld\n", (long)ru->ru_utime.tv_sec, (long)ru->ru_utime.tv_usec);
50*670b568eSEd Maste fprintf(f, " System CPU time=%ld.%06ld\n", (long)ru->ru_stime.tv_sec, (long)ru->ru_stime.tv_usec);
51*670b568eSEd Maste fprintf(f, " Max RSS=%ld\n", ru->ru_maxrss);
52*670b568eSEd Maste }
53*670b568eSEd Maste
print_stat(FILE * f,const struct stat * stat)54*670b568eSEd Maste static void print_stat(FILE *f, const struct stat *stat) {
55*670b568eSEd Maste fprintf(f,
56*670b568eSEd Maste "{ .st_dev=%ld, st_ino=%ld, st_mode=%04o, st_nlink=%ld, st_uid=%d, st_gid=%d,\n"
57*670b568eSEd Maste " .st_rdev=%ld, .st_size=%ld, st_blksize=%ld, .st_block=%ld,\n "
58*670b568eSEd Maste #ifdef HAVE_STAT_BIRTHTIME
59*670b568eSEd Maste ".st_birthtime=%ld, "
60*670b568eSEd Maste #endif
61*670b568eSEd Maste ".st_atime=%ld, .st_mtime=%ld, .st_ctime=%ld}\n",
62*670b568eSEd Maste (long)stat->st_dev, (long)stat->st_ino, stat->st_mode,
63*670b568eSEd Maste (long)stat->st_nlink, stat->st_uid, stat->st_gid,
64*670b568eSEd Maste (long)stat->st_rdev, (long)stat->st_size, (long)stat->st_blksize,
65*670b568eSEd Maste (long)stat->st_blocks,
66*670b568eSEd Maste #ifdef HAVE_STAT_BIRTHTIME
67*670b568eSEd Maste (long)stat->st_birthtime,
68*670b568eSEd Maste #endif
69*670b568eSEd Maste (long)stat->st_atime, (long)stat->st_mtime, (long)stat->st_ctime);
70*670b568eSEd Maste }
71*670b568eSEd Maste
72*670b568eSEd Maste static volatile sig_atomic_t had_signal[NSIG];
clear_had_signals()73*670b568eSEd Maste void clear_had_signals() {
74*670b568eSEd Maste memset(const_cast<sig_atomic_t *>(had_signal), 0, sizeof(had_signal));
75*670b568eSEd Maste }
handle_signal(int x)76*670b568eSEd Maste static void handle_signal(int x) {
77*670b568eSEd Maste had_signal[x] = true;
78*670b568eSEd Maste }
79*670b568eSEd Maste
80*670b568eSEd Maste // Check that the given child process terminates as expected.
CheckChildFinished(pid_t pid,bool signaled=false)81*670b568eSEd Maste void CheckChildFinished(pid_t pid, bool signaled=false) {
82*670b568eSEd Maste // Wait for the child to finish.
83*670b568eSEd Maste int rc;
84*670b568eSEd Maste int status = 0;
85*670b568eSEd Maste do {
86*670b568eSEd Maste rc = waitpid(pid, &status, __WALL);
87*670b568eSEd Maste if (rc < 0) {
88*670b568eSEd Maste fprintf(stderr, "Warning: waitpid error %s (%d)\n", strerror(errno), errno);
89*670b568eSEd Maste ADD_FAILURE() << "Failed to wait for child";
90*670b568eSEd Maste break;
91*670b568eSEd Maste } else if (rc == pid) {
92*670b568eSEd Maste break;
93*670b568eSEd Maste }
94*670b568eSEd Maste } while (true);
95*670b568eSEd Maste EXPECT_EQ(pid, rc);
96*670b568eSEd Maste if (rc == pid) {
97*670b568eSEd Maste if (signaled) {
98*670b568eSEd Maste EXPECT_TRUE(WIFSIGNALED(status));
99*670b568eSEd Maste } else {
100*670b568eSEd Maste EXPECT_TRUE(WIFEXITED(status)) << std::hex << status;
101*670b568eSEd Maste EXPECT_EQ(0, WEXITSTATUS(status));
102*670b568eSEd Maste }
103*670b568eSEd Maste }
104*670b568eSEd Maste }
105*670b568eSEd Maste
106*670b568eSEd Maste //------------------------------------------------
107*670b568eSEd Maste // Basic tests of process descriptor functionality
108*670b568eSEd Maste
TEST(Pdfork,Simple)109*670b568eSEd Maste TEST(Pdfork, Simple) {
110*670b568eSEd Maste int pd = -1;
111*670b568eSEd Maste int pipefds[2];
112*670b568eSEd Maste pid_t parent = getpid_();
113*670b568eSEd Maste EXPECT_OK(pipe(pipefds));
114*670b568eSEd Maste int pid = pdfork(&pd, 0);
115*670b568eSEd Maste EXPECT_OK(pid);
116*670b568eSEd Maste if (pid == 0) {
117*670b568eSEd Maste // Child: check pid values.
118*670b568eSEd Maste EXPECT_EQ(-1, pd);
119*670b568eSEd Maste EXPECT_NE(parent, getpid_());
120*670b568eSEd Maste EXPECT_EQ(parent, getppid());
121*670b568eSEd Maste close(pipefds[0]);
122*670b568eSEd Maste SEND_INT_MESSAGE(pipefds[1], MSG_CHILD_STARTED);
123*670b568eSEd Maste if (verbose) fprintf(stderr, "Child waiting for exit message\n");
124*670b568eSEd Maste // Terminate once the parent has completed the checks
125*670b568eSEd Maste AWAIT_INT_MESSAGE(pipefds[1], MSG_PARENT_REQUEST_CHILD_EXIT);
126*670b568eSEd Maste exit(testing::Test::HasFailure());
127*670b568eSEd Maste }
128*670b568eSEd Maste close(pipefds[1]);
129*670b568eSEd Maste // Ensure the child has started.
130*670b568eSEd Maste AWAIT_INT_MESSAGE(pipefds[0], MSG_CHILD_STARTED);
131*670b568eSEd Maste
132*670b568eSEd Maste EXPECT_NE(-1, pd);
133*670b568eSEd Maste EXPECT_PID_ALIVE(pid);
134*670b568eSEd Maste int pid_got;
135*670b568eSEd Maste EXPECT_OK(pdgetpid(pd, &pid_got));
136*670b568eSEd Maste EXPECT_EQ(pid, pid_got);
137*670b568eSEd Maste
138*670b568eSEd Maste // Tell the child to exit and wait until it is a zombie.
139*670b568eSEd Maste SEND_INT_MESSAGE(pipefds[0], MSG_PARENT_REQUEST_CHILD_EXIT);
140*670b568eSEd Maste // EXPECT_PID_ZOMBIE waits for up to ~500ms, that should be enough time for
141*670b568eSEd Maste // the child to exit successfully.
142*670b568eSEd Maste EXPECT_PID_ZOMBIE(pid);
143*670b568eSEd Maste close(pipefds[0]);
144*670b568eSEd Maste
145*670b568eSEd Maste // Wait for the the child.
146*670b568eSEd Maste int status;
147*670b568eSEd Maste struct rusage ru;
148*670b568eSEd Maste memset(&ru, 0, sizeof(ru));
149*670b568eSEd Maste int waitrc = pdwait4_(pd, &status, 0, &ru);
150*670b568eSEd Maste EXPECT_EQ(pid, waitrc);
151*670b568eSEd Maste if (verbose) {
152*670b568eSEd Maste fprintf(stderr, "For pd %d pid %d:\n", pd, pid);
153*670b568eSEd Maste print_rusage(stderr, &ru);
154*670b568eSEd Maste }
155*670b568eSEd Maste EXPECT_PID_GONE(pid);
156*670b568eSEd Maste
157*670b568eSEd Maste // Can only pdwait4(pd) once (as initial call reaps zombie).
158*670b568eSEd Maste memset(&ru, 0, sizeof(ru));
159*670b568eSEd Maste EXPECT_EQ(-1, pdwait4_(pd, &status, 0, &ru));
160*670b568eSEd Maste EXPECT_EQ(ECHILD, errno);
161*670b568eSEd Maste
162*670b568eSEd Maste EXPECT_OK(close(pd));
163*670b568eSEd Maste }
164*670b568eSEd Maste
TEST(Pdfork,InvalidFlag)165*670b568eSEd Maste TEST(Pdfork, InvalidFlag) {
166*670b568eSEd Maste int pd = -1;
167*670b568eSEd Maste int pid = pdfork(&pd, PD_DAEMON<<5);
168*670b568eSEd Maste if (pid == 0) {
169*670b568eSEd Maste exit(1);
170*670b568eSEd Maste }
171*670b568eSEd Maste EXPECT_EQ(-1, pid);
172*670b568eSEd Maste EXPECT_EQ(EINVAL, errno);
173*670b568eSEd Maste if (pid > 0) waitpid(pid, NULL, __WALL);
174*670b568eSEd Maste }
175*670b568eSEd Maste
TEST(Pdfork,TimeCheck)176*670b568eSEd Maste TEST(Pdfork, TimeCheck) {
177*670b568eSEd Maste time_t now = time(NULL); // seconds since epoch
178*670b568eSEd Maste EXPECT_NE(-1, now);
179*670b568eSEd Maste if (verbose) fprintf(stderr, "Calling pdfork around %ld\n", (long)(long)now);
180*670b568eSEd Maste
181*670b568eSEd Maste int pd = -1;
182*670b568eSEd Maste pid_t pid = pdfork(&pd, 0);
183*670b568eSEd Maste EXPECT_OK(pid);
184*670b568eSEd Maste if (pid == 0) {
185*670b568eSEd Maste // Child: check we didn't get a valid process descriptor then exit.
186*670b568eSEd Maste EXPECT_EQ(-1, pdgetpid(pd, &pid));
187*670b568eSEd Maste EXPECT_EQ(EBADF, errno);
188*670b568eSEd Maste exit(HasFailure());
189*670b568eSEd Maste }
190*670b568eSEd Maste
191*670b568eSEd Maste #ifdef HAVE_PROCDESC_FSTAT
192*670b568eSEd Maste // Parent process. Ensure that [acm]times have been set correctly.
193*670b568eSEd Maste struct stat stat;
194*670b568eSEd Maste memset(&stat, 0, sizeof(stat));
195*670b568eSEd Maste EXPECT_OK(fstat(pd, &stat));
196*670b568eSEd Maste if (verbose) print_stat(stderr, &stat);
197*670b568eSEd Maste
198*670b568eSEd Maste #ifdef HAVE_STAT_BIRTHTIME
199*670b568eSEd Maste EXPECT_GE(now, stat.st_birthtime);
200*670b568eSEd Maste EXPECT_EQ(stat.st_birthtime, stat.st_atime);
201*670b568eSEd Maste #endif
202*670b568eSEd Maste EXPECT_LT((now - stat.st_atime), 2);
203*670b568eSEd Maste EXPECT_EQ(stat.st_atime, stat.st_ctime);
204*670b568eSEd Maste EXPECT_EQ(stat.st_ctime, stat.st_mtime);
205*670b568eSEd Maste #endif
206*670b568eSEd Maste
207*670b568eSEd Maste // Wait for the child to finish.
208*670b568eSEd Maste pid_t pd_pid = -1;
209*670b568eSEd Maste EXPECT_OK(pdgetpid(pd, &pd_pid));
210*670b568eSEd Maste EXPECT_EQ(pid, pd_pid);
211*670b568eSEd Maste CheckChildFinished(pid);
212*670b568eSEd Maste }
213*670b568eSEd Maste
TEST(Pdfork,UseDescriptor)214*670b568eSEd Maste TEST(Pdfork, UseDescriptor) {
215*670b568eSEd Maste int pd = -1;
216*670b568eSEd Maste pid_t pid = pdfork(&pd, 0);
217*670b568eSEd Maste EXPECT_OK(pid);
218*670b568eSEd Maste if (pid == 0) {
219*670b568eSEd Maste // Child: immediately exit
220*670b568eSEd Maste exit(0);
221*670b568eSEd Maste }
222*670b568eSEd Maste CheckChildFinished(pid);
223*670b568eSEd Maste }
224*670b568eSEd Maste
TEST(Pdfork,NonProcessDescriptor)225*670b568eSEd Maste TEST(Pdfork, NonProcessDescriptor) {
226*670b568eSEd Maste int fd = open("/etc/passwd", O_RDONLY);
227*670b568eSEd Maste EXPECT_OK(fd);
228*670b568eSEd Maste // pd*() operations should fail on a non-process descriptor.
229*670b568eSEd Maste EXPECT_EQ(-1, pdkill(fd, SIGUSR1));
230*670b568eSEd Maste int status;
231*670b568eSEd Maste EXPECT_EQ(-1, pdwait4_(fd, &status, 0, NULL));
232*670b568eSEd Maste pid_t pid;
233*670b568eSEd Maste EXPECT_EQ(-1, pdgetpid(fd, &pid));
234*670b568eSEd Maste close(fd);
235*670b568eSEd Maste }
236*670b568eSEd Maste
SubThreadMain(void * arg)237*670b568eSEd Maste static void *SubThreadMain(void *arg) {
238*670b568eSEd Maste // Notify the main thread that we have started
239*670b568eSEd Maste if (verbose) fprintf(stderr, " subthread started: pipe=%p\n", arg);
240*670b568eSEd Maste SEND_INT_MESSAGE((int)(intptr_t)arg, MSG_CHILD_STARTED);
241*670b568eSEd Maste while (true) {
242*670b568eSEd Maste if (verbose) fprintf(stderr, " subthread: \"I aten't dead\"\n");
243*670b568eSEd Maste usleep(100000);
244*670b568eSEd Maste }
245*670b568eSEd Maste return NULL;
246*670b568eSEd Maste }
247*670b568eSEd Maste
ThreadMain(void *)248*670b568eSEd Maste static void *ThreadMain(void *) {
249*670b568eSEd Maste int pd;
250*670b568eSEd Maste int pipefds[2];
251*670b568eSEd Maste EXPECT_EQ(0, pipe(pipefds));
252*670b568eSEd Maste pid_t child = pdfork(&pd, 0);
253*670b568eSEd Maste if (child == 0) {
254*670b568eSEd Maste close(pipefds[0]);
255*670b568eSEd Maste // Child: start a subthread then loop.
256*670b568eSEd Maste pthread_t child_subthread;
257*670b568eSEd Maste // Wait for the subthread startup using another pipe.
258*670b568eSEd Maste int thread_pipefds[2];
259*670b568eSEd Maste EXPECT_EQ(0, pipe(thread_pipefds));
260*670b568eSEd Maste EXPECT_OK(pthread_create(&child_subthread, NULL, SubThreadMain,
261*670b568eSEd Maste (void *)(intptr_t)thread_pipefds[0]));
262*670b568eSEd Maste if (verbose) {
263*670b568eSEd Maste fprintf(stderr, " pdforked process %d: waiting for subthread.\n",
264*670b568eSEd Maste getpid());
265*670b568eSEd Maste }
266*670b568eSEd Maste AWAIT_INT_MESSAGE(thread_pipefds[1], MSG_CHILD_STARTED);
267*670b568eSEd Maste close(thread_pipefds[0]);
268*670b568eSEd Maste close(thread_pipefds[1]);
269*670b568eSEd Maste // Child: Notify parent that all threads have started
270*670b568eSEd Maste if (verbose) fprintf(stderr, " pdforked process %d: subthread started\n", getpid());
271*670b568eSEd Maste SEND_INT_MESSAGE(pipefds[1], MSG_CHILD_STARTED);
272*670b568eSEd Maste while (true) {
273*670b568eSEd Maste if (verbose) fprintf(stderr, " pdforked process %d: \"I aten't dead\"\n", getpid());
274*670b568eSEd Maste usleep(100000);
275*670b568eSEd Maste }
276*670b568eSEd Maste exit(0);
277*670b568eSEd Maste }
278*670b568eSEd Maste if (verbose) fprintf(stderr, " thread generated pd %d\n", pd);
279*670b568eSEd Maste close(pipefds[1]);
280*670b568eSEd Maste AWAIT_INT_MESSAGE(pipefds[0], MSG_CHILD_STARTED);
281*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] got child startup message\n", getpid_());
282*670b568eSEd Maste
283*670b568eSEd Maste // Pass the process descriptor back to the main thread.
284*670b568eSEd Maste return reinterpret_cast<void *>(pd);
285*670b568eSEd Maste }
286*670b568eSEd Maste
TEST(Pdfork,FromThread)287*670b568eSEd Maste TEST(Pdfork, FromThread) {
288*670b568eSEd Maste // Fire off a new thread to do all of the creation work.
289*670b568eSEd Maste pthread_t child_thread;
290*670b568eSEd Maste EXPECT_OK(pthread_create(&child_thread, NULL, ThreadMain, NULL));
291*670b568eSEd Maste void *data;
292*670b568eSEd Maste EXPECT_OK(pthread_join(child_thread, &data));
293*670b568eSEd Maste int pd = reinterpret_cast<intptr_t>(data);
294*670b568eSEd Maste if (verbose) fprintf(stderr, "retrieved pd %d from terminated thread\n", pd);
295*670b568eSEd Maste
296*670b568eSEd Maste // Kill and reap.
297*670b568eSEd Maste pid_t pid;
298*670b568eSEd Maste EXPECT_OK(pdgetpid(pd, &pid));
299*670b568eSEd Maste EXPECT_OK(pdkill(pd, SIGKILL));
300*670b568eSEd Maste int status;
301*670b568eSEd Maste EXPECT_EQ(pid, pdwait4_(pd, &status, 0, NULL));
302*670b568eSEd Maste EXPECT_TRUE(WIFSIGNALED(status));
303*670b568eSEd Maste }
304*670b568eSEd Maste
305*670b568eSEd Maste //------------------------------------------------
306*670b568eSEd Maste // More complicated tests.
307*670b568eSEd Maste
308*670b568eSEd Maste
309*670b568eSEd Maste // Test fixture that pdfork()s off a child process, which terminates
310*670b568eSEd Maste // when it receives anything on a pipe.
311*670b568eSEd Maste class PipePdforkBase : public ::testing::Test {
312*670b568eSEd Maste public:
PipePdforkBase(int pdfork_flags)313*670b568eSEd Maste PipePdforkBase(int pdfork_flags) : pd_(-1), pid_(-1) {
314*670b568eSEd Maste clear_had_signals();
315*670b568eSEd Maste int pipes[2];
316*670b568eSEd Maste EXPECT_OK(pipe(pipes));
317*670b568eSEd Maste pipe_ = pipes[1];
318*670b568eSEd Maste int parent = getpid_();
319*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] about to pdfork()\n", getpid_());
320*670b568eSEd Maste int rc = pdfork(&pd_, pdfork_flags);
321*670b568eSEd Maste EXPECT_OK(rc);
322*670b568eSEd Maste if (rc == 0) {
323*670b568eSEd Maste // Child process: blocking-read an int from the pipe then exit with that value.
324*670b568eSEd Maste EXPECT_NE(parent, getpid_());
325*670b568eSEd Maste EXPECT_EQ(parent, getppid());
326*670b568eSEd Maste if (verbose) fprintf(stderr, " [%d] child of %d waiting for value on pipe\n", getpid_(), getppid());
327*670b568eSEd Maste read(pipes[0], &rc, sizeof(rc));
328*670b568eSEd Maste if (verbose) fprintf(stderr, " [%d] got value %d on pipe, exiting\n", getpid_(), rc);
329*670b568eSEd Maste exit(rc);
330*670b568eSEd Maste }
331*670b568eSEd Maste pid_ = rc;
332*670b568eSEd Maste usleep(100); // ensure the child has a chance to run
333*670b568eSEd Maste }
~PipePdforkBase()334*670b568eSEd Maste ~PipePdforkBase() {
335*670b568eSEd Maste // Terminate by any means necessary.
336*670b568eSEd Maste if (pd_ > 0) {
337*670b568eSEd Maste pdkill(pd_, SIGKILL);
338*670b568eSEd Maste close(pd_);
339*670b568eSEd Maste }
340*670b568eSEd Maste if (pid_ > 0) {
341*670b568eSEd Maste kill(pid_, SIGKILL);
342*670b568eSEd Maste waitpid(pid_, NULL, __WALL|WNOHANG);
343*670b568eSEd Maste }
344*670b568eSEd Maste // Check signal expectations.
345*670b568eSEd Maste EXPECT_FALSE(had_signal[SIGCHLD]);
346*670b568eSEd Maste }
TerminateChild()347*670b568eSEd Maste int TerminateChild() {
348*670b568eSEd Maste // Tell the child to exit.
349*670b568eSEd Maste int zero = 0;
350*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] write 0 to pipe\n", getpid_());
351*670b568eSEd Maste return write(pipe_, &zero, sizeof(zero));
352*670b568eSEd Maste }
353*670b568eSEd Maste protected:
354*670b568eSEd Maste int pd_;
355*670b568eSEd Maste int pipe_;
356*670b568eSEd Maste pid_t pid_;
357*670b568eSEd Maste };
358*670b568eSEd Maste
359*670b568eSEd Maste class PipePdfork : public PipePdforkBase {
360*670b568eSEd Maste public:
PipePdfork()361*670b568eSEd Maste PipePdfork() : PipePdforkBase(0) {}
362*670b568eSEd Maste };
363*670b568eSEd Maste
364*670b568eSEd Maste class PipePdforkDaemon : public PipePdforkBase {
365*670b568eSEd Maste public:
PipePdforkDaemon()366*670b568eSEd Maste PipePdforkDaemon() : PipePdforkBase(PD_DAEMON) {}
367*670b568eSEd Maste };
368*670b568eSEd Maste
369*670b568eSEd Maste // Can we poll a process descriptor?
TEST_F(PipePdfork,Poll)370*670b568eSEd Maste TEST_F(PipePdfork, Poll) {
371*670b568eSEd Maste // Poll the process descriptor, nothing happening.
372*670b568eSEd Maste struct pollfd fdp;
373*670b568eSEd Maste fdp.fd = pd_;
374*670b568eSEd Maste fdp.events = POLLIN | POLLERR | POLLHUP;
375*670b568eSEd Maste fdp.revents = 0;
376*670b568eSEd Maste EXPECT_EQ(0, poll(&fdp, 1, 0));
377*670b568eSEd Maste
378*670b568eSEd Maste TerminateChild();
379*670b568eSEd Maste
380*670b568eSEd Maste // Poll again, should have activity on the process descriptor.
381*670b568eSEd Maste EXPECT_EQ(1, poll(&fdp, 1, 2000));
382*670b568eSEd Maste EXPECT_TRUE(fdp.revents & POLLHUP);
383*670b568eSEd Maste
384*670b568eSEd Maste // Poll a third time, still have POLLHUP.
385*670b568eSEd Maste fdp.revents = 0;
386*670b568eSEd Maste EXPECT_EQ(1, poll(&fdp, 1, 0));
387*670b568eSEd Maste EXPECT_TRUE(fdp.revents & POLLHUP);
388*670b568eSEd Maste }
389*670b568eSEd Maste
390*670b568eSEd Maste // Can multiple processes poll on the same descriptor?
TEST_F(PipePdfork,PollMultiple)391*670b568eSEd Maste TEST_F(PipePdfork, PollMultiple) {
392*670b568eSEd Maste int pipefds[2];
393*670b568eSEd Maste EXPECT_EQ(0, pipe(pipefds));
394*670b568eSEd Maste int child = fork();
395*670b568eSEd Maste EXPECT_OK(child);
396*670b568eSEd Maste if (child == 0) {
397*670b568eSEd Maste close(pipefds[0]);
398*670b568eSEd Maste // Child: wait for parent to acknowledge startup
399*670b568eSEd Maste SEND_INT_MESSAGE(pipefds[1], MSG_CHILD_STARTED);
400*670b568eSEd Maste // Child: wait for two messages from the parent and the forked process
401*670b568eSEd Maste // before telling the other process to terminate.
402*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] waiting for read 1\n", getpid_());
403*670b568eSEd Maste AWAIT_INT_MESSAGE(pipefds[1], MSG_PARENT_REQUEST_CHILD_EXIT);
404*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] waiting for read 2\n", getpid_());
405*670b568eSEd Maste AWAIT_INT_MESSAGE(pipefds[1], MSG_PARENT_REQUEST_CHILD_EXIT);
406*670b568eSEd Maste TerminateChild();
407*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] about to exit\n", getpid_());
408*670b568eSEd Maste exit(testing::Test::HasFailure());
409*670b568eSEd Maste }
410*670b568eSEd Maste close(pipefds[1]);
411*670b568eSEd Maste AWAIT_INT_MESSAGE(pipefds[0], MSG_CHILD_STARTED);
412*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] got child startup message\n", getpid_());
413*670b568eSEd Maste // Fork again
414*670b568eSEd Maste int doppel = fork();
415*670b568eSEd Maste EXPECT_OK(doppel);
416*670b568eSEd Maste // We now have:
417*670b568eSEd Maste // pid A: main process, here
418*670b568eSEd Maste // |--pid B: pdfork()ed process, blocked on read()
419*670b568eSEd Maste // |--pid C: fork()ed process, in read() above
420*670b568eSEd Maste // +--pid D: doppel process, here
421*670b568eSEd Maste
422*670b568eSEd Maste // Both A and D execute the following code.
423*670b568eSEd Maste // First, check no activity on the process descriptor yet.
424*670b568eSEd Maste struct pollfd fdp;
425*670b568eSEd Maste fdp.fd = pd_;
426*670b568eSEd Maste fdp.events = POLLIN | POLLERR | POLLHUP;
427*670b568eSEd Maste fdp.revents = 0;
428*670b568eSEd Maste EXPECT_EQ(0, poll(&fdp, 1, 0));
429*670b568eSEd Maste
430*670b568eSEd Maste // Both A and D ask C to exit, allowing it to do so.
431*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] telling child to exit\n", getpid_());
432*670b568eSEd Maste SEND_INT_MESSAGE(pipefds[0], MSG_PARENT_REQUEST_CHILD_EXIT);
433*670b568eSEd Maste close(pipefds[0]);
434*670b568eSEd Maste
435*670b568eSEd Maste // Now, wait (indefinitely) for activity on the process descriptor.
436*670b568eSEd Maste // We expect:
437*670b568eSEd Maste // - pid C will finish its two read() calls, write to the pipe and exit.
438*670b568eSEd Maste // - pid B will unblock from read(), and exit
439*670b568eSEd Maste // - this will generate an event on the process descriptor...
440*670b568eSEd Maste // - ...in both process A and process D.
441*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] waiting for child to exit\n", getpid_());
442*670b568eSEd Maste EXPECT_EQ(1, poll(&fdp, 1, 2000));
443*670b568eSEd Maste EXPECT_TRUE(fdp.revents & POLLHUP);
444*670b568eSEd Maste
445*670b568eSEd Maste if (doppel == 0) {
446*670b568eSEd Maste // Child: process D exits.
447*670b568eSEd Maste exit(0);
448*670b568eSEd Maste } else {
449*670b568eSEd Maste // Parent: wait on process D.
450*670b568eSEd Maste int rc = 0;
451*670b568eSEd Maste waitpid(doppel, &rc, __WALL);
452*670b568eSEd Maste EXPECT_TRUE(WIFEXITED(rc));
453*670b568eSEd Maste EXPECT_EQ(0, WEXITSTATUS(rc));
454*670b568eSEd Maste // Also wait on process B.
455*670b568eSEd Maste CheckChildFinished(child);
456*670b568eSEd Maste }
457*670b568eSEd Maste }
458*670b568eSEd Maste
459*670b568eSEd Maste // Check that exit status/rusage for a dead pdfork()ed child can be retrieved
460*670b568eSEd Maste // via any process descriptor, multiple times.
TEST_F(PipePdfork,MultipleRetrieveExitStatus)461*670b568eSEd Maste TEST_F(PipePdfork, MultipleRetrieveExitStatus) {
462*670b568eSEd Maste EXPECT_PID_ALIVE(pid_);
463*670b568eSEd Maste int pd_copy = dup(pd_);
464*670b568eSEd Maste EXPECT_LT(0, TerminateChild());
465*670b568eSEd Maste
466*670b568eSEd Maste int status;
467*670b568eSEd Maste struct rusage ru;
468*670b568eSEd Maste memset(&ru, 0, sizeof(ru));
469*670b568eSEd Maste int waitrc = pdwait4_(pd_copy, &status, 0, &ru);
470*670b568eSEd Maste EXPECT_EQ(pid_, waitrc);
471*670b568eSEd Maste if (verbose) {
472*670b568eSEd Maste fprintf(stderr, "For pd %d -> pid %d:\n", pd_, pid_);
473*670b568eSEd Maste print_rusage(stderr, &ru);
474*670b568eSEd Maste }
475*670b568eSEd Maste EXPECT_PID_GONE(pid_);
476*670b568eSEd Maste
477*670b568eSEd Maste #ifdef NOTYET
478*670b568eSEd Maste // Child has been reaped, so original process descriptor dangles but
479*670b568eSEd Maste // still has access to rusage information.
480*670b568eSEd Maste memset(&ru, 0, sizeof(ru));
481*670b568eSEd Maste EXPECT_EQ(0, pdwait4_(pd_, &status, 0, &ru));
482*670b568eSEd Maste #endif
483*670b568eSEd Maste close(pd_copy);
484*670b568eSEd Maste }
485*670b568eSEd Maste
TEST_F(PipePdfork,ChildExit)486*670b568eSEd Maste TEST_F(PipePdfork, ChildExit) {
487*670b568eSEd Maste EXPECT_PID_ALIVE(pid_);
488*670b568eSEd Maste EXPECT_LT(0, TerminateChild());
489*670b568eSEd Maste EXPECT_PID_DEAD(pid_);
490*670b568eSEd Maste
491*670b568eSEd Maste int status;
492*670b568eSEd Maste int rc = pdwait4_(pd_, &status, 0, NULL);
493*670b568eSEd Maste EXPECT_OK(rc);
494*670b568eSEd Maste EXPECT_EQ(pid_, rc);
495*670b568eSEd Maste pid_ = 0;
496*670b568eSEd Maste }
497*670b568eSEd Maste
498*670b568eSEd Maste #ifdef HAVE_PROC_FDINFO
TEST_F(PipePdfork,FdInfo)499*670b568eSEd Maste TEST_F(PipePdfork, FdInfo) {
500*670b568eSEd Maste char buffer[1024];
501*670b568eSEd Maste sprintf(buffer, "/proc/%d/fdinfo/%d", getpid_(), pd_);
502*670b568eSEd Maste int procfd = open(buffer, O_RDONLY);
503*670b568eSEd Maste EXPECT_OK(procfd);
504*670b568eSEd Maste
505*670b568eSEd Maste EXPECT_OK(read(procfd, buffer, sizeof(buffer)));
506*670b568eSEd Maste // The fdinfo should include the file pos of the underlying file
507*670b568eSEd Maste EXPECT_NE((char*)NULL, strstr(buffer, "pos:\t0")) << buffer;
508*670b568eSEd Maste // ...and the underlying pid
509*670b568eSEd Maste char pidline[256];
510*670b568eSEd Maste sprintf(pidline, "pid:\t%d", pid_);
511*670b568eSEd Maste EXPECT_NE((char*)NULL, strstr(buffer, pidline)) << buffer;
512*670b568eSEd Maste close(procfd);
513*670b568eSEd Maste }
514*670b568eSEd Maste #endif
515*670b568eSEd Maste
516*670b568eSEd Maste // Closing a normal process descriptor terminates the underlying process.
TEST_F(PipePdfork,Close)517*670b568eSEd Maste TEST_F(PipePdfork, Close) {
518*670b568eSEd Maste sighandler_t original = signal(SIGCHLD, handle_signal);
519*670b568eSEd Maste EXPECT_PID_ALIVE(pid_);
520*670b568eSEd Maste int status;
521*670b568eSEd Maste EXPECT_EQ(0, waitpid(pid_, &status, __WALL|WNOHANG));
522*670b568eSEd Maste
523*670b568eSEd Maste EXPECT_OK(close(pd_));
524*670b568eSEd Maste pd_ = -1;
525*670b568eSEd Maste EXPECT_FALSE(had_signal[SIGCHLD]);
526*670b568eSEd Maste EXPECT_PID_DEAD(pid_);
527*670b568eSEd Maste
528*670b568eSEd Maste #ifdef __FreeBSD__
529*670b568eSEd Maste EXPECT_EQ(-1, waitpid(pid_, NULL, __WALL));
530*670b568eSEd Maste EXPECT_EQ(errno, ECHILD);
531*670b568eSEd Maste #else
532*670b568eSEd Maste // Having closed the process descriptor means that pdwait4(pd) now doesn't work.
533*670b568eSEd Maste int rc = pdwait4_(pd_, &status, 0, NULL);
534*670b568eSEd Maste EXPECT_EQ(-1, rc);
535*670b568eSEd Maste EXPECT_EQ(EBADF, errno);
536*670b568eSEd Maste
537*670b568eSEd Maste // Closing all process descriptors means the the child can only be reaped via pid.
538*670b568eSEd Maste EXPECT_EQ(pid_, waitpid(pid_, &status, __WALL|WNOHANG));
539*670b568eSEd Maste #endif
540*670b568eSEd Maste signal(SIGCHLD, original);
541*670b568eSEd Maste }
542*670b568eSEd Maste
TEST_F(PipePdfork,CloseLast)543*670b568eSEd Maste TEST_F(PipePdfork, CloseLast) {
544*670b568eSEd Maste sighandler_t original = signal(SIGCHLD, handle_signal);
545*670b568eSEd Maste // Child should only die when last process descriptor is closed.
546*670b568eSEd Maste EXPECT_PID_ALIVE(pid_);
547*670b568eSEd Maste int pd_other = dup(pd_);
548*670b568eSEd Maste
549*670b568eSEd Maste EXPECT_OK(close(pd_));
550*670b568eSEd Maste pd_ = -1;
551*670b568eSEd Maste
552*670b568eSEd Maste EXPECT_PID_ALIVE(pid_);
553*670b568eSEd Maste int status;
554*670b568eSEd Maste EXPECT_EQ(0, waitpid(pid_, &status, __WALL|WNOHANG));
555*670b568eSEd Maste
556*670b568eSEd Maste // Can no longer pdwait4() the closed process descriptor...
557*670b568eSEd Maste EXPECT_EQ(-1, pdwait4_(pd_, &status, WNOHANG, NULL));
558*670b568eSEd Maste EXPECT_EQ(EBADF, errno);
559*670b568eSEd Maste // ...but can pdwait4() the still-open process descriptor.
560*670b568eSEd Maste errno = 0;
561*670b568eSEd Maste EXPECT_EQ(0, pdwait4_(pd_other, &status, WNOHANG, NULL));
562*670b568eSEd Maste EXPECT_EQ(0, errno);
563*670b568eSEd Maste
564*670b568eSEd Maste EXPECT_OK(close(pd_other));
565*670b568eSEd Maste EXPECT_PID_DEAD(pid_);
566*670b568eSEd Maste
567*670b568eSEd Maste EXPECT_FALSE(had_signal[SIGCHLD]);
568*670b568eSEd Maste signal(SIGCHLD, original);
569*670b568eSEd Maste }
570*670b568eSEd Maste
FORK_TEST(Pdfork,OtherUserIfRoot)571*670b568eSEd Maste FORK_TEST(Pdfork, OtherUserIfRoot) {
572*670b568eSEd Maste GTEST_SKIP_IF_NOT_ROOT();
573*670b568eSEd Maste int pd;
574*670b568eSEd Maste int status;
575*670b568eSEd Maste pid_t pid = pdfork(&pd, 0);
576*670b568eSEd Maste EXPECT_OK(pid);
577*670b568eSEd Maste if (pid == 0) {
578*670b568eSEd Maste // Child process: loop forever.
579*670b568eSEd Maste while (true) usleep(100000);
580*670b568eSEd Maste }
581*670b568eSEd Maste usleep(100);
582*670b568eSEd Maste
583*670b568eSEd Maste // Now that the second process has been pdfork()ed, change euid.
584*670b568eSEd Maste ASSERT_NE(0u, other_uid) << "other_uid not initialized correctly, "
585*670b568eSEd Maste "please pass the -u <uid> flag.";
586*670b568eSEd Maste EXPECT_EQ(0, setuid(other_uid));
587*670b568eSEd Maste EXPECT_EQ(other_uid, getuid());
588*670b568eSEd Maste if (verbose) fprintf(stderr, "uid=%d euid=%d\n", getuid(), geteuid());
589*670b568eSEd Maste
590*670b568eSEd Maste // Fail to kill child with normal PID operation.
591*670b568eSEd Maste EXPECT_EQ(-1, kill(pid, SIGKILL));
592*670b568eSEd Maste EXPECT_EQ(EPERM, errno);
593*670b568eSEd Maste EXPECT_PID_ALIVE(pid);
594*670b568eSEd Maste
595*670b568eSEd Maste // Ideally, we should be able to send signals via a process descriptor even
596*670b568eSEd Maste // if it's owned by another user, but this is not implementated on FreeBSD.
597*670b568eSEd Maste #ifdef __FreeBSD__
598*670b568eSEd Maste // On FreeBSD, pdkill() still performs all the same checks that kill() does
599*670b568eSEd Maste // and therefore cannot be used to send a signal to a process with another
600*670b568eSEd Maste // UID unless we are root.
601*670b568eSEd Maste EXPECT_SYSCALL_FAIL(EBADF, pdkill(pid, SIGKILL));
602*670b568eSEd Maste EXPECT_PID_ALIVE(pid);
603*670b568eSEd Maste // However, the process will be killed when we close the process descriptor.
604*670b568eSEd Maste EXPECT_OK(close(pd));
605*670b568eSEd Maste EXPECT_PID_GONE(pid);
606*670b568eSEd Maste // Can't pdwait4() after close() since close() reparents the child to a reaper (init)
607*670b568eSEd Maste EXPECT_SYSCALL_FAIL(EBADF, pdwait4_(pd, &status, WNOHANG, NULL));
608*670b568eSEd Maste #else
609*670b568eSEd Maste // Sending a signal with pdkill() should be permitted though.
610*670b568eSEd Maste EXPECT_OK(pdkill(pd, SIGKILL));
611*670b568eSEd Maste EXPECT_PID_ZOMBIE(pid);
612*670b568eSEd Maste
613*670b568eSEd Maste int rc = pdwait4_(pd, &status, WNOHANG, NULL);
614*670b568eSEd Maste EXPECT_OK(rc);
615*670b568eSEd Maste EXPECT_EQ(pid, rc);
616*670b568eSEd Maste EXPECT_TRUE(WIFSIGNALED(status));
617*670b568eSEd Maste #endif
618*670b568eSEd Maste }
619*670b568eSEd Maste
TEST_F(PipePdfork,WaitPidThenPd)620*670b568eSEd Maste TEST_F(PipePdfork, WaitPidThenPd) {
621*670b568eSEd Maste TerminateChild();
622*670b568eSEd Maste int status;
623*670b568eSEd Maste // If we waitpid(pid) first...
624*670b568eSEd Maste int rc = waitpid(pid_, &status, __WALL);
625*670b568eSEd Maste EXPECT_OK(rc);
626*670b568eSEd Maste EXPECT_EQ(pid_, rc);
627*670b568eSEd Maste
628*670b568eSEd Maste #ifdef NOTYET
629*670b568eSEd Maste // ...the zombie is reaped but we can still subsequently pdwait4(pd).
630*670b568eSEd Maste EXPECT_EQ(0, pdwait4_(pd_, &status, 0, NULL));
631*670b568eSEd Maste #endif
632*670b568eSEd Maste }
633*670b568eSEd Maste
TEST_F(PipePdfork,WaitPdThenPid)634*670b568eSEd Maste TEST_F(PipePdfork, WaitPdThenPid) {
635*670b568eSEd Maste TerminateChild();
636*670b568eSEd Maste int status;
637*670b568eSEd Maste // If we pdwait4(pd) first...
638*670b568eSEd Maste int rc = pdwait4_(pd_, &status, 0, NULL);
639*670b568eSEd Maste EXPECT_OK(rc);
640*670b568eSEd Maste EXPECT_EQ(pid_, rc);
641*670b568eSEd Maste
642*670b568eSEd Maste // ...the zombie is reaped and cannot subsequently waitpid(pid).
643*670b568eSEd Maste EXPECT_EQ(-1, waitpid(pid_, &status, __WALL));
644*670b568eSEd Maste EXPECT_EQ(ECHILD, errno);
645*670b568eSEd Maste }
646*670b568eSEd Maste
647*670b568eSEd Maste // Setting PD_DAEMON prevents close() from killing the child.
TEST_F(PipePdforkDaemon,Close)648*670b568eSEd Maste TEST_F(PipePdforkDaemon, Close) {
649*670b568eSEd Maste EXPECT_OK(close(pd_));
650*670b568eSEd Maste pd_ = -1;
651*670b568eSEd Maste EXPECT_PID_ALIVE(pid_);
652*670b568eSEd Maste
653*670b568eSEd Maste // Can still explicitly kill it via the pid.
654*670b568eSEd Maste if (pid_ > 0) {
655*670b568eSEd Maste EXPECT_OK(kill(pid_, SIGKILL));
656*670b568eSEd Maste EXPECT_PID_DEAD(pid_);
657*670b568eSEd Maste }
658*670b568eSEd Maste }
659*670b568eSEd Maste
TestPdkill(pid_t pid,int pd)660*670b568eSEd Maste static void TestPdkill(pid_t pid, int pd) {
661*670b568eSEd Maste EXPECT_PID_ALIVE(pid);
662*670b568eSEd Maste // SIGCONT is ignored by default.
663*670b568eSEd Maste EXPECT_OK(pdkill(pd, SIGCONT));
664*670b568eSEd Maste EXPECT_PID_ALIVE(pid);
665*670b568eSEd Maste
666*670b568eSEd Maste // SIGINT isn't
667*670b568eSEd Maste EXPECT_OK(pdkill(pd, SIGINT));
668*670b568eSEd Maste EXPECT_PID_DEAD(pid);
669*670b568eSEd Maste
670*670b568eSEd Maste // pdkill() on zombie is no-op.
671*670b568eSEd Maste errno = 0;
672*670b568eSEd Maste EXPECT_EQ(0, pdkill(pd, SIGINT));
673*670b568eSEd Maste EXPECT_EQ(0, errno);
674*670b568eSEd Maste
675*670b568eSEd Maste // pdkill() on reaped process gives -ESRCH.
676*670b568eSEd Maste CheckChildFinished(pid, true);
677*670b568eSEd Maste EXPECT_EQ(-1, pdkill(pd, SIGINT));
678*670b568eSEd Maste EXPECT_EQ(ESRCH, errno);
679*670b568eSEd Maste }
680*670b568eSEd Maste
TEST_F(PipePdfork,Pdkill)681*670b568eSEd Maste TEST_F(PipePdfork, Pdkill) {
682*670b568eSEd Maste TestPdkill(pid_, pd_);
683*670b568eSEd Maste }
684*670b568eSEd Maste
TEST_F(PipePdforkDaemon,Pdkill)685*670b568eSEd Maste TEST_F(PipePdforkDaemon, Pdkill) {
686*670b568eSEd Maste TestPdkill(pid_, pd_);
687*670b568eSEd Maste }
688*670b568eSEd Maste
TEST(Pdfork,PdkillOtherSignal)689*670b568eSEd Maste TEST(Pdfork, PdkillOtherSignal) {
690*670b568eSEd Maste int pd = -1;
691*670b568eSEd Maste int pipefds[2];
692*670b568eSEd Maste EXPECT_EQ(0, pipe(pipefds));
693*670b568eSEd Maste int pid = pdfork(&pd, 0);
694*670b568eSEd Maste EXPECT_OK(pid);
695*670b568eSEd Maste if (pid == 0) {
696*670b568eSEd Maste // Child: tell the parent that we have started before entering the loop,
697*670b568eSEd Maste // and importantly only do so once we have registered the SIGUSR1 handler.
698*670b568eSEd Maste close(pipefds[0]);
699*670b568eSEd Maste clear_had_signals();
700*670b568eSEd Maste signal(SIGUSR1, handle_signal);
701*670b568eSEd Maste SEND_INT_MESSAGE(pipefds[1], MSG_CHILD_STARTED);
702*670b568eSEd Maste // Child: watch for SIGUSR1 forever.
703*670b568eSEd Maste while (!had_signal[SIGUSR1]) {
704*670b568eSEd Maste usleep(100000);
705*670b568eSEd Maste }
706*670b568eSEd Maste exit(123);
707*670b568eSEd Maste }
708*670b568eSEd Maste // Wait for child to start
709*670b568eSEd Maste close(pipefds[1]);
710*670b568eSEd Maste AWAIT_INT_MESSAGE(pipefds[0], MSG_CHILD_STARTED);
711*670b568eSEd Maste close(pipefds[0]);
712*670b568eSEd Maste
713*670b568eSEd Maste // Send an invalid signal.
714*670b568eSEd Maste EXPECT_EQ(-1, pdkill(pd, 0xFFFF));
715*670b568eSEd Maste EXPECT_EQ(EINVAL, errno);
716*670b568eSEd Maste
717*670b568eSEd Maste // Send an expected SIGUSR1 to the pdfork()ed child.
718*670b568eSEd Maste EXPECT_PID_ALIVE(pid);
719*670b568eSEd Maste pdkill(pd, SIGUSR1);
720*670b568eSEd Maste EXPECT_PID_DEAD(pid);
721*670b568eSEd Maste
722*670b568eSEd Maste // Child's exit status confirms whether it received the signal.
723*670b568eSEd Maste int status;
724*670b568eSEd Maste int rc = waitpid(pid, &status, __WALL);
725*670b568eSEd Maste EXPECT_OK(rc);
726*670b568eSEd Maste EXPECT_EQ(pid, rc);
727*670b568eSEd Maste EXPECT_TRUE(WIFEXITED(status)) << "status: 0x" << std::hex << status;
728*670b568eSEd Maste EXPECT_EQ(123, WEXITSTATUS(status));
729*670b568eSEd Maste }
730*670b568eSEd Maste
PdforkParentDeath(int pdfork_flags)731*670b568eSEd Maste pid_t PdforkParentDeath(int pdfork_flags) {
732*670b568eSEd Maste // Set up:
733*670b568eSEd Maste // pid A: main process, here
734*670b568eSEd Maste // +--pid B: fork()ed process, starts a child process with pdfork() then
735*670b568eSEd Maste // waits for parent to send a shutdown message.
736*670b568eSEd Maste // +--pid C: pdfork()ed process, looping forever
737*670b568eSEd Maste int sock_fds[2];
738*670b568eSEd Maste EXPECT_OK(socketpair(AF_UNIX, SOCK_STREAM, 0, sock_fds));
739*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] parent about to fork()...\n", getpid_());
740*670b568eSEd Maste pid_t child = fork();
741*670b568eSEd Maste EXPECT_OK(child);
742*670b568eSEd Maste if (child == 0) {
743*670b568eSEd Maste int pd;
744*670b568eSEd Maste if (verbose) fprintf(stderr, " [%d] child about to pdfork()...\n", getpid_());
745*670b568eSEd Maste int pipefds[2]; // for startup notification
746*670b568eSEd Maste EXPECT_OK(pipe(pipefds));
747*670b568eSEd Maste pid_t grandchild = pdfork(&pd, pdfork_flags);
748*670b568eSEd Maste if (grandchild == 0) {
749*670b568eSEd Maste close(pipefds[0]);
750*670b568eSEd Maste pid_t grandchildPid = getpid_();
751*670b568eSEd Maste EXPECT_EQ(sizeof(grandchildPid), (size_t)write(pipefds[1], &grandchildPid, sizeof(grandchildPid)));
752*670b568eSEd Maste while (true) {
753*670b568eSEd Maste if (verbose) fprintf(stderr, " [%d] grandchild: \"I aten't dead\"\n", grandchildPid);
754*670b568eSEd Maste sleep(1);
755*670b568eSEd Maste }
756*670b568eSEd Maste }
757*670b568eSEd Maste close(pipefds[1]);
758*670b568eSEd Maste if (verbose) fprintf(stderr, " [%d] pdfork()ed grandchild %d, sending ID to parent\n", getpid_(), grandchild);
759*670b568eSEd Maste // Wait for grandchild to start.
760*670b568eSEd Maste pid_t grandchild2;
761*670b568eSEd Maste EXPECT_EQ(sizeof(grandchild2), (size_t)read(pipefds[0], &grandchild2, sizeof(grandchild2)));
762*670b568eSEd Maste EXPECT_EQ(grandchild, grandchild2) << "received invalid grandchild pid";
763*670b568eSEd Maste if (verbose) fprintf(stderr, " [%d] grandchild %d has started successfully\n", getpid_(), grandchild);
764*670b568eSEd Maste close(pipefds[0]);
765*670b568eSEd Maste
766*670b568eSEd Maste // Send grandchild pid to parent.
767*670b568eSEd Maste EXPECT_EQ(sizeof(grandchild), (size_t)write(sock_fds[1], &grandchild, sizeof(grandchild)));
768*670b568eSEd Maste if (verbose) fprintf(stderr, " [%d] sent grandchild pid %d to parent\n", getpid_(), grandchild);
769*670b568eSEd Maste // Wait for parent to acknowledge the message.
770*670b568eSEd Maste AWAIT_INT_MESSAGE(sock_fds[1], MSG_PARENT_REQUEST_CHILD_EXIT);
771*670b568eSEd Maste if (verbose) fprintf(stderr, " [%d] parent acknowledged grandchild pid %d\n", getpid_(), grandchild);
772*670b568eSEd Maste if (verbose) fprintf(stderr, " [%d] child terminating\n", getpid_());
773*670b568eSEd Maste exit(testing::Test::HasFailure());
774*670b568eSEd Maste }
775*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] fork()ed child is %d\n", getpid_(), child);
776*670b568eSEd Maste pid_t grandchild;
777*670b568eSEd Maste read(sock_fds[0], &grandchild, sizeof(grandchild));
778*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] received grandchild id %d\n", getpid_(), grandchild);
779*670b568eSEd Maste EXPECT_PID_ALIVE(child);
780*670b568eSEd Maste EXPECT_PID_ALIVE(grandchild);
781*670b568eSEd Maste // Tell child to exit.
782*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] telling child %d to exit\n", getpid_(), child);
783*670b568eSEd Maste SEND_INT_MESSAGE(sock_fds[0], MSG_PARENT_REQUEST_CHILD_EXIT);
784*670b568eSEd Maste // Child dies, closing its process descriptor for the grandchild.
785*670b568eSEd Maste EXPECT_PID_DEAD(child);
786*670b568eSEd Maste CheckChildFinished(child);
787*670b568eSEd Maste return grandchild;
788*670b568eSEd Maste }
789*670b568eSEd Maste
TEST(Pdfork,Bagpuss)790*670b568eSEd Maste TEST(Pdfork, Bagpuss) {
791*670b568eSEd Maste // "And of course when Bagpuss goes to sleep, all his friends go to sleep too"
792*670b568eSEd Maste pid_t grandchild = PdforkParentDeath(0);
793*670b568eSEd Maste // By default: child death => closed process descriptor => grandchild death.
794*670b568eSEd Maste EXPECT_PID_DEAD(grandchild);
795*670b568eSEd Maste }
796*670b568eSEd Maste
TEST(Pdfork,BagpussDaemon)797*670b568eSEd Maste TEST(Pdfork, BagpussDaemon) {
798*670b568eSEd Maste pid_t grandchild = PdforkParentDeath(PD_DAEMON);
799*670b568eSEd Maste // With PD_DAEMON: child death => closed process descriptor => no effect on grandchild.
800*670b568eSEd Maste EXPECT_PID_ALIVE(grandchild);
801*670b568eSEd Maste if (grandchild > 0) {
802*670b568eSEd Maste EXPECT_OK(kill(grandchild, SIGKILL));
803*670b568eSEd Maste }
804*670b568eSEd Maste }
805*670b568eSEd Maste
806*670b568eSEd Maste // The exit of a pdfork()ed process should not generate SIGCHLD.
TEST_F(PipePdfork,NoSigchld)807*670b568eSEd Maste TEST_F(PipePdfork, NoSigchld) {
808*670b568eSEd Maste clear_had_signals();
809*670b568eSEd Maste sighandler_t original = signal(SIGCHLD, handle_signal);
810*670b568eSEd Maste TerminateChild();
811*670b568eSEd Maste int rc = 0;
812*670b568eSEd Maste // Can waitpid() for the specific pid of the pdfork()ed child.
813*670b568eSEd Maste EXPECT_EQ(pid_, waitpid(pid_, &rc, __WALL));
814*670b568eSEd Maste EXPECT_TRUE(WIFEXITED(rc)) << "0x" << std::hex << rc;
815*670b568eSEd Maste EXPECT_FALSE(had_signal[SIGCHLD]);
816*670b568eSEd Maste signal(SIGCHLD, original);
817*670b568eSEd Maste }
818*670b568eSEd Maste
819*670b568eSEd Maste // The exit of a pdfork()ed process whose process descriptors have
820*670b568eSEd Maste // all been closed should generate SIGCHLD. The child process needs
821*670b568eSEd Maste // PD_DAEMON to survive the closure of the process descriptors.
TEST_F(PipePdforkDaemon,NoPDSigchld)822*670b568eSEd Maste TEST_F(PipePdforkDaemon, NoPDSigchld) {
823*670b568eSEd Maste clear_had_signals();
824*670b568eSEd Maste sighandler_t original = signal(SIGCHLD, handle_signal);
825*670b568eSEd Maste
826*670b568eSEd Maste EXPECT_OK(close(pd_));
827*670b568eSEd Maste TerminateChild();
828*670b568eSEd Maste #ifdef __FreeBSD__
829*670b568eSEd Maste EXPECT_EQ(-1, waitpid(pid_, NULL, __WALL));
830*670b568eSEd Maste EXPECT_EQ(errno, ECHILD);
831*670b568eSEd Maste #else
832*670b568eSEd Maste int rc = 0;
833*670b568eSEd Maste // Can waitpid() for the specific pid of the pdfork()ed child.
834*670b568eSEd Maste EXPECT_EQ(pid_, waitpid(pid_, &rc, __WALL));
835*670b568eSEd Maste EXPECT_TRUE(WIFEXITED(rc)) << "0x" << std::hex << rc;
836*670b568eSEd Maste #endif
837*670b568eSEd Maste EXPECT_FALSE(had_signal[SIGCHLD]);
838*670b568eSEd Maste signal(SIGCHLD, original);
839*670b568eSEd Maste }
840*670b568eSEd Maste
841*670b568eSEd Maste #ifdef HAVE_PROCDESC_FSTAT
TEST_F(PipePdfork,ModeBits)842*670b568eSEd Maste TEST_F(PipePdfork, ModeBits) {
843*670b568eSEd Maste // Owner rwx bits indicate liveness of child
844*670b568eSEd Maste struct stat stat;
845*670b568eSEd Maste memset(&stat, 0, sizeof(stat));
846*670b568eSEd Maste EXPECT_OK(fstat(pd_, &stat));
847*670b568eSEd Maste if (verbose) print_stat(stderr, &stat);
848*670b568eSEd Maste EXPECT_EQ(S_IRWXU, (long)(stat.st_mode & S_IRWXU));
849*670b568eSEd Maste
850*670b568eSEd Maste TerminateChild();
851*670b568eSEd Maste usleep(100000);
852*670b568eSEd Maste
853*670b568eSEd Maste memset(&stat, 0, sizeof(stat));
854*670b568eSEd Maste EXPECT_OK(fstat(pd_, &stat));
855*670b568eSEd Maste if (verbose) print_stat(stderr, &stat);
856*670b568eSEd Maste EXPECT_EQ(0, (int)(stat.st_mode & S_IRWXU));
857*670b568eSEd Maste }
858*670b568eSEd Maste #endif
859*670b568eSEd Maste
TEST_F(PipePdfork,WildcardWait)860*670b568eSEd Maste TEST_F(PipePdfork, WildcardWait) {
861*670b568eSEd Maste TerminateChild();
862*670b568eSEd Maste EXPECT_PID_ZOMBIE(pid_); // Ensure child is truly dead.
863*670b568eSEd Maste
864*670b568eSEd Maste // Wildcard waitpid(-1) should not see the pdfork()ed child because
865*670b568eSEd Maste // there is still a process descriptor for it.
866*670b568eSEd Maste int rc;
867*670b568eSEd Maste EXPECT_EQ(-1, waitpid(-1, &rc, WNOHANG));
868*670b568eSEd Maste EXPECT_EQ(ECHILD, errno);
869*670b568eSEd Maste
870*670b568eSEd Maste EXPECT_OK(close(pd_));
871*670b568eSEd Maste pd_ = -1;
872*670b568eSEd Maste }
873*670b568eSEd Maste
FORK_TEST(Pdfork,Pdkill)874*670b568eSEd Maste FORK_TEST(Pdfork, Pdkill) {
875*670b568eSEd Maste clear_had_signals();
876*670b568eSEd Maste int pd;
877*670b568eSEd Maste int pipefds[2];
878*670b568eSEd Maste EXPECT_OK(pipe(pipefds));
879*670b568eSEd Maste pid_t pid = pdfork(&pd, 0);
880*670b568eSEd Maste EXPECT_OK(pid);
881*670b568eSEd Maste
882*670b568eSEd Maste if (pid == 0) {
883*670b568eSEd Maste // Child: set a SIGINT handler, notify the parent and sleep.
884*670b568eSEd Maste close(pipefds[0]);
885*670b568eSEd Maste clear_had_signals();
886*670b568eSEd Maste signal(SIGINT, handle_signal);
887*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] child started\n", getpid_());
888*670b568eSEd Maste SEND_INT_MESSAGE(pipefds[1], MSG_CHILD_STARTED);
889*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] child about to sleep(10)\n", getpid_());
890*670b568eSEd Maste // Note: we could receive the SIGINT just before sleep(), so we use a loop
891*670b568eSEd Maste // with a short delay instead of one long sleep().
892*670b568eSEd Maste for (int i = 0; i < 50 && !had_signal[SIGINT]; i++) {
893*670b568eSEd Maste usleep(100000);
894*670b568eSEd Maste }
895*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] child slept, had[SIGINT]=%d\n",
896*670b568eSEd Maste getpid_(), (int)had_signal[SIGINT]);
897*670b568eSEd Maste // Return non-zero if we didn't see SIGINT.
898*670b568eSEd Maste exit(had_signal[SIGINT] ? 0 : 99);
899*670b568eSEd Maste }
900*670b568eSEd Maste
901*670b568eSEd Maste // Parent: get child's PID.
902*670b568eSEd Maste pid_t pd_pid;
903*670b568eSEd Maste EXPECT_OK(pdgetpid(pd, &pd_pid));
904*670b568eSEd Maste EXPECT_EQ(pid, pd_pid);
905*670b568eSEd Maste
906*670b568eSEd Maste // Interrupt the child once it's registered the SIGINT handler.
907*670b568eSEd Maste close(pipefds[1]);
908*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] waiting for child\n", getpid_());
909*670b568eSEd Maste AWAIT_INT_MESSAGE(pipefds[0], MSG_CHILD_STARTED);
910*670b568eSEd Maste EXPECT_OK(pdkill(pd, SIGINT));
911*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] sent SIGINT\n", getpid_());
912*670b568eSEd Maste
913*670b568eSEd Maste // Make sure the child finished properly (caught signal then exited).
914*670b568eSEd Maste CheckChildFinished(pid);
915*670b568eSEd Maste }
916*670b568eSEd Maste
FORK_TEST(Pdfork,PdkillSignal)917*670b568eSEd Maste FORK_TEST(Pdfork, PdkillSignal) {
918*670b568eSEd Maste int pd;
919*670b568eSEd Maste int pipefds[2];
920*670b568eSEd Maste EXPECT_OK(pipe(pipefds));
921*670b568eSEd Maste pid_t pid = pdfork(&pd, 0);
922*670b568eSEd Maste EXPECT_OK(pid);
923*670b568eSEd Maste
924*670b568eSEd Maste if (pid == 0) {
925*670b568eSEd Maste close(pipefds[0]);
926*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] child started\n", getpid_());
927*670b568eSEd Maste SEND_INT_MESSAGE(pipefds[1], MSG_CHILD_STARTED);
928*670b568eSEd Maste // Child: wait for shutdown message. No SIGINT handler. The message should
929*670b568eSEd Maste // never be received, since SIGINT should terminate the process.
930*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] child about to read()\n", getpid_());
931*670b568eSEd Maste AWAIT_INT_MESSAGE(pipefds[1], MSG_PARENT_REQUEST_CHILD_EXIT);
932*670b568eSEd Maste fprintf(stderr, "[%d] child read() returned unexpectedly\n", getpid_());
933*670b568eSEd Maste exit(99);
934*670b568eSEd Maste }
935*670b568eSEd Maste // Wait for child to start before signalling.
936*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] waiting for child\n", getpid_());
937*670b568eSEd Maste close(pipefds[1]);
938*670b568eSEd Maste AWAIT_INT_MESSAGE(pipefds[0], MSG_CHILD_STARTED);
939*670b568eSEd Maste // Kill the child (as it doesn't handle SIGINT).
940*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] sending SIGINT\n", getpid_());
941*670b568eSEd Maste EXPECT_OK(pdkill(pd, SIGINT));
942*670b568eSEd Maste
943*670b568eSEd Maste // Make sure the child finished properly (terminated by signal).
944*670b568eSEd Maste CheckChildFinished(pid, true);
945*670b568eSEd Maste }
946*670b568eSEd Maste
947*670b568eSEd Maste //------------------------------------------------
948*670b568eSEd Maste // Test interactions with other parts of Capsicum:
949*670b568eSEd Maste // - capability mode
950*670b568eSEd Maste // - capabilities
951*670b568eSEd Maste
FORK_TEST(Pdfork,DaemonUnrestricted)952*670b568eSEd Maste FORK_TEST(Pdfork, DaemonUnrestricted) {
953*670b568eSEd Maste EXPECT_OK(cap_enter());
954*670b568eSEd Maste int fd;
955*670b568eSEd Maste
956*670b568eSEd Maste // Capability mode leaves pdfork() available, with and without flag.
957*670b568eSEd Maste int rc;
958*670b568eSEd Maste rc = pdfork(&fd, PD_DAEMON);
959*670b568eSEd Maste EXPECT_OK(rc);
960*670b568eSEd Maste if (rc == 0) {
961*670b568eSEd Maste // Child: immediately terminate.
962*670b568eSEd Maste exit(0);
963*670b568eSEd Maste }
964*670b568eSEd Maste
965*670b568eSEd Maste rc = pdfork(&fd, 0);
966*670b568eSEd Maste EXPECT_OK(rc);
967*670b568eSEd Maste if (rc == 0) {
968*670b568eSEd Maste // Child: immediately terminate.
969*670b568eSEd Maste exit(0);
970*670b568eSEd Maste }
971*670b568eSEd Maste }
972*670b568eSEd Maste
TEST(Pdfork,MissingRights)973*670b568eSEd Maste TEST(Pdfork, MissingRights) {
974*670b568eSEd Maste pid_t parent = getpid_();
975*670b568eSEd Maste int pd = -1;
976*670b568eSEd Maste pid_t pid = pdfork(&pd, 0);
977*670b568eSEd Maste EXPECT_OK(pid);
978*670b568eSEd Maste if (pid == 0) {
979*670b568eSEd Maste // Child: loop forever.
980*670b568eSEd Maste EXPECT_NE(parent, getpid_());
981*670b568eSEd Maste while (true) sleep(1);
982*670b568eSEd Maste }
983*670b568eSEd Maste // Create two capabilities from the process descriptor.
984*670b568eSEd Maste cap_rights_t r_ro;
985*670b568eSEd Maste cap_rights_init(&r_ro, CAP_READ, CAP_LOOKUP);
986*670b568eSEd Maste int cap_incapable = dup(pd);
987*670b568eSEd Maste EXPECT_OK(cap_incapable);
988*670b568eSEd Maste EXPECT_OK(cap_rights_limit(cap_incapable, &r_ro));
989*670b568eSEd Maste cap_rights_t r_pdall;
990*670b568eSEd Maste cap_rights_init(&r_pdall, CAP_PDGETPID, CAP_PDWAIT, CAP_PDKILL);
991*670b568eSEd Maste int cap_capable = dup(pd);
992*670b568eSEd Maste EXPECT_OK(cap_capable);
993*670b568eSEd Maste EXPECT_OK(cap_rights_limit(cap_capable, &r_pdall));
994*670b568eSEd Maste
995*670b568eSEd Maste pid_t other_pid;
996*670b568eSEd Maste EXPECT_NOTCAPABLE(pdgetpid(cap_incapable, &other_pid));
997*670b568eSEd Maste EXPECT_NOTCAPABLE(pdkill(cap_incapable, SIGINT));
998*670b568eSEd Maste int status;
999*670b568eSEd Maste EXPECT_NOTCAPABLE(pdwait4_(cap_incapable, &status, 0, NULL));
1000*670b568eSEd Maste
1001*670b568eSEd Maste EXPECT_OK(pdgetpid(cap_capable, &other_pid));
1002*670b568eSEd Maste EXPECT_EQ(pid, other_pid);
1003*670b568eSEd Maste EXPECT_OK(pdkill(cap_capable, SIGINT));
1004*670b568eSEd Maste int rc = pdwait4_(pd, &status, 0, NULL);
1005*670b568eSEd Maste EXPECT_OK(rc);
1006*670b568eSEd Maste EXPECT_EQ(pid, rc);
1007*670b568eSEd Maste }
1008*670b568eSEd Maste
1009*670b568eSEd Maste
1010*670b568eSEd Maste //------------------------------------------------
1011*670b568eSEd Maste // Passing process descriptors between processes.
1012*670b568eSEd Maste
TEST_F(PipePdfork,PassProcessDescriptor)1013*670b568eSEd Maste TEST_F(PipePdfork, PassProcessDescriptor) {
1014*670b568eSEd Maste int sock_fds[2];
1015*670b568eSEd Maste EXPECT_OK(socketpair(AF_UNIX, SOCK_STREAM, 0, sock_fds));
1016*670b568eSEd Maste
1017*670b568eSEd Maste struct msghdr mh;
1018*670b568eSEd Maste mh.msg_name = NULL; // No address needed
1019*670b568eSEd Maste mh.msg_namelen = 0;
1020*670b568eSEd Maste char buffer1[1024];
1021*670b568eSEd Maste struct iovec iov[1];
1022*670b568eSEd Maste iov[0].iov_base = buffer1;
1023*670b568eSEd Maste iov[0].iov_len = sizeof(buffer1);
1024*670b568eSEd Maste mh.msg_iov = iov;
1025*670b568eSEd Maste mh.msg_iovlen = 1;
1026*670b568eSEd Maste char buffer2[1024];
1027*670b568eSEd Maste mh.msg_control = buffer2;
1028*670b568eSEd Maste mh.msg_controllen = sizeof(buffer2);
1029*670b568eSEd Maste struct cmsghdr *cmptr;
1030*670b568eSEd Maste
1031*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] about to fork()\n", getpid_());
1032*670b568eSEd Maste pid_t child2 = fork();
1033*670b568eSEd Maste if (child2 == 0) {
1034*670b568eSEd Maste // Child: close our copy of the original process descriptor.
1035*670b568eSEd Maste close(pd_);
1036*670b568eSEd Maste SEND_INT_MESSAGE(sock_fds[0], MSG_CHILD_STARTED);
1037*670b568eSEd Maste // Child: wait to receive process descriptor over socket
1038*670b568eSEd Maste if (verbose) fprintf(stderr, " [%d] child of %d waiting for process descriptor on socket\n", getpid_(), getppid());
1039*670b568eSEd Maste int rc = recvmsg(sock_fds[0], &mh, 0);
1040*670b568eSEd Maste EXPECT_OK(rc);
1041*670b568eSEd Maste EXPECT_LE(CMSG_LEN(sizeof(int)), mh.msg_controllen);
1042*670b568eSEd Maste cmptr = CMSG_FIRSTHDR(&mh);
1043*670b568eSEd Maste int pd = *(int*)CMSG_DATA(cmptr);
1044*670b568eSEd Maste EXPECT_EQ(CMSG_LEN(sizeof(int)), cmptr->cmsg_len);
1045*670b568eSEd Maste cmptr = CMSG_NXTHDR(&mh, cmptr);
1046*670b568eSEd Maste EXPECT_TRUE(cmptr == NULL);
1047*670b568eSEd Maste if (verbose) fprintf(stderr, " [%d] got process descriptor %d on socket\n", getpid_(), pd);
1048*670b568eSEd Maste SEND_INT_MESSAGE(sock_fds[0], MSG_CHILD_FD_RECEIVED);
1049*670b568eSEd Maste
1050*670b568eSEd Maste // Child: confirm we can do pd*() operations on the process descriptor
1051*670b568eSEd Maste pid_t other;
1052*670b568eSEd Maste EXPECT_OK(pdgetpid(pd, &other));
1053*670b568eSEd Maste if (verbose) fprintf(stderr, " [%d] process descriptor %d is pid %d\n", getpid_(), pd, other);
1054*670b568eSEd Maste
1055*670b568eSEd Maste // Wait until the parent has closed the process descriptor.
1056*670b568eSEd Maste AWAIT_INT_MESSAGE(sock_fds[0], MSG_PARENT_CLOSED_FD);
1057*670b568eSEd Maste
1058*670b568eSEd Maste if (verbose) fprintf(stderr, " [%d] close process descriptor %d\n", getpid_(), pd);
1059*670b568eSEd Maste close(pd);
1060*670b568eSEd Maste
1061*670b568eSEd Maste // Last process descriptor closed, expect death
1062*670b568eSEd Maste EXPECT_PID_DEAD(other);
1063*670b568eSEd Maste
1064*670b568eSEd Maste exit(HasFailure());
1065*670b568eSEd Maste }
1066*670b568eSEd Maste // Wait until the child has started.
1067*670b568eSEd Maste AWAIT_INT_MESSAGE(sock_fds[1], MSG_CHILD_STARTED);
1068*670b568eSEd Maste
1069*670b568eSEd Maste // Send the process descriptor over the pipe to the sub-process
1070*670b568eSEd Maste mh.msg_controllen = CMSG_LEN(sizeof(int));
1071*670b568eSEd Maste cmptr = CMSG_FIRSTHDR(&mh);
1072*670b568eSEd Maste cmptr->cmsg_level = SOL_SOCKET;
1073*670b568eSEd Maste cmptr->cmsg_type = SCM_RIGHTS;
1074*670b568eSEd Maste cmptr->cmsg_len = CMSG_LEN(sizeof(int));
1075*670b568eSEd Maste *(int *)CMSG_DATA(cmptr) = pd_;
1076*670b568eSEd Maste buffer1[0] = 0;
1077*670b568eSEd Maste iov[0].iov_len = 1;
1078*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] send process descriptor %d on socket\n", getpid_(), pd_);
1079*670b568eSEd Maste int rc = sendmsg(sock_fds[1], &mh, 0);
1080*670b568eSEd Maste EXPECT_OK(rc);
1081*670b568eSEd Maste // Wait until the child has received the process descriptor.
1082*670b568eSEd Maste AWAIT_INT_MESSAGE(sock_fds[1], MSG_CHILD_FD_RECEIVED);
1083*670b568eSEd Maste
1084*670b568eSEd Maste if (verbose) fprintf(stderr, "[%d] close process descriptor %d\n", getpid_(), pd_);
1085*670b568eSEd Maste close(pd_); // Not last open process descriptor
1086*670b568eSEd Maste SEND_INT_MESSAGE(sock_fds[1], MSG_PARENT_CLOSED_FD);
1087*670b568eSEd Maste
1088*670b568eSEd Maste // wait for child2
1089*670b568eSEd Maste int status;
1090*670b568eSEd Maste EXPECT_EQ(child2, waitpid(child2, &status, __WALL));
1091*670b568eSEd Maste rc = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
1092*670b568eSEd Maste EXPECT_EQ(0, rc);
1093*670b568eSEd Maste
1094*670b568eSEd Maste // confirm death all round
1095*670b568eSEd Maste EXPECT_PID_DEAD(child2);
1096*670b568eSEd Maste EXPECT_PID_DEAD(pid_);
1097*670b568eSEd Maste }
1098