1*c243e490SMarcel Moolenaar /* 2*c243e490SMarcel Moolenaar * Automated Testing Framework (atf) 3*c243e490SMarcel Moolenaar * 4*c243e490SMarcel Moolenaar * Copyright (c) 2008 The NetBSD Foundation, Inc. 5*c243e490SMarcel Moolenaar * All rights reserved. 6*c243e490SMarcel Moolenaar * 7*c243e490SMarcel Moolenaar * Redistribution and use in source and binary forms, with or without 8*c243e490SMarcel Moolenaar * modification, are permitted provided that the following conditions 9*c243e490SMarcel Moolenaar * are met: 10*c243e490SMarcel Moolenaar * 1. Redistributions of source code must retain the above copyright 11*c243e490SMarcel Moolenaar * notice, this list of conditions and the following disclaimer. 12*c243e490SMarcel Moolenaar * 2. Redistributions in binary form must reproduce the above copyright 13*c243e490SMarcel Moolenaar * notice, this list of conditions and the following disclaimer in the 14*c243e490SMarcel Moolenaar * documentation and/or other materials provided with the distribution. 15*c243e490SMarcel Moolenaar * 16*c243e490SMarcel Moolenaar * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17*c243e490SMarcel Moolenaar * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18*c243e490SMarcel Moolenaar * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19*c243e490SMarcel Moolenaar * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20*c243e490SMarcel Moolenaar * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21*c243e490SMarcel Moolenaar * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*c243e490SMarcel Moolenaar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23*c243e490SMarcel Moolenaar * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24*c243e490SMarcel Moolenaar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25*c243e490SMarcel Moolenaar * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26*c243e490SMarcel Moolenaar * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27*c243e490SMarcel Moolenaar * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28*c243e490SMarcel Moolenaar */ 29*c243e490SMarcel Moolenaar 30*c243e490SMarcel Moolenaar #include <sys/types.h> 31*c243e490SMarcel Moolenaar #include <sys/time.h> 32*c243e490SMarcel Moolenaar #include <sys/resource.h> 33*c243e490SMarcel Moolenaar #include <sys/wait.h> 34*c243e490SMarcel Moolenaar 35*c243e490SMarcel Moolenaar #include <errno.h> 36*c243e490SMarcel Moolenaar #include <fcntl.h> 37*c243e490SMarcel Moolenaar #include <signal.h> 38*c243e490SMarcel Moolenaar #include <stdio.h> 39*c243e490SMarcel Moolenaar #include <stdlib.h> 40*c243e490SMarcel Moolenaar #include <string.h> 41*c243e490SMarcel Moolenaar #include <unistd.h> 42*c243e490SMarcel Moolenaar 43*c243e490SMarcel Moolenaar #include <atf-c.h> 44*c243e490SMarcel Moolenaar 45*c243e490SMarcel Moolenaar #include "atf-c/defs.h" 46*c243e490SMarcel Moolenaar 47*c243e490SMarcel Moolenaar #include "process.h" 48*c243e490SMarcel Moolenaar #include "sanity.h" 49*c243e490SMarcel Moolenaar #include "test_helpers.h" 50*c243e490SMarcel Moolenaar 51*c243e490SMarcel Moolenaar atf_error_t atf_process_status_init(atf_process_status_t *, int); 52*c243e490SMarcel Moolenaar 53*c243e490SMarcel Moolenaar /* --------------------------------------------------------------------- 54*c243e490SMarcel Moolenaar * Auxiliary functions for testing of 'atf_process_fork'. 55*c243e490SMarcel Moolenaar * --------------------------------------------------------------------- */ 56*c243e490SMarcel Moolenaar 57*c243e490SMarcel Moolenaar /* 58*c243e490SMarcel Moolenaar * Testing of atf_process_fork is quite messy. We want to be able to test 59*c243e490SMarcel Moolenaar * all the possible combinations of stdout and stderr behavior to ensure 60*c243e490SMarcel Moolenaar * that the streams are manipulated correctly. 61*c243e490SMarcel Moolenaar * 62*c243e490SMarcel Moolenaar * To do this, the do_fork function is a wrapper for atf_process_fork that 63*c243e490SMarcel Moolenaar * issues stream-specific hooks before fork, while the child is running and 64*c243e490SMarcel Moolenaar * after the child terminates. We then provide test cases that just call 65*c243e490SMarcel Moolenaar * do_fork with different hooks. 66*c243e490SMarcel Moolenaar * 67*c243e490SMarcel Moolenaar * The hooks are described by base_stream, and we then have one *_stream 68*c243e490SMarcel Moolenaar * type for ever possible stream behavior. 69*c243e490SMarcel Moolenaar */ 70*c243e490SMarcel Moolenaar 71*c243e490SMarcel Moolenaar enum out_type { stdout_type, stderr_type }; 72*c243e490SMarcel Moolenaar 73*c243e490SMarcel Moolenaar struct base_stream { 74*c243e490SMarcel Moolenaar void (*init)(void *); 75*c243e490SMarcel Moolenaar void (*process)(void *, atf_process_child_t *); 76*c243e490SMarcel Moolenaar void (*fini)(void *); 77*c243e490SMarcel Moolenaar 78*c243e490SMarcel Moolenaar /* m_sb is initialized by subclasses that need it, but all consumers 79*c243e490SMarcel Moolenaar * must use m_sb_ptr, which may or may not point to m_sb. This allows 80*c243e490SMarcel Moolenaar * us to test the interface with a NULL value, which triggers a 81*c243e490SMarcel Moolenaar * default behavior. */ 82*c243e490SMarcel Moolenaar atf_process_stream_t m_sb; 83*c243e490SMarcel Moolenaar atf_process_stream_t *m_sb_ptr; 84*c243e490SMarcel Moolenaar enum out_type m_type; 85*c243e490SMarcel Moolenaar }; 86*c243e490SMarcel Moolenaar #define BASE_STREAM(ihook, phook, fhook, type) \ 87*c243e490SMarcel Moolenaar { .init = ihook, \ 88*c243e490SMarcel Moolenaar .process = phook, \ 89*c243e490SMarcel Moolenaar .fini = fhook, \ 90*c243e490SMarcel Moolenaar .m_type = type } 91*c243e490SMarcel Moolenaar 92*c243e490SMarcel Moolenaar static 93*c243e490SMarcel Moolenaar void 94*c243e490SMarcel Moolenaar check_file(const enum out_type type) 95*c243e490SMarcel Moolenaar { 96*c243e490SMarcel Moolenaar switch (type) { 97*c243e490SMarcel Moolenaar case stdout_type: 98*c243e490SMarcel Moolenaar ATF_CHECK(grep_file("stdout", "stdout: msg")); 99*c243e490SMarcel Moolenaar ATF_CHECK(!grep_file("stdout", "stderr: msg")); 100*c243e490SMarcel Moolenaar break; 101*c243e490SMarcel Moolenaar case stderr_type: 102*c243e490SMarcel Moolenaar ATF_CHECK(grep_file("stderr", "stderr: msg")); 103*c243e490SMarcel Moolenaar ATF_CHECK(!grep_file("stderr", "stdout: msg")); 104*c243e490SMarcel Moolenaar break; 105*c243e490SMarcel Moolenaar default: 106*c243e490SMarcel Moolenaar UNREACHABLE; 107*c243e490SMarcel Moolenaar } 108*c243e490SMarcel Moolenaar } 109*c243e490SMarcel Moolenaar 110*c243e490SMarcel Moolenaar struct capture_stream { 111*c243e490SMarcel Moolenaar struct base_stream m_base; 112*c243e490SMarcel Moolenaar 113*c243e490SMarcel Moolenaar atf_dynstr_t m_msg; 114*c243e490SMarcel Moolenaar }; 115*c243e490SMarcel Moolenaar #define CAPTURE_STREAM(type) \ 116*c243e490SMarcel Moolenaar { .m_base = BASE_STREAM(capture_stream_init, \ 117*c243e490SMarcel Moolenaar capture_stream_process, \ 118*c243e490SMarcel Moolenaar capture_stream_fini, \ 119*c243e490SMarcel Moolenaar type) } 120*c243e490SMarcel Moolenaar 121*c243e490SMarcel Moolenaar static 122*c243e490SMarcel Moolenaar void 123*c243e490SMarcel Moolenaar capture_stream_init(void *v) 124*c243e490SMarcel Moolenaar { 125*c243e490SMarcel Moolenaar struct capture_stream *s = v; 126*c243e490SMarcel Moolenaar 127*c243e490SMarcel Moolenaar s->m_base.m_sb_ptr = &s->m_base.m_sb; 128*c243e490SMarcel Moolenaar RE(atf_process_stream_init_capture(&s->m_base.m_sb)); 129*c243e490SMarcel Moolenaar RE(atf_dynstr_init(&s->m_msg)); 130*c243e490SMarcel Moolenaar } 131*c243e490SMarcel Moolenaar 132*c243e490SMarcel Moolenaar static 133*c243e490SMarcel Moolenaar void 134*c243e490SMarcel Moolenaar capture_stream_process(void *v, atf_process_child_t *c) 135*c243e490SMarcel Moolenaar { 136*c243e490SMarcel Moolenaar struct capture_stream *s = v; 137*c243e490SMarcel Moolenaar 138*c243e490SMarcel Moolenaar switch (s->m_base.m_type) { 139*c243e490SMarcel Moolenaar case stdout_type: 140*c243e490SMarcel Moolenaar (void)read_line(atf_process_child_stdout(c), &s->m_msg); 141*c243e490SMarcel Moolenaar break; 142*c243e490SMarcel Moolenaar case stderr_type: 143*c243e490SMarcel Moolenaar (void)read_line(atf_process_child_stderr(c), &s->m_msg); 144*c243e490SMarcel Moolenaar break; 145*c243e490SMarcel Moolenaar default: 146*c243e490SMarcel Moolenaar UNREACHABLE; 147*c243e490SMarcel Moolenaar } 148*c243e490SMarcel Moolenaar } 149*c243e490SMarcel Moolenaar 150*c243e490SMarcel Moolenaar static 151*c243e490SMarcel Moolenaar void 152*c243e490SMarcel Moolenaar capture_stream_fini(void *v) 153*c243e490SMarcel Moolenaar { 154*c243e490SMarcel Moolenaar struct capture_stream *s = v; 155*c243e490SMarcel Moolenaar 156*c243e490SMarcel Moolenaar switch (s->m_base.m_type) { 157*c243e490SMarcel Moolenaar case stdout_type: 158*c243e490SMarcel Moolenaar ATF_CHECK(grep_string(&s->m_msg, "stdout: msg")); 159*c243e490SMarcel Moolenaar ATF_CHECK(!grep_string(&s->m_msg, "stderr: msg")); 160*c243e490SMarcel Moolenaar break; 161*c243e490SMarcel Moolenaar case stderr_type: 162*c243e490SMarcel Moolenaar ATF_CHECK(!grep_string(&s->m_msg, "stdout: msg")); 163*c243e490SMarcel Moolenaar ATF_CHECK(grep_string(&s->m_msg, "stderr: msg")); 164*c243e490SMarcel Moolenaar break; 165*c243e490SMarcel Moolenaar default: 166*c243e490SMarcel Moolenaar UNREACHABLE; 167*c243e490SMarcel Moolenaar } 168*c243e490SMarcel Moolenaar 169*c243e490SMarcel Moolenaar atf_dynstr_fini(&s->m_msg); 170*c243e490SMarcel Moolenaar atf_process_stream_fini(&s->m_base.m_sb); 171*c243e490SMarcel Moolenaar } 172*c243e490SMarcel Moolenaar 173*c243e490SMarcel Moolenaar struct connect_stream { 174*c243e490SMarcel Moolenaar struct base_stream m_base; 175*c243e490SMarcel Moolenaar 176*c243e490SMarcel Moolenaar int m_fd; 177*c243e490SMarcel Moolenaar }; 178*c243e490SMarcel Moolenaar #define CONNECT_STREAM(type) \ 179*c243e490SMarcel Moolenaar { .m_base = BASE_STREAM(connect_stream_init, \ 180*c243e490SMarcel Moolenaar NULL, \ 181*c243e490SMarcel Moolenaar connect_stream_fini, \ 182*c243e490SMarcel Moolenaar type) } 183*c243e490SMarcel Moolenaar 184*c243e490SMarcel Moolenaar static 185*c243e490SMarcel Moolenaar void 186*c243e490SMarcel Moolenaar connect_stream_init(void *v) 187*c243e490SMarcel Moolenaar { 188*c243e490SMarcel Moolenaar struct connect_stream *s = v; 189*c243e490SMarcel Moolenaar int src_fd; 190*c243e490SMarcel Moolenaar 191*c243e490SMarcel Moolenaar switch (s->m_base.m_type) { 192*c243e490SMarcel Moolenaar case stdout_type: 193*c243e490SMarcel Moolenaar src_fd = STDOUT_FILENO; 194*c243e490SMarcel Moolenaar s->m_fd = open("stdout", O_WRONLY | O_CREAT | O_TRUNC, 0644); 195*c243e490SMarcel Moolenaar break; 196*c243e490SMarcel Moolenaar case stderr_type: 197*c243e490SMarcel Moolenaar src_fd = STDERR_FILENO; 198*c243e490SMarcel Moolenaar s->m_fd = open("stderr", O_WRONLY | O_CREAT | O_TRUNC, 0644); 199*c243e490SMarcel Moolenaar break; 200*c243e490SMarcel Moolenaar default: 201*c243e490SMarcel Moolenaar UNREACHABLE; 202*c243e490SMarcel Moolenaar src_fd = -1; 203*c243e490SMarcel Moolenaar } 204*c243e490SMarcel Moolenaar ATF_REQUIRE(s->m_fd != -1); 205*c243e490SMarcel Moolenaar 206*c243e490SMarcel Moolenaar s->m_base.m_sb_ptr = &s->m_base.m_sb; 207*c243e490SMarcel Moolenaar RE(atf_process_stream_init_connect(&s->m_base.m_sb, src_fd, s->m_fd)); 208*c243e490SMarcel Moolenaar } 209*c243e490SMarcel Moolenaar 210*c243e490SMarcel Moolenaar static 211*c243e490SMarcel Moolenaar void 212*c243e490SMarcel Moolenaar connect_stream_fini(void *v) 213*c243e490SMarcel Moolenaar { 214*c243e490SMarcel Moolenaar struct connect_stream *s = v; 215*c243e490SMarcel Moolenaar 216*c243e490SMarcel Moolenaar ATF_REQUIRE(close(s->m_fd) != -1); 217*c243e490SMarcel Moolenaar 218*c243e490SMarcel Moolenaar atf_process_stream_fini(&s->m_base.m_sb); 219*c243e490SMarcel Moolenaar 220*c243e490SMarcel Moolenaar check_file(s->m_base.m_type); 221*c243e490SMarcel Moolenaar } 222*c243e490SMarcel Moolenaar 223*c243e490SMarcel Moolenaar struct inherit_stream { 224*c243e490SMarcel Moolenaar struct base_stream m_base; 225*c243e490SMarcel Moolenaar int m_fd; 226*c243e490SMarcel Moolenaar 227*c243e490SMarcel Moolenaar int m_old_fd; 228*c243e490SMarcel Moolenaar }; 229*c243e490SMarcel Moolenaar #define INHERIT_STREAM(type) \ 230*c243e490SMarcel Moolenaar { .m_base = BASE_STREAM(inherit_stream_init, \ 231*c243e490SMarcel Moolenaar NULL, \ 232*c243e490SMarcel Moolenaar inherit_stream_fini, \ 233*c243e490SMarcel Moolenaar type) } 234*c243e490SMarcel Moolenaar 235*c243e490SMarcel Moolenaar static 236*c243e490SMarcel Moolenaar void 237*c243e490SMarcel Moolenaar inherit_stream_init(void *v) 238*c243e490SMarcel Moolenaar { 239*c243e490SMarcel Moolenaar struct inherit_stream *s = v; 240*c243e490SMarcel Moolenaar const char *name; 241*c243e490SMarcel Moolenaar 242*c243e490SMarcel Moolenaar s->m_base.m_sb_ptr = &s->m_base.m_sb; 243*c243e490SMarcel Moolenaar RE(atf_process_stream_init_inherit(&s->m_base.m_sb)); 244*c243e490SMarcel Moolenaar 245*c243e490SMarcel Moolenaar switch (s->m_base.m_type) { 246*c243e490SMarcel Moolenaar case stdout_type: 247*c243e490SMarcel Moolenaar s->m_fd = STDOUT_FILENO; 248*c243e490SMarcel Moolenaar name = "stdout"; 249*c243e490SMarcel Moolenaar break; 250*c243e490SMarcel Moolenaar case stderr_type: 251*c243e490SMarcel Moolenaar s->m_fd = STDERR_FILENO; 252*c243e490SMarcel Moolenaar name = "stderr"; 253*c243e490SMarcel Moolenaar break; 254*c243e490SMarcel Moolenaar default: 255*c243e490SMarcel Moolenaar UNREACHABLE; 256*c243e490SMarcel Moolenaar name = NULL; 257*c243e490SMarcel Moolenaar } 258*c243e490SMarcel Moolenaar 259*c243e490SMarcel Moolenaar s->m_old_fd = dup(s->m_fd); 260*c243e490SMarcel Moolenaar ATF_REQUIRE(s->m_old_fd != -1); 261*c243e490SMarcel Moolenaar ATF_REQUIRE(close(s->m_fd) != -1); 262*c243e490SMarcel Moolenaar ATF_REQUIRE_EQ(open(name, O_WRONLY | O_CREAT | O_TRUNC, 0644), 263*c243e490SMarcel Moolenaar s->m_fd); 264*c243e490SMarcel Moolenaar } 265*c243e490SMarcel Moolenaar 266*c243e490SMarcel Moolenaar static 267*c243e490SMarcel Moolenaar void 268*c243e490SMarcel Moolenaar inherit_stream_fini(void *v) 269*c243e490SMarcel Moolenaar { 270*c243e490SMarcel Moolenaar struct inherit_stream *s = v; 271*c243e490SMarcel Moolenaar 272*c243e490SMarcel Moolenaar ATF_REQUIRE(dup2(s->m_old_fd, s->m_fd) != -1); 273*c243e490SMarcel Moolenaar ATF_REQUIRE(close(s->m_old_fd) != -1); 274*c243e490SMarcel Moolenaar 275*c243e490SMarcel Moolenaar atf_process_stream_fini(&s->m_base.m_sb); 276*c243e490SMarcel Moolenaar 277*c243e490SMarcel Moolenaar check_file(s->m_base.m_type); 278*c243e490SMarcel Moolenaar } 279*c243e490SMarcel Moolenaar 280*c243e490SMarcel Moolenaar #define default_stream inherit_stream 281*c243e490SMarcel Moolenaar #define DEFAULT_STREAM(type) \ 282*c243e490SMarcel Moolenaar { .m_base = BASE_STREAM(default_stream_init, \ 283*c243e490SMarcel Moolenaar NULL, \ 284*c243e490SMarcel Moolenaar default_stream_fini, \ 285*c243e490SMarcel Moolenaar type) } 286*c243e490SMarcel Moolenaar 287*c243e490SMarcel Moolenaar static 288*c243e490SMarcel Moolenaar void 289*c243e490SMarcel Moolenaar default_stream_init(void *v) 290*c243e490SMarcel Moolenaar { 291*c243e490SMarcel Moolenaar struct inherit_stream *s = v; 292*c243e490SMarcel Moolenaar 293*c243e490SMarcel Moolenaar inherit_stream_init(v); 294*c243e490SMarcel Moolenaar s->m_base.m_sb_ptr = NULL; 295*c243e490SMarcel Moolenaar } 296*c243e490SMarcel Moolenaar 297*c243e490SMarcel Moolenaar static 298*c243e490SMarcel Moolenaar void 299*c243e490SMarcel Moolenaar default_stream_fini(void *v) 300*c243e490SMarcel Moolenaar { 301*c243e490SMarcel Moolenaar inherit_stream_fini(v); 302*c243e490SMarcel Moolenaar } 303*c243e490SMarcel Moolenaar 304*c243e490SMarcel Moolenaar struct redirect_fd_stream { 305*c243e490SMarcel Moolenaar struct base_stream m_base; 306*c243e490SMarcel Moolenaar 307*c243e490SMarcel Moolenaar int m_fd; 308*c243e490SMarcel Moolenaar }; 309*c243e490SMarcel Moolenaar #define REDIRECT_FD_STREAM(type) \ 310*c243e490SMarcel Moolenaar { .m_base = BASE_STREAM(redirect_fd_stream_init, \ 311*c243e490SMarcel Moolenaar NULL, \ 312*c243e490SMarcel Moolenaar redirect_fd_stream_fini, \ 313*c243e490SMarcel Moolenaar type) } 314*c243e490SMarcel Moolenaar 315*c243e490SMarcel Moolenaar static 316*c243e490SMarcel Moolenaar void 317*c243e490SMarcel Moolenaar redirect_fd_stream_init(void *v) 318*c243e490SMarcel Moolenaar { 319*c243e490SMarcel Moolenaar struct redirect_fd_stream *s = v; 320*c243e490SMarcel Moolenaar 321*c243e490SMarcel Moolenaar switch (s->m_base.m_type) { 322*c243e490SMarcel Moolenaar case stdout_type: 323*c243e490SMarcel Moolenaar s->m_fd = open("stdout", O_WRONLY | O_CREAT | O_TRUNC, 0644); 324*c243e490SMarcel Moolenaar break; 325*c243e490SMarcel Moolenaar case stderr_type: 326*c243e490SMarcel Moolenaar s->m_fd = open("stderr", O_WRONLY | O_CREAT | O_TRUNC, 0644); 327*c243e490SMarcel Moolenaar break; 328*c243e490SMarcel Moolenaar default: 329*c243e490SMarcel Moolenaar UNREACHABLE; 330*c243e490SMarcel Moolenaar } 331*c243e490SMarcel Moolenaar ATF_REQUIRE(s->m_fd != -1); 332*c243e490SMarcel Moolenaar 333*c243e490SMarcel Moolenaar s->m_base.m_sb_ptr = &s->m_base.m_sb; 334*c243e490SMarcel Moolenaar RE(atf_process_stream_init_redirect_fd(&s->m_base.m_sb, s->m_fd)); 335*c243e490SMarcel Moolenaar } 336*c243e490SMarcel Moolenaar 337*c243e490SMarcel Moolenaar static 338*c243e490SMarcel Moolenaar void 339*c243e490SMarcel Moolenaar redirect_fd_stream_fini(void *v) 340*c243e490SMarcel Moolenaar { 341*c243e490SMarcel Moolenaar struct redirect_fd_stream *s = v; 342*c243e490SMarcel Moolenaar 343*c243e490SMarcel Moolenaar ATF_REQUIRE(close(s->m_fd) != -1); 344*c243e490SMarcel Moolenaar 345*c243e490SMarcel Moolenaar atf_process_stream_fini(&s->m_base.m_sb); 346*c243e490SMarcel Moolenaar 347*c243e490SMarcel Moolenaar check_file(s->m_base.m_type); 348*c243e490SMarcel Moolenaar } 349*c243e490SMarcel Moolenaar 350*c243e490SMarcel Moolenaar struct redirect_path_stream { 351*c243e490SMarcel Moolenaar struct base_stream m_base; 352*c243e490SMarcel Moolenaar 353*c243e490SMarcel Moolenaar atf_fs_path_t m_path; 354*c243e490SMarcel Moolenaar }; 355*c243e490SMarcel Moolenaar #define REDIRECT_PATH_STREAM(type) \ 356*c243e490SMarcel Moolenaar { .m_base = BASE_STREAM(redirect_path_stream_init, \ 357*c243e490SMarcel Moolenaar NULL, \ 358*c243e490SMarcel Moolenaar redirect_path_stream_fini, \ 359*c243e490SMarcel Moolenaar type) } 360*c243e490SMarcel Moolenaar 361*c243e490SMarcel Moolenaar static 362*c243e490SMarcel Moolenaar void 363*c243e490SMarcel Moolenaar redirect_path_stream_init(void *v) 364*c243e490SMarcel Moolenaar { 365*c243e490SMarcel Moolenaar struct redirect_path_stream *s = v; 366*c243e490SMarcel Moolenaar 367*c243e490SMarcel Moolenaar switch (s->m_base.m_type) { 368*c243e490SMarcel Moolenaar case stdout_type: 369*c243e490SMarcel Moolenaar RE(atf_fs_path_init_fmt(&s->m_path, "stdout")); 370*c243e490SMarcel Moolenaar break; 371*c243e490SMarcel Moolenaar case stderr_type: 372*c243e490SMarcel Moolenaar RE(atf_fs_path_init_fmt(&s->m_path, "stderr")); 373*c243e490SMarcel Moolenaar break; 374*c243e490SMarcel Moolenaar default: 375*c243e490SMarcel Moolenaar UNREACHABLE; 376*c243e490SMarcel Moolenaar } 377*c243e490SMarcel Moolenaar 378*c243e490SMarcel Moolenaar s->m_base.m_sb_ptr = &s->m_base.m_sb; 379*c243e490SMarcel Moolenaar RE(atf_process_stream_init_redirect_path(&s->m_base.m_sb, &s->m_path)); 380*c243e490SMarcel Moolenaar } 381*c243e490SMarcel Moolenaar 382*c243e490SMarcel Moolenaar static 383*c243e490SMarcel Moolenaar void 384*c243e490SMarcel Moolenaar redirect_path_stream_fini(void *v) 385*c243e490SMarcel Moolenaar { 386*c243e490SMarcel Moolenaar struct redirect_path_stream *s = v; 387*c243e490SMarcel Moolenaar 388*c243e490SMarcel Moolenaar atf_process_stream_fini(&s->m_base.m_sb); 389*c243e490SMarcel Moolenaar 390*c243e490SMarcel Moolenaar atf_fs_path_fini(&s->m_path); 391*c243e490SMarcel Moolenaar 392*c243e490SMarcel Moolenaar check_file(s->m_base.m_type); 393*c243e490SMarcel Moolenaar } 394*c243e490SMarcel Moolenaar 395*c243e490SMarcel Moolenaar static void child_print(void *) ATF_DEFS_ATTRIBUTE_NORETURN; 396*c243e490SMarcel Moolenaar 397*c243e490SMarcel Moolenaar struct child_print_data { 398*c243e490SMarcel Moolenaar const char *m_msg; 399*c243e490SMarcel Moolenaar }; 400*c243e490SMarcel Moolenaar 401*c243e490SMarcel Moolenaar static 402*c243e490SMarcel Moolenaar void 403*c243e490SMarcel Moolenaar child_print(void *v) 404*c243e490SMarcel Moolenaar { 405*c243e490SMarcel Moolenaar struct child_print_data *cpd = v; 406*c243e490SMarcel Moolenaar 407*c243e490SMarcel Moolenaar fprintf(stdout, "stdout: %s\n", cpd->m_msg); 408*c243e490SMarcel Moolenaar fprintf(stderr, "stderr: %s\n", cpd->m_msg); 409*c243e490SMarcel Moolenaar 410*c243e490SMarcel Moolenaar exit(EXIT_SUCCESS); 411*c243e490SMarcel Moolenaar } 412*c243e490SMarcel Moolenaar 413*c243e490SMarcel Moolenaar static 414*c243e490SMarcel Moolenaar void 415*c243e490SMarcel Moolenaar do_fork(const struct base_stream *outfs, void *out, 416*c243e490SMarcel Moolenaar const struct base_stream *errfs, void *err) 417*c243e490SMarcel Moolenaar { 418*c243e490SMarcel Moolenaar atf_process_child_t child; 419*c243e490SMarcel Moolenaar atf_process_status_t status; 420*c243e490SMarcel Moolenaar struct child_print_data cpd = { "msg" }; 421*c243e490SMarcel Moolenaar 422*c243e490SMarcel Moolenaar outfs->init(out); 423*c243e490SMarcel Moolenaar errfs->init(err); 424*c243e490SMarcel Moolenaar 425*c243e490SMarcel Moolenaar RE(atf_process_fork(&child, child_print, outfs->m_sb_ptr, 426*c243e490SMarcel Moolenaar errfs->m_sb_ptr, &cpd)); 427*c243e490SMarcel Moolenaar if (outfs->process != NULL) 428*c243e490SMarcel Moolenaar outfs->process(out, &child); 429*c243e490SMarcel Moolenaar if (errfs->process != NULL) 430*c243e490SMarcel Moolenaar errfs->process(err, &child); 431*c243e490SMarcel Moolenaar RE(atf_process_child_wait(&child, &status)); 432*c243e490SMarcel Moolenaar 433*c243e490SMarcel Moolenaar outfs->fini(out); 434*c243e490SMarcel Moolenaar errfs->fini(err); 435*c243e490SMarcel Moolenaar 436*c243e490SMarcel Moolenaar atf_process_status_fini(&status); 437*c243e490SMarcel Moolenaar } 438*c243e490SMarcel Moolenaar 439*c243e490SMarcel Moolenaar /* --------------------------------------------------------------------- 440*c243e490SMarcel Moolenaar * Test cases for the "stream" type. 441*c243e490SMarcel Moolenaar * --------------------------------------------------------------------- */ 442*c243e490SMarcel Moolenaar 443*c243e490SMarcel Moolenaar ATF_TC(stream_init_capture); 444*c243e490SMarcel Moolenaar ATF_TC_HEAD(stream_init_capture, tc) 445*c243e490SMarcel Moolenaar { 446*c243e490SMarcel Moolenaar atf_tc_set_md_var(tc, "descr", "Tests the " 447*c243e490SMarcel Moolenaar "atf_process_stream_init_capture function"); 448*c243e490SMarcel Moolenaar } 449*c243e490SMarcel Moolenaar ATF_TC_BODY(stream_init_capture, tc) 450*c243e490SMarcel Moolenaar { 451*c243e490SMarcel Moolenaar atf_process_stream_t sb; 452*c243e490SMarcel Moolenaar 453*c243e490SMarcel Moolenaar RE(atf_process_stream_init_capture(&sb)); 454*c243e490SMarcel Moolenaar 455*c243e490SMarcel Moolenaar ATF_CHECK_EQ(atf_process_stream_type(&sb), 456*c243e490SMarcel Moolenaar atf_process_stream_type_capture); 457*c243e490SMarcel Moolenaar 458*c243e490SMarcel Moolenaar atf_process_stream_fini(&sb); 459*c243e490SMarcel Moolenaar } 460*c243e490SMarcel Moolenaar 461*c243e490SMarcel Moolenaar ATF_TC(stream_init_connect); 462*c243e490SMarcel Moolenaar ATF_TC_HEAD(stream_init_connect, tc) 463*c243e490SMarcel Moolenaar { 464*c243e490SMarcel Moolenaar atf_tc_set_md_var(tc, "descr", "Tests the " 465*c243e490SMarcel Moolenaar "atf_process_stream_init_connect function"); 466*c243e490SMarcel Moolenaar } 467*c243e490SMarcel Moolenaar ATF_TC_BODY(stream_init_connect, tc) 468*c243e490SMarcel Moolenaar { 469*c243e490SMarcel Moolenaar atf_process_stream_t sb; 470*c243e490SMarcel Moolenaar 471*c243e490SMarcel Moolenaar RE(atf_process_stream_init_connect(&sb, 1, 2)); 472*c243e490SMarcel Moolenaar 473*c243e490SMarcel Moolenaar ATF_CHECK_EQ(atf_process_stream_type(&sb), 474*c243e490SMarcel Moolenaar atf_process_stream_type_connect); 475*c243e490SMarcel Moolenaar 476*c243e490SMarcel Moolenaar atf_process_stream_fini(&sb); 477*c243e490SMarcel Moolenaar } 478*c243e490SMarcel Moolenaar 479*c243e490SMarcel Moolenaar ATF_TC(stream_init_inherit); 480*c243e490SMarcel Moolenaar ATF_TC_HEAD(stream_init_inherit, tc) 481*c243e490SMarcel Moolenaar { 482*c243e490SMarcel Moolenaar atf_tc_set_md_var(tc, "descr", "Tests the " 483*c243e490SMarcel Moolenaar "atf_process_stream_init_inherit function"); 484*c243e490SMarcel Moolenaar } 485*c243e490SMarcel Moolenaar ATF_TC_BODY(stream_init_inherit, tc) 486*c243e490SMarcel Moolenaar { 487*c243e490SMarcel Moolenaar atf_process_stream_t sb; 488*c243e490SMarcel Moolenaar 489*c243e490SMarcel Moolenaar RE(atf_process_stream_init_inherit(&sb)); 490*c243e490SMarcel Moolenaar 491*c243e490SMarcel Moolenaar ATF_CHECK_EQ(atf_process_stream_type(&sb), 492*c243e490SMarcel Moolenaar atf_process_stream_type_inherit); 493*c243e490SMarcel Moolenaar 494*c243e490SMarcel Moolenaar atf_process_stream_fini(&sb); 495*c243e490SMarcel Moolenaar } 496*c243e490SMarcel Moolenaar 497*c243e490SMarcel Moolenaar ATF_TC(stream_init_redirect_fd); 498*c243e490SMarcel Moolenaar ATF_TC_HEAD(stream_init_redirect_fd, tc) 499*c243e490SMarcel Moolenaar { 500*c243e490SMarcel Moolenaar atf_tc_set_md_var(tc, "descr", "Tests the " 501*c243e490SMarcel Moolenaar "atf_process_stream_init_redirect_fd function"); 502*c243e490SMarcel Moolenaar } 503*c243e490SMarcel Moolenaar ATF_TC_BODY(stream_init_redirect_fd, tc) 504*c243e490SMarcel Moolenaar { 505*c243e490SMarcel Moolenaar atf_process_stream_t sb; 506*c243e490SMarcel Moolenaar 507*c243e490SMarcel Moolenaar RE(atf_process_stream_init_redirect_fd(&sb, 1)); 508*c243e490SMarcel Moolenaar 509*c243e490SMarcel Moolenaar ATF_CHECK_EQ(atf_process_stream_type(&sb), 510*c243e490SMarcel Moolenaar atf_process_stream_type_redirect_fd); 511*c243e490SMarcel Moolenaar 512*c243e490SMarcel Moolenaar atf_process_stream_fini(&sb); 513*c243e490SMarcel Moolenaar } 514*c243e490SMarcel Moolenaar 515*c243e490SMarcel Moolenaar ATF_TC(stream_init_redirect_path); 516*c243e490SMarcel Moolenaar ATF_TC_HEAD(stream_init_redirect_path, tc) 517*c243e490SMarcel Moolenaar { 518*c243e490SMarcel Moolenaar atf_tc_set_md_var(tc, "descr", "Tests the " 519*c243e490SMarcel Moolenaar "atf_process_stream_init_redirect_path function"); 520*c243e490SMarcel Moolenaar } 521*c243e490SMarcel Moolenaar ATF_TC_BODY(stream_init_redirect_path, tc) 522*c243e490SMarcel Moolenaar { 523*c243e490SMarcel Moolenaar atf_process_stream_t sb; 524*c243e490SMarcel Moolenaar atf_fs_path_t path; 525*c243e490SMarcel Moolenaar 526*c243e490SMarcel Moolenaar RE(atf_fs_path_init_fmt(&path, "foo")); 527*c243e490SMarcel Moolenaar RE(atf_process_stream_init_redirect_path(&sb, &path)); 528*c243e490SMarcel Moolenaar 529*c243e490SMarcel Moolenaar ATF_CHECK_EQ(atf_process_stream_type(&sb), 530*c243e490SMarcel Moolenaar atf_process_stream_type_redirect_path); 531*c243e490SMarcel Moolenaar 532*c243e490SMarcel Moolenaar atf_process_stream_fini(&sb); 533*c243e490SMarcel Moolenaar atf_fs_path_fini(&path); 534*c243e490SMarcel Moolenaar } 535*c243e490SMarcel Moolenaar 536*c243e490SMarcel Moolenaar /* --------------------------------------------------------------------- 537*c243e490SMarcel Moolenaar * Test cases for the "status" type. 538*c243e490SMarcel Moolenaar * --------------------------------------------------------------------- */ 539*c243e490SMarcel Moolenaar 540*c243e490SMarcel Moolenaar static void child_exit_success(void) ATF_DEFS_ATTRIBUTE_NORETURN; 541*c243e490SMarcel Moolenaar static void child_exit_failure(void) ATF_DEFS_ATTRIBUTE_NORETURN; 542*c243e490SMarcel Moolenaar static void child_sigkill(void) ATF_DEFS_ATTRIBUTE_NORETURN; 543*c243e490SMarcel Moolenaar static void child_sigquit(void) ATF_DEFS_ATTRIBUTE_NORETURN; 544*c243e490SMarcel Moolenaar static void child_sigterm(void) ATF_DEFS_ATTRIBUTE_NORETURN; 545*c243e490SMarcel Moolenaar 546*c243e490SMarcel Moolenaar void 547*c243e490SMarcel Moolenaar child_exit_success(void) 548*c243e490SMarcel Moolenaar { 549*c243e490SMarcel Moolenaar exit(EXIT_SUCCESS); 550*c243e490SMarcel Moolenaar } 551*c243e490SMarcel Moolenaar 552*c243e490SMarcel Moolenaar void 553*c243e490SMarcel Moolenaar child_exit_failure(void) 554*c243e490SMarcel Moolenaar { 555*c243e490SMarcel Moolenaar exit(EXIT_FAILURE); 556*c243e490SMarcel Moolenaar } 557*c243e490SMarcel Moolenaar 558*c243e490SMarcel Moolenaar void 559*c243e490SMarcel Moolenaar child_sigkill(void) 560*c243e490SMarcel Moolenaar { 561*c243e490SMarcel Moolenaar kill(getpid(), SIGKILL); 562*c243e490SMarcel Moolenaar abort(); 563*c243e490SMarcel Moolenaar } 564*c243e490SMarcel Moolenaar 565*c243e490SMarcel Moolenaar void 566*c243e490SMarcel Moolenaar child_sigquit(void) 567*c243e490SMarcel Moolenaar { 568*c243e490SMarcel Moolenaar kill(getpid(), SIGQUIT); 569*c243e490SMarcel Moolenaar abort(); 570*c243e490SMarcel Moolenaar } 571*c243e490SMarcel Moolenaar 572*c243e490SMarcel Moolenaar void 573*c243e490SMarcel Moolenaar child_sigterm(void) 574*c243e490SMarcel Moolenaar { 575*c243e490SMarcel Moolenaar kill(getpid(), SIGTERM); 576*c243e490SMarcel Moolenaar abort(); 577*c243e490SMarcel Moolenaar } 578*c243e490SMarcel Moolenaar 579*c243e490SMarcel Moolenaar static 580*c243e490SMarcel Moolenaar int 581*c243e490SMarcel Moolenaar fork_and_wait_child(void (*child_func)(void)) 582*c243e490SMarcel Moolenaar { 583*c243e490SMarcel Moolenaar pid_t pid; 584*c243e490SMarcel Moolenaar int status; 585*c243e490SMarcel Moolenaar 586*c243e490SMarcel Moolenaar pid = fork(); 587*c243e490SMarcel Moolenaar ATF_REQUIRE(pid != -1); 588*c243e490SMarcel Moolenaar if (pid == 0) { 589*c243e490SMarcel Moolenaar status = 0; /* Silence compiler warnings */ 590*c243e490SMarcel Moolenaar child_func(); 591*c243e490SMarcel Moolenaar UNREACHABLE; 592*c243e490SMarcel Moolenaar } else { 593*c243e490SMarcel Moolenaar ATF_REQUIRE(waitpid(pid, &status, 0) != 0); 594*c243e490SMarcel Moolenaar } 595*c243e490SMarcel Moolenaar 596*c243e490SMarcel Moolenaar return status; 597*c243e490SMarcel Moolenaar } 598*c243e490SMarcel Moolenaar 599*c243e490SMarcel Moolenaar ATF_TC(status_exited); 600*c243e490SMarcel Moolenaar ATF_TC_HEAD(status_exited, tc) 601*c243e490SMarcel Moolenaar { 602*c243e490SMarcel Moolenaar atf_tc_set_md_var(tc, "descr", "Tests the status type for processes " 603*c243e490SMarcel Moolenaar "that exit cleanly"); 604*c243e490SMarcel Moolenaar } 605*c243e490SMarcel Moolenaar ATF_TC_BODY(status_exited, tc) 606*c243e490SMarcel Moolenaar { 607*c243e490SMarcel Moolenaar { 608*c243e490SMarcel Moolenaar const int rawstatus = fork_and_wait_child(child_exit_success); 609*c243e490SMarcel Moolenaar atf_process_status_t s; 610*c243e490SMarcel Moolenaar RE(atf_process_status_init(&s, rawstatus)); 611*c243e490SMarcel Moolenaar ATF_CHECK(atf_process_status_exited(&s)); 612*c243e490SMarcel Moolenaar ATF_CHECK_EQ(atf_process_status_exitstatus(&s), EXIT_SUCCESS); 613*c243e490SMarcel Moolenaar ATF_CHECK(!atf_process_status_signaled(&s)); 614*c243e490SMarcel Moolenaar atf_process_status_fini(&s); 615*c243e490SMarcel Moolenaar } 616*c243e490SMarcel Moolenaar 617*c243e490SMarcel Moolenaar { 618*c243e490SMarcel Moolenaar const int rawstatus = fork_and_wait_child(child_exit_failure); 619*c243e490SMarcel Moolenaar atf_process_status_t s; 620*c243e490SMarcel Moolenaar RE(atf_process_status_init(&s, rawstatus)); 621*c243e490SMarcel Moolenaar ATF_CHECK(atf_process_status_exited(&s)); 622*c243e490SMarcel Moolenaar ATF_CHECK_EQ(atf_process_status_exitstatus(&s), EXIT_FAILURE); 623*c243e490SMarcel Moolenaar ATF_CHECK(!atf_process_status_signaled(&s)); 624*c243e490SMarcel Moolenaar atf_process_status_fini(&s); 625*c243e490SMarcel Moolenaar } 626*c243e490SMarcel Moolenaar } 627*c243e490SMarcel Moolenaar 628*c243e490SMarcel Moolenaar ATF_TC(status_signaled); 629*c243e490SMarcel Moolenaar ATF_TC_HEAD(status_signaled, tc) 630*c243e490SMarcel Moolenaar { 631*c243e490SMarcel Moolenaar atf_tc_set_md_var(tc, "descr", "Tests the status type for processes " 632*c243e490SMarcel Moolenaar "that end due to a signal"); 633*c243e490SMarcel Moolenaar } 634*c243e490SMarcel Moolenaar ATF_TC_BODY(status_signaled, tc) 635*c243e490SMarcel Moolenaar { 636*c243e490SMarcel Moolenaar { 637*c243e490SMarcel Moolenaar const int rawstatus = fork_and_wait_child(child_sigkill); 638*c243e490SMarcel Moolenaar atf_process_status_t s; 639*c243e490SMarcel Moolenaar RE(atf_process_status_init(&s, rawstatus)); 640*c243e490SMarcel Moolenaar ATF_CHECK(!atf_process_status_exited(&s)); 641*c243e490SMarcel Moolenaar ATF_CHECK(atf_process_status_signaled(&s)); 642*c243e490SMarcel Moolenaar ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGKILL); 643*c243e490SMarcel Moolenaar ATF_CHECK(!atf_process_status_coredump(&s)); 644*c243e490SMarcel Moolenaar atf_process_status_fini(&s); 645*c243e490SMarcel Moolenaar } 646*c243e490SMarcel Moolenaar 647*c243e490SMarcel Moolenaar { 648*c243e490SMarcel Moolenaar const int rawstatus = fork_and_wait_child(child_sigterm); 649*c243e490SMarcel Moolenaar atf_process_status_t s; 650*c243e490SMarcel Moolenaar RE(atf_process_status_init(&s, rawstatus)); 651*c243e490SMarcel Moolenaar ATF_CHECK(!atf_process_status_exited(&s)); 652*c243e490SMarcel Moolenaar ATF_CHECK(atf_process_status_signaled(&s)); 653*c243e490SMarcel Moolenaar ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGTERM); 654*c243e490SMarcel Moolenaar ATF_CHECK(!atf_process_status_coredump(&s)); 655*c243e490SMarcel Moolenaar atf_process_status_fini(&s); 656*c243e490SMarcel Moolenaar } 657*c243e490SMarcel Moolenaar } 658*c243e490SMarcel Moolenaar 659*c243e490SMarcel Moolenaar ATF_TC(status_coredump); 660*c243e490SMarcel Moolenaar ATF_TC_HEAD(status_coredump, tc) 661*c243e490SMarcel Moolenaar { 662*c243e490SMarcel Moolenaar atf_tc_set_md_var(tc, "descr", "Tests the status type for processes " 663*c243e490SMarcel Moolenaar "that crash"); 664*c243e490SMarcel Moolenaar } 665*c243e490SMarcel Moolenaar ATF_TC_BODY(status_coredump, tc) 666*c243e490SMarcel Moolenaar { 667*c243e490SMarcel Moolenaar struct rlimit rl; 668*c243e490SMarcel Moolenaar rl.rlim_cur = RLIM_INFINITY; 669*c243e490SMarcel Moolenaar rl.rlim_max = RLIM_INFINITY; 670*c243e490SMarcel Moolenaar if (setrlimit(RLIMIT_CORE, &rl) == -1) 671*c243e490SMarcel Moolenaar atf_tc_skip("Cannot unlimit the core file size; check limits " 672*c243e490SMarcel Moolenaar "manually"); 673*c243e490SMarcel Moolenaar 674*c243e490SMarcel Moolenaar const int rawstatus = fork_and_wait_child(child_sigquit); 675*c243e490SMarcel Moolenaar atf_process_status_t s; 676*c243e490SMarcel Moolenaar RE(atf_process_status_init(&s, rawstatus)); 677*c243e490SMarcel Moolenaar ATF_CHECK(!atf_process_status_exited(&s)); 678*c243e490SMarcel Moolenaar ATF_CHECK(atf_process_status_signaled(&s)); 679*c243e490SMarcel Moolenaar ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGQUIT); 680*c243e490SMarcel Moolenaar ATF_CHECK(atf_process_status_coredump(&s)); 681*c243e490SMarcel Moolenaar atf_process_status_fini(&s); 682*c243e490SMarcel Moolenaar } 683*c243e490SMarcel Moolenaar 684*c243e490SMarcel Moolenaar /* --------------------------------------------------------------------- 685*c243e490SMarcel Moolenaar * Test cases for the "child" type. 686*c243e490SMarcel Moolenaar * --------------------------------------------------------------------- */ 687*c243e490SMarcel Moolenaar 688*c243e490SMarcel Moolenaar static void child_report_pid(void *) ATF_DEFS_ATTRIBUTE_NORETURN; 689*c243e490SMarcel Moolenaar 690*c243e490SMarcel Moolenaar static 691*c243e490SMarcel Moolenaar void 692*c243e490SMarcel Moolenaar child_report_pid(void *v ATF_DEFS_ATTRIBUTE_UNUSED) 693*c243e490SMarcel Moolenaar { 694*c243e490SMarcel Moolenaar const pid_t pid = getpid(); 695*c243e490SMarcel Moolenaar if (write(STDOUT_FILENO, &pid, sizeof(pid)) != sizeof(pid)) 696*c243e490SMarcel Moolenaar abort(); 697*c243e490SMarcel Moolenaar fprintf(stderr, "Reporting %d to parent\n", (int)getpid()); 698*c243e490SMarcel Moolenaar exit(EXIT_SUCCESS); 699*c243e490SMarcel Moolenaar } 700*c243e490SMarcel Moolenaar 701*c243e490SMarcel Moolenaar ATF_TC(child_pid); 702*c243e490SMarcel Moolenaar ATF_TC_HEAD(child_pid, tc) 703*c243e490SMarcel Moolenaar { 704*c243e490SMarcel Moolenaar atf_tc_set_md_var(tc, "descr", "Tests the correctness of the pid " 705*c243e490SMarcel Moolenaar "stored in the child type"); 706*c243e490SMarcel Moolenaar } 707*c243e490SMarcel Moolenaar ATF_TC_BODY(child_pid, tc) 708*c243e490SMarcel Moolenaar { 709*c243e490SMarcel Moolenaar atf_process_stream_t outsb, errsb; 710*c243e490SMarcel Moolenaar atf_process_child_t child; 711*c243e490SMarcel Moolenaar atf_process_status_t status; 712*c243e490SMarcel Moolenaar pid_t pid; 713*c243e490SMarcel Moolenaar 714*c243e490SMarcel Moolenaar RE(atf_process_stream_init_capture(&outsb)); 715*c243e490SMarcel Moolenaar RE(atf_process_stream_init_inherit(&errsb)); 716*c243e490SMarcel Moolenaar 717*c243e490SMarcel Moolenaar RE(atf_process_fork(&child, child_report_pid, &outsb, &errsb, NULL)); 718*c243e490SMarcel Moolenaar ATF_CHECK_EQ(read(atf_process_child_stdout(&child), &pid, sizeof(pid)), 719*c243e490SMarcel Moolenaar sizeof(pid)); 720*c243e490SMarcel Moolenaar printf("Expected PID: %d\n", (int)atf_process_child_pid(&child)); 721*c243e490SMarcel Moolenaar printf("Actual PID: %d\n", (int)pid); 722*c243e490SMarcel Moolenaar ATF_CHECK_EQ(atf_process_child_pid(&child), pid); 723*c243e490SMarcel Moolenaar 724*c243e490SMarcel Moolenaar RE(atf_process_child_wait(&child, &status)); 725*c243e490SMarcel Moolenaar atf_process_status_fini(&status); 726*c243e490SMarcel Moolenaar 727*c243e490SMarcel Moolenaar atf_process_stream_fini(&outsb); 728*c243e490SMarcel Moolenaar atf_process_stream_fini(&errsb); 729*c243e490SMarcel Moolenaar } 730*c243e490SMarcel Moolenaar 731*c243e490SMarcel Moolenaar static 732*c243e490SMarcel Moolenaar void 733*c243e490SMarcel Moolenaar child_loop(void *v ATF_DEFS_ATTRIBUTE_UNUSED) 734*c243e490SMarcel Moolenaar { 735*c243e490SMarcel Moolenaar for (;;) 736*c243e490SMarcel Moolenaar sleep(1); 737*c243e490SMarcel Moolenaar } 738*c243e490SMarcel Moolenaar 739*c243e490SMarcel Moolenaar static 740*c243e490SMarcel Moolenaar void 741*c243e490SMarcel Moolenaar nop_signal(int sig ATF_DEFS_ATTRIBUTE_UNUSED) 742*c243e490SMarcel Moolenaar { 743*c243e490SMarcel Moolenaar } 744*c243e490SMarcel Moolenaar 745*c243e490SMarcel Moolenaar static 746*c243e490SMarcel Moolenaar void 747*c243e490SMarcel Moolenaar child_spawn_loop_and_wait_eintr(void *v ATF_DEFS_ATTRIBUTE_UNUSED) 748*c243e490SMarcel Moolenaar { 749*c243e490SMarcel Moolenaar atf_process_child_t child; 750*c243e490SMarcel Moolenaar atf_process_status_t status; 751*c243e490SMarcel Moolenaar struct sigaction sighup, old_sighup; 752*c243e490SMarcel Moolenaar 753*c243e490SMarcel Moolenaar #define RE_ABORT(expr) \ 754*c243e490SMarcel Moolenaar do { \ 755*c243e490SMarcel Moolenaar atf_error_t _aux_err = expr; \ 756*c243e490SMarcel Moolenaar if (atf_is_error(_aux_err)) { \ 757*c243e490SMarcel Moolenaar atf_error_free(_aux_err); \ 758*c243e490SMarcel Moolenaar abort(); \ 759*c243e490SMarcel Moolenaar } \ 760*c243e490SMarcel Moolenaar } while (0) 761*c243e490SMarcel Moolenaar 762*c243e490SMarcel Moolenaar { 763*c243e490SMarcel Moolenaar atf_process_stream_t outsb, errsb; 764*c243e490SMarcel Moolenaar 765*c243e490SMarcel Moolenaar RE_ABORT(atf_process_stream_init_capture(&outsb)); 766*c243e490SMarcel Moolenaar RE_ABORT(atf_process_stream_init_inherit(&errsb)); 767*c243e490SMarcel Moolenaar RE_ABORT(atf_process_fork(&child, child_loop, &outsb, &errsb, NULL)); 768*c243e490SMarcel Moolenaar atf_process_stream_fini(&outsb); 769*c243e490SMarcel Moolenaar atf_process_stream_fini(&errsb); 770*c243e490SMarcel Moolenaar } 771*c243e490SMarcel Moolenaar 772*c243e490SMarcel Moolenaar sighup.sa_handler = nop_signal; 773*c243e490SMarcel Moolenaar sigemptyset(&sighup.sa_mask); 774*c243e490SMarcel Moolenaar sighup.sa_flags = 0; 775*c243e490SMarcel Moolenaar if (sigaction(SIGHUP, &sighup, &old_sighup) == -1) 776*c243e490SMarcel Moolenaar abort(); 777*c243e490SMarcel Moolenaar 778*c243e490SMarcel Moolenaar printf("waiting\n"); 779*c243e490SMarcel Moolenaar fflush(stdout); 780*c243e490SMarcel Moolenaar 781*c243e490SMarcel Moolenaar fprintf(stderr, "Child entering wait(2)\n"); 782*c243e490SMarcel Moolenaar atf_error_t err = atf_process_child_wait(&child, &status); 783*c243e490SMarcel Moolenaar fprintf(stderr, "Child's wait(2) terminated\n"); 784*c243e490SMarcel Moolenaar if (!atf_is_error(err)) { 785*c243e490SMarcel Moolenaar fprintf(stderr, "wait completed successfully (not interrupted)\n"); 786*c243e490SMarcel Moolenaar abort(); 787*c243e490SMarcel Moolenaar } 788*c243e490SMarcel Moolenaar if (!atf_error_is(err, "libc")) { 789*c243e490SMarcel Moolenaar fprintf(stderr, "wait did not raise libc_error\n"); 790*c243e490SMarcel Moolenaar abort(); 791*c243e490SMarcel Moolenaar } 792*c243e490SMarcel Moolenaar if (atf_libc_error_code(err) != EINTR) { 793*c243e490SMarcel Moolenaar fprintf(stderr, "libc_error is not EINTR\n"); 794*c243e490SMarcel Moolenaar abort(); 795*c243e490SMarcel Moolenaar } 796*c243e490SMarcel Moolenaar atf_error_free(err); 797*c243e490SMarcel Moolenaar 798*c243e490SMarcel Moolenaar sigaction(SIGHUP, &old_sighup, NULL); 799*c243e490SMarcel Moolenaar 800*c243e490SMarcel Moolenaar fprintf(stderr, "Child is killing subchild\n"); 801*c243e490SMarcel Moolenaar kill(atf_process_child_pid(&child), SIGTERM); 802*c243e490SMarcel Moolenaar 803*c243e490SMarcel Moolenaar RE_ABORT(atf_process_child_wait(&child, &status)); 804*c243e490SMarcel Moolenaar atf_process_status_fini(&status); 805*c243e490SMarcel Moolenaar 806*c243e490SMarcel Moolenaar #undef RE_ABORT 807*c243e490SMarcel Moolenaar 808*c243e490SMarcel Moolenaar exit(EXIT_SUCCESS); 809*c243e490SMarcel Moolenaar } 810*c243e490SMarcel Moolenaar 811*c243e490SMarcel Moolenaar ATF_TC(child_wait_eintr); 812*c243e490SMarcel Moolenaar ATF_TC_HEAD(child_wait_eintr, tc) 813*c243e490SMarcel Moolenaar { 814*c243e490SMarcel Moolenaar atf_tc_set_md_var(tc, "descr", "Tests the interruption of the wait " 815*c243e490SMarcel Moolenaar "method by an external signal, and the return of " 816*c243e490SMarcel Moolenaar "an EINTR error"); 817*c243e490SMarcel Moolenaar atf_tc_set_md_var(tc, "timeout", "30"); 818*c243e490SMarcel Moolenaar } 819*c243e490SMarcel Moolenaar ATF_TC_BODY(child_wait_eintr, tc) 820*c243e490SMarcel Moolenaar { 821*c243e490SMarcel Moolenaar atf_process_child_t child; 822*c243e490SMarcel Moolenaar atf_process_status_t status; 823*c243e490SMarcel Moolenaar 824*c243e490SMarcel Moolenaar { 825*c243e490SMarcel Moolenaar atf_process_stream_t outsb, errsb; 826*c243e490SMarcel Moolenaar 827*c243e490SMarcel Moolenaar RE(atf_process_stream_init_capture(&outsb)); 828*c243e490SMarcel Moolenaar RE(atf_process_stream_init_inherit(&errsb)); 829*c243e490SMarcel Moolenaar RE(atf_process_fork(&child, child_spawn_loop_and_wait_eintr, 830*c243e490SMarcel Moolenaar &outsb, &errsb, NULL)); 831*c243e490SMarcel Moolenaar atf_process_stream_fini(&outsb); 832*c243e490SMarcel Moolenaar atf_process_stream_fini(&errsb); 833*c243e490SMarcel Moolenaar } 834*c243e490SMarcel Moolenaar 835*c243e490SMarcel Moolenaar { 836*c243e490SMarcel Moolenaar /* Wait until the child process performs the wait call. This is 837*c243e490SMarcel Moolenaar * racy, because the message we get from it is sent *before* 838*c243e490SMarcel Moolenaar * doing the real system call... but I can't figure any other way 839*c243e490SMarcel Moolenaar * to do this. */ 840*c243e490SMarcel Moolenaar char buf[16]; 841*c243e490SMarcel Moolenaar printf("Waiting for child to issue wait(2)\n"); 842*c243e490SMarcel Moolenaar ATF_REQUIRE(read(atf_process_child_stdout(&child), buf, 843*c243e490SMarcel Moolenaar sizeof(buf)) > 0); 844*c243e490SMarcel Moolenaar sleep(1); 845*c243e490SMarcel Moolenaar } 846*c243e490SMarcel Moolenaar 847*c243e490SMarcel Moolenaar printf("Interrupting child's wait(2) call\n"); 848*c243e490SMarcel Moolenaar kill(atf_process_child_pid(&child), SIGHUP); 849*c243e490SMarcel Moolenaar 850*c243e490SMarcel Moolenaar printf("Waiting for child's completion\n"); 851*c243e490SMarcel Moolenaar RE(atf_process_child_wait(&child, &status)); 852*c243e490SMarcel Moolenaar ATF_REQUIRE(atf_process_status_exited(&status)); 853*c243e490SMarcel Moolenaar ATF_REQUIRE_EQ(atf_process_status_exitstatus(&status), EXIT_SUCCESS); 854*c243e490SMarcel Moolenaar atf_process_status_fini(&status); 855*c243e490SMarcel Moolenaar } 856*c243e490SMarcel Moolenaar 857*c243e490SMarcel Moolenaar /* --------------------------------------------------------------------- 858*c243e490SMarcel Moolenaar * Tests cases for the free functions. 859*c243e490SMarcel Moolenaar * --------------------------------------------------------------------- */ 860*c243e490SMarcel Moolenaar 861*c243e490SMarcel Moolenaar static 862*c243e490SMarcel Moolenaar void 863*c243e490SMarcel Moolenaar do_exec(const atf_tc_t *tc, const char *helper_name, atf_process_status_t *s, 864*c243e490SMarcel Moolenaar void (*prehook)(void)) 865*c243e490SMarcel Moolenaar { 866*c243e490SMarcel Moolenaar atf_fs_path_t process_helpers; 867*c243e490SMarcel Moolenaar const char *argv[3]; 868*c243e490SMarcel Moolenaar 869*c243e490SMarcel Moolenaar get_process_helpers_path(tc, true, &process_helpers); 870*c243e490SMarcel Moolenaar 871*c243e490SMarcel Moolenaar argv[0] = atf_fs_path_cstring(&process_helpers); 872*c243e490SMarcel Moolenaar argv[1] = helper_name; 873*c243e490SMarcel Moolenaar argv[2] = NULL; 874*c243e490SMarcel Moolenaar printf("Executing %s %s\n", argv[0], argv[1]); 875*c243e490SMarcel Moolenaar 876*c243e490SMarcel Moolenaar RE(atf_process_exec_array(s, &process_helpers, argv, NULL, NULL, prehook)); 877*c243e490SMarcel Moolenaar atf_fs_path_fini(&process_helpers); 878*c243e490SMarcel Moolenaar } 879*c243e490SMarcel Moolenaar 880*c243e490SMarcel Moolenaar static 881*c243e490SMarcel Moolenaar void 882*c243e490SMarcel Moolenaar check_line(int fd, const char *exp) 883*c243e490SMarcel Moolenaar { 884*c243e490SMarcel Moolenaar atf_dynstr_t line; 885*c243e490SMarcel Moolenaar bool eof; 886*c243e490SMarcel Moolenaar 887*c243e490SMarcel Moolenaar atf_dynstr_init(&line); 888*c243e490SMarcel Moolenaar eof = read_line(fd, &line); 889*c243e490SMarcel Moolenaar ATF_CHECK(!eof); 890*c243e490SMarcel Moolenaar ATF_CHECK_MSG(atf_equal_dynstr_cstring(&line, exp), 891*c243e490SMarcel Moolenaar "read: '%s', expected: '%s'", 892*c243e490SMarcel Moolenaar atf_dynstr_cstring(&line), exp); 893*c243e490SMarcel Moolenaar atf_dynstr_fini(&line); 894*c243e490SMarcel Moolenaar } 895*c243e490SMarcel Moolenaar 896*c243e490SMarcel Moolenaar ATF_TC(exec_failure); 897*c243e490SMarcel Moolenaar ATF_TC_HEAD(exec_failure, tc) 898*c243e490SMarcel Moolenaar { 899*c243e490SMarcel Moolenaar atf_tc_set_md_var(tc, "descr", "Tests execing a command"); 900*c243e490SMarcel Moolenaar } 901*c243e490SMarcel Moolenaar ATF_TC_BODY(exec_failure, tc) 902*c243e490SMarcel Moolenaar { 903*c243e490SMarcel Moolenaar atf_process_status_t status; 904*c243e490SMarcel Moolenaar 905*c243e490SMarcel Moolenaar do_exec(tc, "exit-failure", &status, NULL); 906*c243e490SMarcel Moolenaar ATF_CHECK(atf_process_status_exited(&status)); 907*c243e490SMarcel Moolenaar ATF_CHECK_EQ(atf_process_status_exitstatus(&status), EXIT_FAILURE); 908*c243e490SMarcel Moolenaar atf_process_status_fini(&status); 909*c243e490SMarcel Moolenaar } 910*c243e490SMarcel Moolenaar 911*c243e490SMarcel Moolenaar ATF_TC(exec_list); 912*c243e490SMarcel Moolenaar ATF_TC_HEAD(exec_list, tc) 913*c243e490SMarcel Moolenaar { 914*c243e490SMarcel Moolenaar atf_tc_set_md_var(tc, "descr", "Tests execing a command"); 915*c243e490SMarcel Moolenaar } 916*c243e490SMarcel Moolenaar ATF_TC_BODY(exec_list, tc) 917*c243e490SMarcel Moolenaar { 918*c243e490SMarcel Moolenaar atf_fs_path_t process_helpers; 919*c243e490SMarcel Moolenaar atf_list_t argv; 920*c243e490SMarcel Moolenaar atf_process_status_t status; 921*c243e490SMarcel Moolenaar 922*c243e490SMarcel Moolenaar RE(atf_list_init(&argv)); 923*c243e490SMarcel Moolenaar 924*c243e490SMarcel Moolenaar get_process_helpers_path(tc, true, &process_helpers); 925*c243e490SMarcel Moolenaar atf_list_append(&argv, strdup(atf_fs_path_cstring(&process_helpers)), true); 926*c243e490SMarcel Moolenaar atf_list_append(&argv, strdup("echo"), true); 927*c243e490SMarcel Moolenaar atf_list_append(&argv, strdup("test-message"), true); 928*c243e490SMarcel Moolenaar { 929*c243e490SMarcel Moolenaar atf_fs_path_t outpath; 930*c243e490SMarcel Moolenaar atf_process_stream_t outsb; 931*c243e490SMarcel Moolenaar 932*c243e490SMarcel Moolenaar RE(atf_fs_path_init_fmt(&outpath, "stdout")); 933*c243e490SMarcel Moolenaar RE(atf_process_stream_init_redirect_path(&outsb, &outpath)); 934*c243e490SMarcel Moolenaar RE(atf_process_exec_list(&status, &process_helpers, &argv, &outsb, 935*c243e490SMarcel Moolenaar NULL, NULL)); 936*c243e490SMarcel Moolenaar atf_process_stream_fini(&outsb); 937*c243e490SMarcel Moolenaar atf_fs_path_fini(&outpath); 938*c243e490SMarcel Moolenaar } 939*c243e490SMarcel Moolenaar atf_list_fini(&argv); 940*c243e490SMarcel Moolenaar 941*c243e490SMarcel Moolenaar ATF_CHECK(atf_process_status_exited(&status)); 942*c243e490SMarcel Moolenaar ATF_CHECK_EQ(atf_process_status_exitstatus(&status), EXIT_SUCCESS); 943*c243e490SMarcel Moolenaar 944*c243e490SMarcel Moolenaar { 945*c243e490SMarcel Moolenaar int fd = open("stdout", O_RDONLY); 946*c243e490SMarcel Moolenaar ATF_CHECK(fd != -1); 947*c243e490SMarcel Moolenaar check_line(fd, "test-message"); 948*c243e490SMarcel Moolenaar close(fd); 949*c243e490SMarcel Moolenaar } 950*c243e490SMarcel Moolenaar 951*c243e490SMarcel Moolenaar atf_process_status_fini(&status); 952*c243e490SMarcel Moolenaar atf_fs_path_fini(&process_helpers); 953*c243e490SMarcel Moolenaar } 954*c243e490SMarcel Moolenaar 955*c243e490SMarcel Moolenaar static void 956*c243e490SMarcel Moolenaar exit_early(void) 957*c243e490SMarcel Moolenaar { 958*c243e490SMarcel Moolenaar exit(80); 959*c243e490SMarcel Moolenaar } 960*c243e490SMarcel Moolenaar 961*c243e490SMarcel Moolenaar ATF_TC(exec_prehook); 962*c243e490SMarcel Moolenaar ATF_TC_HEAD(exec_prehook, tc) 963*c243e490SMarcel Moolenaar { 964*c243e490SMarcel Moolenaar atf_tc_set_md_var(tc, "descr", "Tests execing a command with a prehook"); 965*c243e490SMarcel Moolenaar } 966*c243e490SMarcel Moolenaar ATF_TC_BODY(exec_prehook, tc) 967*c243e490SMarcel Moolenaar { 968*c243e490SMarcel Moolenaar atf_process_status_t status; 969*c243e490SMarcel Moolenaar 970*c243e490SMarcel Moolenaar do_exec(tc, "exit-success", &status, exit_early); 971*c243e490SMarcel Moolenaar ATF_CHECK(atf_process_status_exited(&status)); 972*c243e490SMarcel Moolenaar ATF_CHECK_EQ(atf_process_status_exitstatus(&status), 80); 973*c243e490SMarcel Moolenaar atf_process_status_fini(&status); 974*c243e490SMarcel Moolenaar } 975*c243e490SMarcel Moolenaar 976*c243e490SMarcel Moolenaar ATF_TC(exec_success); 977*c243e490SMarcel Moolenaar ATF_TC_HEAD(exec_success, tc) 978*c243e490SMarcel Moolenaar { 979*c243e490SMarcel Moolenaar atf_tc_set_md_var(tc, "descr", "Tests execing a command"); 980*c243e490SMarcel Moolenaar } 981*c243e490SMarcel Moolenaar ATF_TC_BODY(exec_success, tc) 982*c243e490SMarcel Moolenaar { 983*c243e490SMarcel Moolenaar atf_process_status_t status; 984*c243e490SMarcel Moolenaar 985*c243e490SMarcel Moolenaar do_exec(tc, "exit-success", &status, NULL); 986*c243e490SMarcel Moolenaar ATF_CHECK(atf_process_status_exited(&status)); 987*c243e490SMarcel Moolenaar ATF_CHECK_EQ(atf_process_status_exitstatus(&status), EXIT_SUCCESS); 988*c243e490SMarcel Moolenaar atf_process_status_fini(&status); 989*c243e490SMarcel Moolenaar } 990*c243e490SMarcel Moolenaar 991*c243e490SMarcel Moolenaar static const int exit_v_null = 1; 992*c243e490SMarcel Moolenaar static const int exit_v_notnull = 2; 993*c243e490SMarcel Moolenaar 994*c243e490SMarcel Moolenaar static 995*c243e490SMarcel Moolenaar void 996*c243e490SMarcel Moolenaar child_cookie(void *v) 997*c243e490SMarcel Moolenaar { 998*c243e490SMarcel Moolenaar if (v == NULL) 999*c243e490SMarcel Moolenaar exit(exit_v_null); 1000*c243e490SMarcel Moolenaar else 1001*c243e490SMarcel Moolenaar exit(exit_v_notnull); 1002*c243e490SMarcel Moolenaar 1003*c243e490SMarcel Moolenaar UNREACHABLE; 1004*c243e490SMarcel Moolenaar } 1005*c243e490SMarcel Moolenaar 1006*c243e490SMarcel Moolenaar ATF_TC(fork_cookie); 1007*c243e490SMarcel Moolenaar ATF_TC_HEAD(fork_cookie, tc) 1008*c243e490SMarcel Moolenaar { 1009*c243e490SMarcel Moolenaar atf_tc_set_md_var(tc, "descr", "Tests forking a child, with " 1010*c243e490SMarcel Moolenaar "a null and non-null data cookie"); 1011*c243e490SMarcel Moolenaar } 1012*c243e490SMarcel Moolenaar ATF_TC_BODY(fork_cookie, tc) 1013*c243e490SMarcel Moolenaar { 1014*c243e490SMarcel Moolenaar atf_process_stream_t outsb, errsb; 1015*c243e490SMarcel Moolenaar 1016*c243e490SMarcel Moolenaar RE(atf_process_stream_init_inherit(&outsb)); 1017*c243e490SMarcel Moolenaar RE(atf_process_stream_init_inherit(&errsb)); 1018*c243e490SMarcel Moolenaar 1019*c243e490SMarcel Moolenaar { 1020*c243e490SMarcel Moolenaar atf_process_child_t child; 1021*c243e490SMarcel Moolenaar atf_process_status_t status; 1022*c243e490SMarcel Moolenaar 1023*c243e490SMarcel Moolenaar RE(atf_process_fork(&child, child_cookie, &outsb, &errsb, NULL)); 1024*c243e490SMarcel Moolenaar RE(atf_process_child_wait(&child, &status)); 1025*c243e490SMarcel Moolenaar 1026*c243e490SMarcel Moolenaar ATF_CHECK(atf_process_status_exited(&status)); 1027*c243e490SMarcel Moolenaar ATF_CHECK_EQ(atf_process_status_exitstatus(&status), exit_v_null); 1028*c243e490SMarcel Moolenaar 1029*c243e490SMarcel Moolenaar atf_process_status_fini(&status); 1030*c243e490SMarcel Moolenaar } 1031*c243e490SMarcel Moolenaar 1032*c243e490SMarcel Moolenaar { 1033*c243e490SMarcel Moolenaar atf_process_child_t child; 1034*c243e490SMarcel Moolenaar atf_process_status_t status; 1035*c243e490SMarcel Moolenaar int dummy_int; 1036*c243e490SMarcel Moolenaar 1037*c243e490SMarcel Moolenaar RE(atf_process_fork(&child, child_cookie, &outsb, &errsb, &dummy_int)); 1038*c243e490SMarcel Moolenaar RE(atf_process_child_wait(&child, &status)); 1039*c243e490SMarcel Moolenaar 1040*c243e490SMarcel Moolenaar ATF_CHECK(atf_process_status_exited(&status)); 1041*c243e490SMarcel Moolenaar ATF_CHECK_EQ(atf_process_status_exitstatus(&status), exit_v_notnull); 1042*c243e490SMarcel Moolenaar 1043*c243e490SMarcel Moolenaar atf_process_status_fini(&status); 1044*c243e490SMarcel Moolenaar } 1045*c243e490SMarcel Moolenaar 1046*c243e490SMarcel Moolenaar atf_process_stream_fini(&errsb); 1047*c243e490SMarcel Moolenaar atf_process_stream_fini(&outsb); 1048*c243e490SMarcel Moolenaar } 1049*c243e490SMarcel Moolenaar 1050*c243e490SMarcel Moolenaar #define TC_FORK_STREAMS(outlc, outuc, errlc, erruc) \ 1051*c243e490SMarcel Moolenaar ATF_TC(fork_out_ ## outlc ## _err_ ## errlc); \ 1052*c243e490SMarcel Moolenaar ATF_TC_HEAD(fork_out_ ## outlc ## _err_ ## errlc, tc) \ 1053*c243e490SMarcel Moolenaar { \ 1054*c243e490SMarcel Moolenaar atf_tc_set_md_var(tc, "descr", "Tests forking a child, with " \ 1055*c243e490SMarcel Moolenaar "stdout " #outlc " and stderr " #errlc); \ 1056*c243e490SMarcel Moolenaar } \ 1057*c243e490SMarcel Moolenaar ATF_TC_BODY(fork_out_ ## outlc ## _err_ ## errlc, tc) \ 1058*c243e490SMarcel Moolenaar { \ 1059*c243e490SMarcel Moolenaar struct outlc ## _stream out = outuc ## _STREAM(stdout_type); \ 1060*c243e490SMarcel Moolenaar struct errlc ## _stream err = erruc ## _STREAM(stderr_type); \ 1061*c243e490SMarcel Moolenaar do_fork(&out.m_base, &out, &err.m_base, &err); \ 1062*c243e490SMarcel Moolenaar } 1063*c243e490SMarcel Moolenaar 1064*c243e490SMarcel Moolenaar TC_FORK_STREAMS(capture, CAPTURE, capture, CAPTURE); 1065*c243e490SMarcel Moolenaar TC_FORK_STREAMS(capture, CAPTURE, connect, CONNECT); 1066*c243e490SMarcel Moolenaar TC_FORK_STREAMS(capture, CAPTURE, default, DEFAULT); 1067*c243e490SMarcel Moolenaar TC_FORK_STREAMS(capture, CAPTURE, inherit, INHERIT); 1068*c243e490SMarcel Moolenaar TC_FORK_STREAMS(capture, CAPTURE, redirect_fd, REDIRECT_FD); 1069*c243e490SMarcel Moolenaar TC_FORK_STREAMS(capture, CAPTURE, redirect_path, REDIRECT_PATH); 1070*c243e490SMarcel Moolenaar TC_FORK_STREAMS(connect, CONNECT, capture, CAPTURE); 1071*c243e490SMarcel Moolenaar TC_FORK_STREAMS(connect, CONNECT, connect, CONNECT); 1072*c243e490SMarcel Moolenaar TC_FORK_STREAMS(connect, CONNECT, default, DEFAULT); 1073*c243e490SMarcel Moolenaar TC_FORK_STREAMS(connect, CONNECT, inherit, INHERIT); 1074*c243e490SMarcel Moolenaar TC_FORK_STREAMS(connect, CONNECT, redirect_fd, REDIRECT_FD); 1075*c243e490SMarcel Moolenaar TC_FORK_STREAMS(connect, CONNECT, redirect_path, REDIRECT_PATH); 1076*c243e490SMarcel Moolenaar TC_FORK_STREAMS(default, DEFAULT, capture, CAPTURE); 1077*c243e490SMarcel Moolenaar TC_FORK_STREAMS(default, DEFAULT, connect, CONNECT); 1078*c243e490SMarcel Moolenaar TC_FORK_STREAMS(default, DEFAULT, default, DEFAULT); 1079*c243e490SMarcel Moolenaar TC_FORK_STREAMS(default, DEFAULT, inherit, INHERIT); 1080*c243e490SMarcel Moolenaar TC_FORK_STREAMS(default, DEFAULT, redirect_fd, REDIRECT_FD); 1081*c243e490SMarcel Moolenaar TC_FORK_STREAMS(default, DEFAULT, redirect_path, REDIRECT_PATH); 1082*c243e490SMarcel Moolenaar TC_FORK_STREAMS(inherit, INHERIT, capture, CAPTURE); 1083*c243e490SMarcel Moolenaar TC_FORK_STREAMS(inherit, INHERIT, connect, CONNECT); 1084*c243e490SMarcel Moolenaar TC_FORK_STREAMS(inherit, INHERIT, default, DEFAULT); 1085*c243e490SMarcel Moolenaar TC_FORK_STREAMS(inherit, INHERIT, inherit, INHERIT); 1086*c243e490SMarcel Moolenaar TC_FORK_STREAMS(inherit, INHERIT, redirect_fd, REDIRECT_FD); 1087*c243e490SMarcel Moolenaar TC_FORK_STREAMS(inherit, INHERIT, redirect_path, REDIRECT_PATH); 1088*c243e490SMarcel Moolenaar TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, capture, CAPTURE); 1089*c243e490SMarcel Moolenaar TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, connect, CONNECT); 1090*c243e490SMarcel Moolenaar TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, default, DEFAULT); 1091*c243e490SMarcel Moolenaar TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, inherit, INHERIT); 1092*c243e490SMarcel Moolenaar TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, redirect_fd, REDIRECT_FD); 1093*c243e490SMarcel Moolenaar TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, redirect_path, REDIRECT_PATH); 1094*c243e490SMarcel Moolenaar TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, capture, CAPTURE); 1095*c243e490SMarcel Moolenaar TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, connect, CONNECT); 1096*c243e490SMarcel Moolenaar TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, default, DEFAULT); 1097*c243e490SMarcel Moolenaar TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, inherit, INHERIT); 1098*c243e490SMarcel Moolenaar TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, redirect_fd, REDIRECT_FD); 1099*c243e490SMarcel Moolenaar TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, redirect_path, REDIRECT_PATH); 1100*c243e490SMarcel Moolenaar 1101*c243e490SMarcel Moolenaar #undef TC_FORK_STREAMS 1102*c243e490SMarcel Moolenaar 1103*c243e490SMarcel Moolenaar /* --------------------------------------------------------------------- 1104*c243e490SMarcel Moolenaar * Main. 1105*c243e490SMarcel Moolenaar * --------------------------------------------------------------------- */ 1106*c243e490SMarcel Moolenaar 1107*c243e490SMarcel Moolenaar ATF_TP_ADD_TCS(tp) 1108*c243e490SMarcel Moolenaar { 1109*c243e490SMarcel Moolenaar /* Add the tests for the "stream" type. */ 1110*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, stream_init_capture); 1111*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, stream_init_connect); 1112*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, stream_init_inherit); 1113*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, stream_init_redirect_fd); 1114*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, stream_init_redirect_path); 1115*c243e490SMarcel Moolenaar 1116*c243e490SMarcel Moolenaar /* Add the tests for the "status" type. */ 1117*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, status_exited); 1118*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, status_signaled); 1119*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, status_coredump); 1120*c243e490SMarcel Moolenaar 1121*c243e490SMarcel Moolenaar /* Add the tests for the "child" type. */ 1122*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, child_pid); 1123*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, child_wait_eintr); 1124*c243e490SMarcel Moolenaar 1125*c243e490SMarcel Moolenaar /* Add the tests for the free functions. */ 1126*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, exec_failure); 1127*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, exec_list); 1128*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, exec_prehook); 1129*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, exec_success); 1130*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_cookie); 1131*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_capture_err_capture); 1132*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_capture_err_connect); 1133*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_capture_err_default); 1134*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_capture_err_inherit); 1135*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_capture_err_redirect_fd); 1136*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_capture_err_redirect_path); 1137*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_connect_err_capture); 1138*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_connect_err_connect); 1139*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_connect_err_default); 1140*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_connect_err_inherit); 1141*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_connect_err_redirect_fd); 1142*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_connect_err_redirect_path); 1143*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_default_err_capture); 1144*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_default_err_connect); 1145*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_default_err_default); 1146*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_default_err_inherit); 1147*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_default_err_redirect_fd); 1148*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_default_err_redirect_path); 1149*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_inherit_err_capture); 1150*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_inherit_err_connect); 1151*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_inherit_err_default); 1152*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_inherit_err_inherit); 1153*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_inherit_err_redirect_fd); 1154*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_inherit_err_redirect_path); 1155*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_capture); 1156*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_connect); 1157*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_default); 1158*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_inherit); 1159*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_redirect_fd); 1160*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_redirect_path); 1161*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_capture); 1162*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_connect); 1163*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_default); 1164*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_inherit); 1165*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_redirect_fd); 1166*c243e490SMarcel Moolenaar ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_redirect_path); 1167*c243e490SMarcel Moolenaar 1168*c243e490SMarcel Moolenaar return atf_no_error(); 1169*c243e490SMarcel Moolenaar } 1170