root/user/testbin/badcall/bad_waitpid.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wait_badpid
  2. wait_badstatus
  3. wait_unaligned
  4. wait_badflags
  5. wait_self
  6. wait_parent
  7. wait_siblings_child
  8. wait_siblings
  9. test_waitpid

   1 /*
   2  * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
   3  *      The President and Fellows of Harvard College.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 1. Redistributions of source code must retain the above copyright
   9  *    notice, this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright
  11  *    notice, this list of conditions and the following disclaimer in the
  12  *    documentation and/or other materials provided with the distribution.
  13  * 3. Neither the name of the University nor the names of its contributors
  14  *    may be used to endorse or promote products derived from this software
  15  *    without specific prior written permission.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
  18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
  21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  */
  29 
  30 /*
  31  * bad calls to waitpid()
  32  */
  33 
  34 #include <sys/types.h>
  35 #include <stdlib.h>
  36 #include <unistd.h>
  37 #include <errno.h>
  38 #include <err.h>
  39 
  40 #include "config.h"
  41 #include "test.h"
  42 
  43 static
  44 void
  45 wait_badpid(int pid, const char *desc)
  46 {
  47         int rv, x;
  48         rv = waitpid(pid, &x, 0);
  49         report_test2(rv, errno, EINVAL, NOSUCHPID_ERROR, desc);
  50 }
  51 
  52 static
  53 void
  54 wait_badstatus(void *ptr, const char *desc)
  55 {
  56         int rv, pid, x;
  57 
  58         pid = fork();
  59         if (pid<0) {
  60                 warn("UH-OH: fork failed");
  61                 return;
  62         }
  63         if (pid==0) {
  64                 exit(0);
  65         }
  66 
  67         rv = waitpid(pid, ptr, 0);
  68         report_test(rv, errno, EFAULT, desc);
  69         waitpid(pid, &x, 0);
  70 }
  71 
  72 static
  73 void
  74 wait_unaligned(void)
  75 {
  76         int rv, pid, x;
  77         int status[2];  /* will have integer alignment */
  78         char *ptr;
  79 
  80         pid = fork();
  81         if (pid<0) {
  82                 warn("UH-OH: fork failed");
  83                 return;
  84         }
  85         if (pid==0) {
  86                 exit(0);
  87         }
  88 
  89         /* start with proper integer alignment */
  90         ptr = (char *)(&status[0]);
  91 
  92         /* generate improper alignment on platforms with restrictions*/
  93         ptr++;
  94 
  95         rv = waitpid(pid, (int *)ptr, 0);
  96         report_survival(rv, errno, "wait with unaligned status");
  97         if (rv<0) {
  98                 waitpid(pid, &x, 0);
  99         }
 100 }
 101 
 102 static
 103 void
 104 wait_badflags(void)
 105 {
 106         int rv, x, pid;
 107 
 108         pid = fork();
 109         if (pid<0) {
 110                 warn("UH-OH: fork failed");
 111                 return;
 112         }
 113         if (pid==0) {
 114                 exit(0);
 115         }
 116 
 117         rv = waitpid(pid, &x, 309429);
 118         report_test(rv, errno, EINVAL, "wait with bad flags");
 119         waitpid(pid, &x, 0);
 120 }
 121 
 122 static
 123 void
 124 wait_self(void)
 125 {
 126         int rv, x;
 127         rv = waitpid(getpid(), &x, 0);
 128         report_survival(rv, errno, "wait for self");
 129 }
 130 
 131 static
 132 void
 133 wait_parent(void)
 134 {
 135         int mypid, childpid, rv, x;
 136 
 137         mypid = getpid();
 138         childpid = fork();
 139         if (childpid<0) {
 140                 warn("UH-OH: can't fork");
 141                 return;
 142         }
 143         if (childpid==0) {
 144                 /* Child. Wait for parent. */
 145                 rv = waitpid(mypid, &x, 0);
 146                 report_survival(rv, errno, "wait for parent (from child)");
 147                 _exit(0);
 148         }
 149         rv = waitpid(childpid, &x, 0);
 150         report_survival(rv, errno, "wait for parent test (from parent)");
 151 }
 152 
 153 ////////////////////////////////////////////////////////////
 154 
 155 static
 156 void
 157 wait_siblings_child(void)
 158 {
 159         int pids[2], mypid, otherpid, fd, rv, x;
 160 
 161         mypid = getpid();
 162 
 163         fd = open(TESTFILE, O_RDONLY);
 164         if (fd<0) {
 165                 warn("UH-OH: child process (pid %d) can't open %s",
 166                      mypid, TESTFILE);
 167                 return;
 168         }
 169 
 170         /*
 171          * Busy-wait until the parent writes the pids into the file.
 172          * This sucks, but there's not a whole lot else we can do.
 173          */
 174         do {
 175                 rv = lseek(fd, 0, SEEK_SET);
 176                 if (rv<0) {
 177                         warn("UH-OH: child process (pid %d) lseek error",
 178                              mypid);
 179                         return;
 180                 }
 181                 rv = read(fd, pids, sizeof(pids));
 182                 if (rv<0) {
 183                         warn("UH-OH: child process (pid %d) read error",
 184                              mypid);
 185                         return;
 186                 }
 187         } while (rv < (int)sizeof(pids));
 188 
 189         if (mypid==pids[0]) {
 190                 otherpid = pids[1];
 191         }
 192         else if (mypid==pids[1]) {
 193                 otherpid = pids[0];
 194         }
 195         else {
 196                 warn("UH-OH: child process (pid %d) got garbage in comm file",
 197                      mypid);
 198                 return;
 199         }
 200         close(fd);
 201 
 202         rv = waitpid(otherpid, &x, 0);
 203         report_survival(rv, errno, "sibling wait");
 204 }
 205 
 206 static
 207 void
 208 wait_siblings(void)
 209 {
 210         int pids[2], fd, rv, x;
 211 
 212         /* Note: this may also blow up if FS synchronization is substandard */
 213 
 214         fd = open_testfile(NULL);
 215         if (fd<0) {
 216                 return;
 217         }
 218 
 219         pids[0] = fork();
 220         if (pids[0]<0) {
 221                 warn("UH-OH: can't fork");
 222                 return;
 223         }
 224         if (pids[0]==0) {
 225                 close(fd);
 226                 wait_siblings_child();
 227                 _exit(0);
 228         }
 229 
 230         pids[1] = fork();
 231         if (pids[1]<0) {
 232                 warn("UH-OH: can't fork");
 233                 /* abandon the other child process :( */
 234                 return;
 235         }
 236         if (pids[1]==0) {
 237                 close(fd);
 238                 wait_siblings_child();
 239                 _exit(0);
 240         }
 241 
 242         rv = write(fd, pids, sizeof(pids));
 243         if (rv < 0) {
 244                 warn("UH-OH: write error on %s", TESTFILE);
 245                 /* abandon child procs :( */
 246                 return;
 247         }
 248         if (rv != (int)sizeof(pids)) {
 249                 warnx("UH-OH: write error on %s: short count", TESTFILE);
 250                 /* abandon child procs :( */
 251                 return;
 252         }
 253 
 254         rv = waitpid(pids[0], &x, 0);
 255         if (rv<0) {
 256                 warn("UH-OH: error waiting for child 0 (pid %d)", pids[0]);
 257         }
 258         rv = waitpid(pids[1], &x, 0);
 259         if (rv<0) {
 260                 warn("UH-OH: error waiting for child 1 (pid %d)", pids[1]);
 261         }
 262         warnx("passed: siblings wait for each other");
 263         close(fd);
 264         remove(TESTFILE);
 265 }
 266 
 267 ////////////////////////////////////////////////////////////
 268 
 269 void
 270 test_waitpid(void)
 271 {
 272         wait_badpid(-8, "wait for pid -8");
 273         wait_badpid(-1, "wait for pid -1");
 274         wait_badpid(0, "pid zero");
 275         wait_badpid(NONEXIST_PID, "nonexistent pid");
 276 
 277         wait_badstatus(NULL, "wait with NULL status");
 278         wait_badstatus(INVAL_PTR, "wait with invalid pointer status");
 279         wait_badstatus(KERN_PTR, "wait with kernel pointer status");
 280 
 281         wait_unaligned();
 282 
 283         wait_badflags();
 284 
 285         wait_self();
 286         wait_parent();
 287         wait_siblings();
 288 }

/* [<][>][^][v][top][bottom][index][help] */