bad_waitpid.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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. * bad calls to waitpid()
  31. */
  32. #include <sys/types.h>
  33. #include <stdlib.h>
  34. #include <unistd.h>
  35. #include <errno.h>
  36. #include <err.h>
  37. #include "config.h"
  38. #include "test.h"
  39. static
  40. void
  41. wait_badpid(int pid, const char *desc)
  42. {
  43. int rv, x;
  44. rv = waitpid(pid, &x, 0);
  45. report_test2(rv, errno, EINVAL, NOSUCHPID_ERROR, desc);
  46. }
  47. static
  48. void
  49. wait_badstatus(void *ptr, const char *desc)
  50. {
  51. int rv, pid, x;
  52. pid = fork();
  53. if (pid<0) {
  54. warn("UH-OH: fork failed");
  55. return;
  56. }
  57. if (pid==0) {
  58. exit(0);
  59. }
  60. rv = waitpid(pid, ptr, 0);
  61. report_test(rv, errno, EFAULT, desc);
  62. waitpid(pid, &x, 0);
  63. }
  64. static
  65. void
  66. wait_unaligned(void)
  67. {
  68. int rv, pid, x;
  69. int status[2]; /* will have integer alignment */
  70. char *ptr;
  71. pid = fork();
  72. if (pid<0) {
  73. warn("UH-OH: fork failed");
  74. return;
  75. }
  76. if (pid==0) {
  77. exit(0);
  78. }
  79. /* start with proper integer alignment */
  80. ptr = (char *)(&status[0]);
  81. /* generate improper alignment on platforms with restrictions*/
  82. ptr++;
  83. rv = waitpid(pid, (int *)ptr, 0);
  84. report_survival(rv, errno, "wait with unaligned status");
  85. if (rv<0) {
  86. waitpid(pid, &x, 0);
  87. }
  88. }
  89. static
  90. void
  91. wait_badflags(void)
  92. {
  93. int rv, x, pid;
  94. pid = fork();
  95. if (pid<0) {
  96. warn("UH-OH: fork failed");
  97. return;
  98. }
  99. if (pid==0) {
  100. exit(0);
  101. }
  102. rv = waitpid(pid, &x, 309429);
  103. report_test(rv, errno, EINVAL, "wait with bad flags");
  104. waitpid(pid, &x, 0);
  105. }
  106. static
  107. void
  108. wait_self(void)
  109. {
  110. int rv, x;
  111. rv = waitpid(getpid(), &x, 0);
  112. report_survival(rv, errno, "wait for self");
  113. }
  114. static
  115. void
  116. wait_parent(void)
  117. {
  118. int mypid, childpid, rv, x;
  119. mypid = getpid();
  120. childpid = fork();
  121. if (childpid<0) {
  122. warn("UH-OH: can't fork");
  123. return;
  124. }
  125. if (childpid==0) {
  126. /* Child. Wait for parent. */
  127. rv = waitpid(mypid, &x, 0);
  128. report_survival(rv, errno, "wait for parent (from child)");
  129. _exit(0);
  130. }
  131. rv = waitpid(childpid, &x, 0);
  132. report_survival(rv, errno, "wait for parent test (from parent)");
  133. }
  134. ////////////////////////////////////////////////////////////
  135. static
  136. void
  137. wait_siblings_child(void)
  138. {
  139. int pids[2], mypid, otherpid, fd, rv, x;
  140. mypid = getpid();
  141. fd = open(TESTFILE, O_RDONLY);
  142. if (fd<0) {
  143. warn("UH-OH: child process (pid %d) can't open %s",
  144. mypid, TESTFILE);
  145. return;
  146. }
  147. /*
  148. * Busy-wait until the parent writes the pids into the file.
  149. * This sucks, but there's not a whole lot else we can do.
  150. */
  151. do {
  152. rv = lseek(fd, 0, SEEK_SET);
  153. if (rv<0) {
  154. warn("UH-OH: child process (pid %d) lseek error",
  155. mypid);
  156. return;
  157. }
  158. rv = read(fd, pids, sizeof(pids));
  159. if (rv<0) {
  160. warn("UH-OH: child process (pid %d) read error",
  161. mypid);
  162. return;
  163. }
  164. } while (rv < (int)sizeof(pids));
  165. if (mypid==pids[0]) {
  166. otherpid = pids[1];
  167. }
  168. else if (mypid==pids[1]) {
  169. otherpid = pids[0];
  170. }
  171. else {
  172. warn("UH-OH: child process (pid %d) got garbage in comm file",
  173. mypid);
  174. return;
  175. }
  176. close(fd);
  177. rv = waitpid(otherpid, &x, 0);
  178. report_survival(rv, errno, "sibling wait");
  179. }
  180. static
  181. void
  182. wait_siblings(void)
  183. {
  184. int pids[2], fd, rv, x;
  185. /* Note: this may also blow up if FS synchronization is substandard */
  186. fd = open_testfile(NULL);
  187. if (fd<0) {
  188. return;
  189. }
  190. pids[0] = fork();
  191. if (pids[0]<0) {
  192. warn("UH-OH: can't fork");
  193. return;
  194. }
  195. if (pids[0]==0) {
  196. close(fd);
  197. wait_siblings_child();
  198. _exit(0);
  199. }
  200. pids[1] = fork();
  201. if (pids[1]<0) {
  202. warn("UH-OH: can't fork");
  203. /* abandon the other child process :( */
  204. return;
  205. }
  206. if (pids[1]==0) {
  207. close(fd);
  208. wait_siblings_child();
  209. _exit(0);
  210. }
  211. rv = write(fd, pids, sizeof(pids));
  212. if (rv < 0) {
  213. warn("UH-OH: write error on %s", TESTFILE);
  214. /* abandon child procs :( */
  215. return;
  216. }
  217. if (rv != (int)sizeof(pids)) {
  218. warnx("UH-OH: write error on %s: short count", TESTFILE);
  219. /* abandon child procs :( */
  220. return;
  221. }
  222. rv = waitpid(pids[0], &x, 0);
  223. if (rv<0) {
  224. warn("UH-OH: error waiting for child 0 (pid %d)", pids[0]);
  225. }
  226. rv = waitpid(pids[1], &x, 0);
  227. if (rv<0) {
  228. warn("UH-OH: error waiting for child 1 (pid %d)", pids[1]);
  229. }
  230. warnx("passed: siblings wait for each other");
  231. close(fd);
  232. remove(TESTFILE);
  233. }
  234. ////////////////////////////////////////////////////////////
  235. void
  236. test_waitpid(void)
  237. {
  238. wait_badpid(-8, "wait for pid -8");
  239. wait_badpid(-1, "wait for pid -1");
  240. wait_badpid(0, "pid zero");
  241. wait_badpid(NONEXIST_PID, "nonexistent pid");
  242. wait_badstatus(NULL, "wait with NULL status");
  243. wait_badstatus(INVAL_PTR, "wait with invalid pointer status");
  244. wait_badstatus(KERN_PTR, "wait with kernel pointer status");
  245. wait_unaligned();
  246. wait_badflags();
  247. wait_self();
  248. wait_parent();
  249. wait_siblings();
  250. }