driver.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  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. #include <sys/types.h>
  30. #include <sys/stat.h>
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <unistd.h>
  35. #include <errno.h>
  36. #include <err.h>
  37. #include "config.h"
  38. #include "test.h"
  39. ////////////////////////////////////////////////////////////
  40. static
  41. int
  42. finderror(int rv, int error)
  43. {
  44. if (rv==-1) {
  45. return error;
  46. }
  47. else {
  48. return 0;
  49. }
  50. }
  51. void
  52. report_survival(int rv, int error, const char *desc)
  53. {
  54. /* allow any error as long as we survive */
  55. errno = finderror(rv, error);
  56. warn("passed: %s", desc);
  57. }
  58. void
  59. report_test(int rv, int error, int right_error, const char *desc)
  60. {
  61. int goterror = finderror(rv, error);
  62. if (goterror == right_error) {
  63. warnx("passed: %s", desc);
  64. }
  65. else if (goterror == EUNIMP || goterror == ENOSYS) {
  66. warnx("------: %s (unimplemented)", desc);
  67. }
  68. else {
  69. errno = goterror;
  70. warn("FAILURE: %s", desc);
  71. }
  72. }
  73. void
  74. report_test2(int rv, int error, int okerr1, int okerr2, const char *desc)
  75. {
  76. int goterror = finderror(rv, error);
  77. if (goterror == okerr1 || goterror == okerr2) {
  78. warnx("passed: %s", desc);
  79. }
  80. else if (goterror == EUNIMP || goterror == ENOSYS) {
  81. warnx("------: %s (unimplemented)", desc);
  82. }
  83. else {
  84. errno = goterror;
  85. warn("FAILURE: %s", desc);
  86. }
  87. }
  88. ////////////////////////////////////////////////////////////
  89. int
  90. open_testfile(const char *string)
  91. {
  92. int fd, rv;
  93. size_t len;
  94. fd = open(TESTFILE, O_RDWR|O_CREAT|O_TRUNC);
  95. if (fd<0) {
  96. warn("UH-OH: creating %s: failed", TESTFILE);
  97. return -1;
  98. }
  99. if (string) {
  100. len = strlen(string);
  101. rv = write(fd, string, len);
  102. if (rv<0) {
  103. warn("UH-OH: write to %s failed", TESTFILE);
  104. close(fd);
  105. remove(TESTFILE);
  106. return -1;
  107. }
  108. if ((unsigned)rv != len) {
  109. warnx("UH-OH: write to %s got short count", TESTFILE);
  110. close(fd);
  111. remove(TESTFILE);
  112. return -1;
  113. }
  114. rv = lseek(fd, 0, SEEK_SET);
  115. if (rv<0) {
  116. warn("UH-OH: rewind of %s failed", TESTFILE);
  117. close(fd);
  118. remove(TESTFILE);
  119. return -1;
  120. }
  121. }
  122. return fd;
  123. }
  124. int
  125. create_testfile(void)
  126. {
  127. int fd, rv;
  128. fd = open_testfile(NULL);
  129. if (fd<0) {
  130. return -1;
  131. }
  132. rv = close(fd);
  133. if (rv<0) {
  134. warn("UH-OH: closing %s failed", TESTFILE);
  135. return -1;
  136. }
  137. return 0;
  138. }
  139. int
  140. create_testdir(void)
  141. {
  142. int rv;
  143. rv = mkdir(TESTDIR, 0775);
  144. if (rv<0) {
  145. warn("UH-OH: mkdir %s failed", TESTDIR);
  146. return -1;
  147. }
  148. return 0;
  149. }
  150. int
  151. create_testlink(void)
  152. {
  153. int rv;
  154. rv = symlink("blahblah", TESTLINK);
  155. if (rv<0) {
  156. warn("UH-OH: making symlink %s failed", TESTLINK);
  157. return -1;
  158. }
  159. return 0;
  160. }
  161. ////////////////////////////////////////////////////////////
  162. static
  163. struct {
  164. int ch;
  165. int asst;
  166. const char *name;
  167. void (*f)(void);
  168. } ops[] = {
  169. { 'a', 2, "execv", test_execv },
  170. { 'b', 2, "waitpid", test_waitpid },
  171. { 'c', 2, "open", test_open },
  172. { 'd', 2, "read", test_read },
  173. { 'e', 2, "write", test_write },
  174. { 'f', 2, "close", test_close },
  175. { 'g', 0, "reboot", test_reboot },
  176. { 'h', 3, "sbrk", test_sbrk },
  177. { 'i', 5, "ioctl", test_ioctl },
  178. { 'j', 2, "lseek", test_lseek },
  179. { 'k', 4, "fsync", test_fsync },
  180. { 'l', 4, "ftruncate", test_ftruncate },
  181. { 'm', 4, "fstat", test_fstat },
  182. { 'n', 4, "remove", test_remove },
  183. { 'o', 4, "rename", test_rename },
  184. { 'p', 5, "link", test_link },
  185. { 'q', 4, "mkdir", test_mkdir },
  186. { 'r', 4, "rmdir", test_rmdir },
  187. { 's', 2, "chdir", test_chdir },
  188. { 't', 4, "getdirentry", test_getdirentry },
  189. { 'u', 5, "symlink", test_symlink },
  190. { 'v', 5, "readlink", test_readlink },
  191. { 'w', 2, "dup2", test_dup2 },
  192. { 'x', 5, "pipe", test_pipe },
  193. { 'y', 5, "__time", test_time },
  194. { 'z', 2, "__getcwd", test_getcwd },
  195. { '{', 5, "stat", test_stat },
  196. { '|', 5, "lstat", test_lstat },
  197. { 0, 0, NULL, NULL }
  198. };
  199. #define LOWEST 'a'
  200. #define HIGHEST '|'
  201. static
  202. void
  203. menu(void)
  204. {
  205. int i;
  206. for (i=0; ops[i].name; i++) {
  207. printf("[%c] %-24s", ops[i].ch, ops[i].name);
  208. if (i%2==1) {
  209. printf("\n");
  210. }
  211. }
  212. if (i%2==1) {
  213. printf("\n");
  214. }
  215. printf("[1] %-24s", "asst1");
  216. printf("[2] %-24s\n", "asst2");
  217. printf("[3] %-24s", "asst3");
  218. printf("[4] %-24s\n", "asst4");
  219. printf("[*] %-24s", "all");
  220. printf("[!] %-24s\n", "quit");
  221. }
  222. static
  223. void
  224. runit(int op)
  225. {
  226. int i, k;
  227. if (op=='!') {
  228. exit(0);
  229. }
  230. if (op=='?') {
  231. menu();
  232. return;
  233. }
  234. if (op=='*') {
  235. for (i=0; ops[i].name; i++) {
  236. printf("[%s]\n", ops[i].name);
  237. ops[i].f();
  238. }
  239. return;
  240. }
  241. if (op>='1' && op <= '4') {
  242. k = op-'0';
  243. for (i=0; ops[i].name; i++) {
  244. if (ops[i].asst <= k) {
  245. printf("[%s]\n", ops[i].name);
  246. ops[i].f();
  247. }
  248. }
  249. return;
  250. }
  251. if (op < LOWEST || op > HIGHEST) {
  252. printf("Invalid request %c\n", op);
  253. return;
  254. }
  255. ops[op-'a'].f();
  256. }
  257. int
  258. main(int argc, char **argv)
  259. {
  260. int op, i, j;
  261. printf("[%c-%c, 1-4, *, ?=menu, !=quit]\n", LOWEST, HIGHEST);
  262. if (argc > 1) {
  263. for (i=1; i<argc; i++) {
  264. for (j=0; argv[i][j]; j++) {
  265. printf("Choose: %c\n",
  266. argv[i][j]);
  267. runit(argv[i][j]);
  268. }
  269. }
  270. }
  271. else {
  272. menu();
  273. while (1) {
  274. printf("Choose: ");
  275. op = getchar();
  276. if (op==EOF) {
  277. break;
  278. }
  279. printf("%c\n", op);
  280. runit(op);
  281. }
  282. }
  283. return 0;
  284. }