00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <sys/types.h>
00035 #include <stdlib.h>
00036 #include <unistd.h>
00037 #include <errno.h>
00038 #include <err.h>
00039
00040 #include "config.h"
00041 #include "test.h"
00042
00043 static
00044 void
00045 wait_badpid(int pid, const char *desc)
00046 {
00047 int rv, x;
00048 rv = waitpid(pid, &x, 0);
00049 report_test2(rv, errno, EINVAL, NOSUCHPID_ERROR, desc);
00050 }
00051
00052 static
00053 void
00054 wait_badstatus(void *ptr, const char *desc)
00055 {
00056 int rv, pid, x;
00057
00058 pid = fork();
00059 if (pid<0) {
00060 warn("UH-OH: fork failed");
00061 return;
00062 }
00063 if (pid==0) {
00064 exit(0);
00065 }
00066
00067 rv = waitpid(pid, ptr, 0);
00068 report_test(rv, errno, EFAULT, desc);
00069 waitpid(pid, &x, 0);
00070 }
00071
00072 static
00073 void
00074 wait_unaligned(void)
00075 {
00076 int rv, pid, x;
00077 int status[2];
00078 char *ptr;
00079
00080 pid = fork();
00081 if (pid<0) {
00082 warn("UH-OH: fork failed");
00083 return;
00084 }
00085 if (pid==0) {
00086 exit(0);
00087 }
00088
00089
00090 ptr = (char *)(&status[0]);
00091
00092
00093 ptr++;
00094
00095 rv = waitpid(pid, (int *)ptr, 0);
00096 report_survival(rv, errno, "wait with unaligned status");
00097 if (rv<0) {
00098 waitpid(pid, &x, 0);
00099 }
00100 }
00101
00102 static
00103 void
00104 wait_badflags(void)
00105 {
00106 int rv, x, pid;
00107
00108 pid = fork();
00109 if (pid<0) {
00110 warn("UH-OH: fork failed");
00111 return;
00112 }
00113 if (pid==0) {
00114 exit(0);
00115 }
00116
00117 rv = waitpid(pid, &x, 309429);
00118 report_test(rv, errno, EINVAL, "wait with bad flags");
00119 waitpid(pid, &x, 0);
00120 }
00121
00122 static
00123 void
00124 wait_self(void)
00125 {
00126 int rv, x;
00127 rv = waitpid(getpid(), &x, 0);
00128 report_survival(rv, errno, "wait for self");
00129 }
00130
00131 static
00132 void
00133 wait_parent(void)
00134 {
00135 int mypid, childpid, rv, x;
00136
00137 mypid = getpid();
00138 childpid = fork();
00139 if (childpid<0) {
00140 warn("UH-OH: can't fork");
00141 return;
00142 }
00143 if (childpid==0) {
00144
00145 rv = waitpid(mypid, &x, 0);
00146 report_survival(rv, errno, "wait for parent (from child)");
00147 _exit(0);
00148 }
00149 rv = waitpid(childpid, &x, 0);
00150 report_survival(rv, errno, "wait for parent test (from parent)");
00151 }
00152
00153
00154
00155 static
00156 void
00157 wait_siblings_child(void)
00158 {
00159 int pids[2], mypid, otherpid, fd, rv, x;
00160
00161 mypid = getpid();
00162
00163 fd = open(TESTFILE, O_RDONLY);
00164 if (fd<0) {
00165 warn("UH-OH: child process (pid %d) can't open %s",
00166 mypid, TESTFILE);
00167 return;
00168 }
00169
00170
00171
00172
00173
00174 do {
00175 rv = lseek(fd, 0, SEEK_SET);
00176 if (rv<0) {
00177 warn("UH-OH: child process (pid %d) lseek error",
00178 mypid);
00179 return;
00180 }
00181 rv = read(fd, pids, sizeof(pids));
00182 if (rv<0) {
00183 warn("UH-OH: child process (pid %d) read error",
00184 mypid);
00185 return;
00186 }
00187 } while (rv < (int)sizeof(pids));
00188
00189 if (mypid==pids[0]) {
00190 otherpid = pids[1];
00191 }
00192 else if (mypid==pids[1]) {
00193 otherpid = pids[0];
00194 }
00195 else {
00196 warn("UH-OH: child process (pid %d) got garbage in comm file",
00197 mypid);
00198 return;
00199 }
00200 close(fd);
00201
00202 rv = waitpid(otherpid, &x, 0);
00203 report_survival(rv, errno, "sibling wait");
00204 }
00205
00206 static
00207 void
00208 wait_siblings(void)
00209 {
00210 int pids[2], fd, rv, x;
00211
00212
00213
00214 fd = open_testfile(NULL);
00215 if (fd<0) {
00216 return;
00217 }
00218
00219 pids[0] = fork();
00220 if (pids[0]<0) {
00221 warn("UH-OH: can't fork");
00222 return;
00223 }
00224 if (pids[0]==0) {
00225 close(fd);
00226 wait_siblings_child();
00227 _exit(0);
00228 }
00229
00230 pids[1] = fork();
00231 if (pids[1]<0) {
00232 warn("UH-OH: can't fork");
00233
00234 return;
00235 }
00236 if (pids[1]==0) {
00237 close(fd);
00238 wait_siblings_child();
00239 _exit(0);
00240 }
00241
00242 rv = write(fd, pids, sizeof(pids));
00243 if (rv < 0) {
00244 warn("UH-OH: write error on %s", TESTFILE);
00245
00246 return;
00247 }
00248 if (rv != (int)sizeof(pids)) {
00249 warnx("UH-OH: write error on %s: short count", TESTFILE);
00250
00251 return;
00252 }
00253
00254 rv = waitpid(pids[0], &x, 0);
00255 if (rv<0) {
00256 warn("UH-OH: error waiting for child 0 (pid %d)", pids[0]);
00257 }
00258 rv = waitpid(pids[1], &x, 0);
00259 if (rv<0) {
00260 warn("UH-OH: error waiting for child 1 (pid %d)", pids[1]);
00261 }
00262 warnx("passed: siblings wait for each other");
00263 close(fd);
00264 remove(TESTFILE);
00265 }
00266
00267
00268
00269 void
00270 test_waitpid(void)
00271 {
00272 wait_badpid(-8, "wait for pid -8");
00273 wait_badpid(-1, "wait for pid -1");
00274 wait_badpid(0, "pid zero");
00275 wait_badpid(NONEXIST_PID, "nonexistent pid");
00276
00277 wait_badstatus(NULL, "wait with NULL status");
00278 wait_badstatus(INVAL_PTR, "wait with invalid pointer status");
00279 wait_badstatus(KERN_PTR, "wait with kernel pointer status");
00280
00281 wait_unaligned();
00282
00283 wait_badflags();
00284
00285 wait_self();
00286 wait_parent();
00287 wait_siblings();
00288 }