1ref -D_def_map_ast=1 2 3hdr spawn 4lib spawn,spawnve,spawnveg,spawnvex 5lib posix_spawnattr_setfchdir,posix_spawnattr_setsid,posix_spawnattr_setumask spawn.h 6 7mem inheritance.pgroup spawn.h 8 9tst lib_posix_spawn unistd.h stdlib.h spawn.h -Dfork=______fork note{ posix_spawn exists and it works and its worth using }end status{ 10 #include <sys/types.h> 11 #include <sys/stat.h> 12 #include <sys/wait.h> 13 #include <spawn.h> 14 #include <signal.h> 15 #include <fcntl.h> 16 #include <string.h> 17 /* if it uses fork() why bother? */ 18 #undef fork 19 pid_t fork _ARG_((void)) { NOTE("uses fork()"); return -1; } 20 pid_t _fork _ARG_((void)) { NOTE("uses _fork()"); return -1; } 21 pid_t __fork _ARG_((void)) { NOTE("uses __fork()"); return -1; } 22 int 23 main(argc, argv) 24 int argc; 25 char** argv; 26 { 27 char* s; 28 pid_t pid; 29 posix_spawnattr_t attr; 30 int n; 31 int status; 32 char* cmd[4]; 33 char tmp[1024]; 34 if (argv[2]) 35 _exit(signal(SIGHUP, SIG_DFL) != SIG_IGN); 36 signal(SIGHUP, SIG_IGN); 37 if (posix_spawnattr_init(&attr)) 38 { 39 NOTE("posix_spawnattr_init() FAILED"); 40 _exit(0); 41 } 42 if (posix_spawnattr_setpgroup(&attr, 0)) 43 { 44 NOTE("posix_spawnattr_setpgroup() FAILED"); 45 _exit(0); 46 } 47 if (posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETPGROUP)) 48 { 49 NOTE("posix_spawnattr_setflags() FAILED"); 50 _exit(0); 51 } 52 /* first try an a.out and verify that SIGHUP is ignored */ 53 cmd[0] = argv[0]; 54 cmd[1] = argv[1]; 55 cmd[2] = "test"; 56 cmd[3] = 0; 57 if (posix_spawn(&pid, cmd[0], 0, &attr, cmd, 0)) 58 { 59 NOTE("posix_spawn() FAILED"); 60 _exit(0); 61 } 62 status = 1; 63 if (wait(&status) < 0) 64 { 65 NOTE("wait() FAILED"); 66 _exit(0); 67 } 68 if (status != 0) 69 { 70 NOTE("SIGHUP ignored in parent not ignored in child"); 71 _exit(0); 72 } 73 /* must return exec-type errors or its useless to us *unless* there is no [v]fork() */ 74 n = strlen(cmd[0]); 75 if (n >= (sizeof(tmp) - 3)) 76 { 77 NOTE("test executable path too long"); 78 _exit(0); 79 } 80 strcpy(tmp, cmd[0]); 81 tmp[n] = '.'; 82 tmp[n+1] = 's'; 83 tmp[n+2] = 'h'; 84 tmp[n+3] = 0; 85 if ((n = open(tmp, O_CREAT|O_WRONLY, S_IRWXU|S_IRWXG|S_IRWXO)) < 0 || 86 chmod(tmp, S_IRWXU|S_IRWXG|S_IRWXO) < 0 || 87 write(n, "exit 99\n", 8) != 8 || 88 close(n) < 0) 89 { 90 NOTE("test script create FAILED"); 91 _exit(0); 92 } 93 cmd[0] = tmp; 94 n = 0; /* 0 means reject */ 95 pid = -1; 96 if (posix_spawn(&pid, cmd[0], 0, &attr, cmd, 0)) 97 { 98 n = 2; 99 NOTE("ENOEXEC produces posix_spawn() error (BEST)"); 100 } 101 else if (pid == -1) 102 NOTE("ENOEXEC returns pid == -1"); 103 else if (wait(&status) != pid) 104 NOTE("ENOEXEC produces no child process"); 105 else if (!WIFEXITED(status)) 106 NOTE("ENOEXEC produces signal exit"); 107 else 108 { 109 status = WEXITSTATUS(status); 110 if (status == 127) 111 { 112 n = 1; 113 NOTE("ENOEXEC produces exit status 127 (GOOD)"); 114 } 115 else if (status == 99) 116 NOTE("ENOEXEC invokes sh"); 117 else if (status == 0) 118 NOTE("ENOEXEC reports no error"); 119 else 120 NOTE("ENOEXEC produces non-zero exit status"); 121 } 122 _exit(n); 123 } 124}end 125 126tst lib_spawn_mode unistd.h stdlib.h note{ first spawn arg is mode and it works }end execute{ 127 #include <signal.h> 128 #include <process.h> 129 #ifndef P_NOWAIT 130 #define P_NOWAIT _P_NOWAIT 131 #endif 132 int 133 main(argc, argv) 134 int argc; 135 char** argv; 136 { 137 int status; 138 char* cmd[4]; 139 if (argv[2]) 140 _exit(signal(SIGHUP, SIG_DFL) != SIG_IGN); 141 signal(SIGHUP, SIG_IGN); 142 cmd[0] = argv[0]; 143 cmd[1] = argv[1]; 144 cmd[2] = "test"; 145 cmd[3] = 0; 146 if (spawnv(P_NOWAIT, cmd[0], cmd) < 0) 147 _exit(1); 148 status = 1; 149 _exit(wait(&status) < 0 || status != 0); 150 } 151}end 152 153tst use_spawn_exec note{ interpreter exec as efficient as fork() }end run{ 154 exit 1 155}end 156