2 #define _XOPEN_SOURCE 600
12 #include <sys/statvfs.h>
14 #include <sys/queue.h>
22 #include "test_driver.h"
27 typedef struct cmd_tree_t {
31 struct queue_t *children;
40 struct cmd_t cmd_list[] = {
41 {"alloc", get_buffer, usage_get_buffer},
42 {"chdir", test_do_chdir, usage_chdir},
43 {"checkbuf", do_checkbuf, usage_checkbuf},
44 {"chmod", test_do_chmod, usage_chmod},
45 {"chown", test_do_chown, usage_chown},
46 {"clear", test_do_clear, usage_clear},
47 {"close", test_do_close, usage_close},
48 {"cmpstr", cmp_bufs, usage_cmpbufs},
49 {"creat", test_do_creat, usage_creat},
50 {"debug", test_do_setdebug, usage_setdebug},
51 {"dup", test_do_dup, usage_dup},
52 {"dup2", test_do_dup2, usage_dup2},
53 {"endian", get_endian, usage_endian},
54 {"exit", test_do_exit, usage_exit},
55 {"fcntl", test_do_fcntl, usage_fcntl},
56 {"fdatasync", test_do_fdatasync, usage_fdatasync},
57 {"fill", test_do_fillbuff, usage_do_fillbuff},
58 {"free", free_buffer, usage_free_buffer},
59 {"fstat", test_do_fstat, usage_fstat},
60 {"fstatvfs", test_do_fstatvfs, usage_fstatvfs},
61 {"fsync", test_do_fsync, usage_fsync},
62 {"ftruncate", test_do_ftruncate, usage_ftruncate},
63 {"getcwd", test_do_getcwd, usage_getcwd},
64 {"getdirentries", test_do_getdirentries, usage_getdirentries},
65 {"init", test_do_init, usage_init},
66 {"init_iovec", test_do_init_iovec, usage_init_iovec},
67 {"init_xtvec", test_do_init_xtvec, usage_init_xtvec},
68 {"ioctl", test_do_ioctl, usage_ioctl},
69 {"iodone", test_do_iodone, usage_iodone},
70 {"iowait", test_do_iowait, usage_iowait},
71 {"ipread", test_do_ipread, usage_ipread},
72 {"ipreadv", test_do_ipreadv, usage_ipreadv},
73 {"ipwrite", test_do_ipwrite, usage_ipwrite},
74 {"ipwritev", test_do_ipwritev, usage_ipwritev},
75 {"iread", test_do_iread, usage_iread},
76 {"ireadv", test_do_ireadv, usage_ireadv},
77 {"ireadx", test_do_ireadx, usage_ireadx},
78 {"iwrite", test_do_iwrite, usage_iwrite},
79 {"iwritev", test_do_iwritev, usage_iwritev},
80 {"iwritex", test_do_iwritex, usage_iwritex},
81 {"list", test_do_list, usage_list},
82 {"lseek", test_do_lseek, usage_lseek},
83 {"lstat", test_do_lstat, usage_lstat},
84 {"mkdir", test_do_mkdir, usage_mkdir},
85 {"mknod", test_do_mknod, usage_mknod},
86 {"mount", test_do_mount, usage_mount},
87 {"open", test_do_open, usage_open},
88 {"printbuf", test_do_printbuf, usage_do_printbuf},
89 {"printline", test_do_printline, usage_printline},
90 {"pread", test_do_pread, usage_pread},
91 {"preadv", test_do_preadv, usage_preadv},
92 {"pwritev", test_do_pwritev, usage_pwritev},
93 {"pwrite", test_do_pwrite, usage_pwrite},
94 {"quit", test_do_exit, usage_exit},
95 {"read", test_do_read, usage_read},
96 {"readv", test_do_readv, usage_readv},
97 {"readx", test_do_readx, usage_readx},
98 {"rmdir", test_do_rmdir, usage_rmdir},
99 {"setbuf", do_setbuf, usage_setbuf},
100 {"sizeof", get_sizeof, usage_sizeof},
101 /* {"setoutput", test_do_setoutput, usage_setoutput}, */
102 {"stat", test_do_stat, usage_stat},
103 {"statvfs", test_do_statvfs, usage_statvfs},
104 {"symlink", test_do_symlink, usage_symlink},
105 {"truncate", test_do_truncate, usage_truncate},
106 {"umask", test_do_umask, usage_umask},
107 {"umount", test_do_umount, usage_umount},
108 {"unlink", test_do_unlink, usage_unlink},
109 {"write", test_do_write, usage_write},
110 {"writev", test_do_writev, usage_writev},
111 {"writex", test_do_writex, usage_writex},
115 int run_cmd(cmd_tree *cmd_arg);
116 cmd_tree* build_tree(char **cmd, int *length, int total);
118 * ##################################################
119 * # Memory functions #
120 * # Intended to allow users to gain access to #
121 * # buffers of memory to be manipulated later #
122 * ##################################################
125 void * alloc_buff32(unsigned int size, int align)
131 if ((err = memalign(&buf, align, size)) != 0) {
139 DBG(3, fprintf(outfp, "Buf is at %p\n", (void *)buf));
140 buf_ptr = (long)buf + ((long)buf & align);
142 DBG(3, fprintf(outfp, "Buf is at %p\n", (void *)buf_ptr));
143 return (void *)buf_ptr;
146 void free_buf32(void * ptr)
151 long alloc_buff64(unsigned int size, int align)
157 if (memalign((void **)&buf, align, size))
163 ret_value = (long)buf + ((long)buf & align);
167 void free_buf64(long ptr)
174 * Hash function for variables. Shamelessly stolen
177 unsigned int dx_hack_hash (const char *name, int len)
179 unsigned int hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
182 unsigned int hash = hash1 + (hash0 ^ (*name++ * 7152373));
183 if (hash & 0x80000000) hash -= 0x7fffffff;
190 struct var_mapping *get_map(char *var_name)
193 struct var_mapping_list *curr;
196 if (var_name[0] == '$') {
197 /* It is a name--chop off the initial and get the mapping $ */
201 index = dx_hack_hash(var_name, strlen(var_name));
202 index %= MAX_VARS -1;
204 DBG(5, fprintf(outfp, "Got index of %d for %s\n", index, var_name));
207 while ((curr) && (curr->map.obj != -1) ) {
208 if ( (curr->map.name == NULL) || (strcmp(curr->map.name, var_name)) )
217 char *get_str(char *var_name)
219 /* See if it is a quoted string */
220 if (var_name[0] == '"') {
221 /* Chop off the beginning and end quotes and return the string */
222 int len = strlen(var_name);
223 var_name[len-1] = '\0';
231 get_or_part(char **str, int* did_alloc)
233 char *tmp_str = *str;
239 if (tmp_str[0] == '|') {
244 for (i=0; (unsigned int)i < strlen(tmp_str); i++) {
245 if (tmp_str[i] == '|') {
246 char *new_str = (char *)malloc(i+1);
247 memcpy(new_str, tmp_str, i);
264 int get_obj(char *var_name)
266 char** str = &var_name;
268 struct var_mapping *var_map;
270 int obj=0, got_obj=0;
272 DBG(5, fprintf(outfp, "Getting object for %s\n", var_name));
274 /* If var_name is a digit, we assume it is a literal */
275 if (isdigit(var_name[0]))
276 return atoi(var_name);
279 * Check for '|', indicates that one or more values are or'd
282 while ((str1 = get_or_part(str, &did_alloc)) != NULL) {
284 if (isdigit(str1[0])) {
285 if (str1[0] == '0') {
286 /* Assume octal format */
287 obj |= strtol(str1, NULL, 8);
291 var_map = get_map(str1);
310 var_map = get_map(var_name);
318 void store_result(char *var_name, int result)
320 int index = dx_hack_hash(var_name, strlen(var_name));
321 struct var_mapping_list *map_obj;
322 struct var_mapping_list *new_map;
323 index %= MAX_VARS -1 ;
325 if (map[index].map.obj >= 0) {
327 /* Got a collision --just chain it*/
328 new_map = malloc(sizeof(struct var_mapping_list));
330 map_obj = &map[index];
331 while (map_obj->next != NULL)
332 map_obj = map_obj->next;
334 map_obj->next = new_map;
336 new_map = &map[index];
338 new_map->map.name = malloc(strlen(var_name) + 1);
339 strcpy(new_map->map.name, var_name);
340 new_map->map.obj = result;
341 new_map->map.type = last_type;
342 new_map->next = NULL;
343 DBG(3, fprintf(outfp, "Stored %d in index %d hashed with %s\n",
344 result, index, var_name));
347 void free_obj(char *obj_name)
350 struct var_mapping_list *prev, *curr;
353 /* See if it is a variable name */
354 if (obj_name[0] == '$') {
355 /* It is a name--chop off the initial $ */
358 index = dx_hack_hash(obj_name, strlen(obj_name));
359 index %= MAX_VARS -1;
361 DBG(5, fprintf(outfp, "Got index of %d\n", index));
366 while ((curr) && (curr->map.obj != -1) ) {
367 if (strcmp(curr->map.name, obj_name)) {
374 /* Remove the object from the chain */
376 prev->next = curr->next;
379 free(curr->map.name);
386 * Given a long string, returns the string divided into
387 * whitespace seperated words in list. Returns the number
390 int parser(char *str, char** list)
392 int len, i=0, j=0, counter=-1;
398 DBG(5, fprintf(outfp, "str is %s len is %d\n", str, len));
401 if ((i==0) || ((str[i] == ' ') && (in_quotes == 0)) ) {
404 DBG(5, fprintf(outfp, "Got word %s\n", list[counter]));
407 while ((str[i] == ' ') && (in_quotes == 0))
410 new_str = list[counter] = malloc(MAX_WORD);
422 if ((str[i] == ' ') && (in_quotes==0)){
423 while (str[i+1] == ' ')
432 DBG(5, fprintf(outfp, "Got word %s\n", list[counter]));
437 int execute_cmd(char *cmd, char **args, int arg_count)
441 if (!strcmp(cmd, "help")) {
443 while(cmd_list[i].cmd != NULL) {
444 if (!strcmp(cmd_list[i].cmd, args[0])) {
445 (cmd_list[i].usage)();
456 while(cmd_list[i].cmd != NULL) {
457 if (!strcmp(cmd_list[i].cmd, cmd)) {
458 return (cmd_list[i].func)(arg_count, args);
462 DBG(2, fprintf(outfp, "Command %s was invalid\n", cmd));
466 int get_args(struct queue_t *child, char** list, int num_args, int argnum)
470 if (child->val != NULL) {
472 } else if (child->cmd != NULL) {
474 if (child->cmd->res_name != NULL)
475 argval = child->cmd->res_name;
478 int val = last_ret_val;
479 sprintf(tmpstr, "%x", val);
483 DBG(2, fprintf(outfp, "I am confused\n"));
487 list[argnum] = malloc(strlen(argval) + 1);
488 strcpy(list[argnum], argval);
491 if (argnum == num_args)
493 else if (child->next == NULL) {
494 DBG(2, fprintf(outfp, "Only on arg number %d out of %d, but ran out of children\n",
498 return get_args(child->next, list, num_args, argnum);
503 int run_cmd(cmd_tree *cmd_arg)
505 char cmdstr[MAX_COMMAND];
511 struct queue_t *child;
518 child = cmd_arg->children;
519 if ( (!strcmp("exit", cmd)) || (!strcmp("quit", cmd)) ||
520 (!strcmp("EXIT", cmd)) || (!strcmp("QUIT", cmd)) )
521 strcpy(cmdstr, "exit");
522 else if (!strcmp("ALLOC", cmd))
523 strcpy(cmdstr, "alloc");
524 else if (!strcmp("FREE", cmd))
525 strcpy(cmdstr, "free");
526 else if (!strcmp("HELP", cmd))
527 strcpy(cmdstr, "help");
528 else if (!strcmp("CALL", cmd)) {
529 if (cmd_arg->arg_count < 1) {
530 DBG(2, fprintf(outfp, "Need at least one command\n"));
534 cmd_arg->arg_count--;
535 if (child->val != NULL)
538 DBG(2, fprintf(outfp, "Need to specify command\n"));
542 DBG(3, fprintf(outfp, "Got cmd %s\n", child->val));
543 if (cmd_arg->arg_count != 0)
547 } else if (!strcmp("DEPOSIT", cmd))
548 strcpy(cmdstr, "fill");
549 else if (!strcmp("PRINT", cmd))
550 strcpy(cmdstr, "printbuf");
552 if (cmd_arg->res_name != NULL) {
554 * If the cmd is not a valid command, just store it
556 res = get_obj(cmd_arg->children->val);
559 /* Just store it as a string */
560 buf = (struct buf_t *)malloc(sizeof(struct buf_t));
561 buf->len = strlen(cmd);
562 buf->buf = (char *)malloc(buf->len+1);
563 strcpy(buf->buf, cmd_arg->children->val);
566 DBG(3, fprintf(outfp, "Stored %s in index %d\n", (char *)buf->buf, next));
570 store_result(cmd_arg->res_name, res);
577 if (cmd_arg->arg_count == 0)
580 args = (char **)malloc(sizeof(char *)*cmd_arg->arg_count);
581 get_args(child, args, cmd_arg->arg_count, 0);
584 DBG(3, fprintf(outfp, "CMD: %s\n ARGS: ",cmdptr));
585 for (i=0; i < cmd_arg->arg_count; i++)
586 DBG(3, fprintf(outfp, "%s ", args[i]));
587 DBG(3, fprintf(outfp, "\n"));
588 res = execute_cmd(cmdptr, args, cmd_arg->arg_count);
589 if (cmd_arg->res_name != NULL)
590 store_result(cmd_arg->res_name, last_ret_val);
596 int is_command(char *name)
598 if ( (strcmp(name, "CALL")) && (strcmp(name, "FILL")) &&
599 (strcmp(name, "ALLOC")) && (strcmp(name, "PRINT")) &&
600 (strcmp(name, "FREE")) && (strcmp(name, "exit")) &&
601 (strcmp(name, "HELP")) && (strcmp(name, "help")) &&
602 (strcmp(name, "quit")) && (strcmp(name, "EXIT")) &&
603 (strcmp(name, "QUIT")) && (strcmp(name, "DEPOSIT")) )
610 int get_type(char *arg0)
612 if ((arg0[0] == '(') || (is_command(arg0)) ){
620 int add_args(char **cmd, int length, int total, cmd_tree *tree)
623 struct queue_t *old, *new;
625 old = tree->children;
626 while ((old) && (old->next))
628 new = (struct queue_t *)malloc(sizeof(struct queue_t));
632 tree->children = new;
635 type = get_type(cmd[0]);
637 DBG(2, fprintf(outfp, "Don't understand %s\n", cmd[0]));
641 new->val = (char *)malloc(strlen(cmd[0])+1);
642 strcpy(new->val, cmd[0]);
647 if (cmd[0][0] == '(') {
652 new->cmd = build_tree(&cmd[1], &new_len, total);
653 if (new->cmd == NULL) { /* Invalid command */
654 return length; /* Pretend we used everything up */
656 total = (length - new_len);
657 DBG(4, fprintf(outfp, "Used %d bytes\n", total));
663 void free_tree(cmd_tree* tree)
668 if (tree->children) {
669 struct queue_t *child = tree->children;
670 struct queue_t *next;
674 free_tree(child->cmd);
682 free(tree->res_name);
690 cmd_tree* build_tree(char **cmd, int *length, int total)
692 int index = 0, used_args = 0;
694 if ((*length < 0) || (!cmd) || (*cmd == NULL))
698 DBG(4, fprintf(outfp, "length is %d\n", *length));
699 tree = (cmd_tree *)malloc(sizeof(cmd_tree));
700 tree->res_name = NULL;
701 tree->children = NULL;
702 if (cmd[index][0] == '$') {
703 tree->res_name = (char *)malloc(strlen(cmd[index])+1);
704 strcpy(tree->res_name, (char*)(cmd[index]+1));
706 if (cmd[index][0] == '=')
709 tree->res_name = NULL;
711 if (is_command(cmd[index]) == 0) {
712 if (tree->res_name == NULL) {
713 DBG(2, fprintf(outfp, "command %s is invalid \n", cmd[index]));
718 tree->val = (char *)malloc(strlen(cmd[index])+1);
719 strcpy(tree->val, cmd[index]);
729 /* Got to get the arguments */
730 while (*length > 0) {
732 if (cmd[index][0] == ')') {
734 DBG(4, fprintf(outfp, "and now len is %d\n", *length));
738 used_args = add_args(&cmd[index], *length, total, tree);
740 *length -= used_args;
748 char *getline(char *prompt)
753 line = malloc(MAX_LINE);
754 if ((do_prompt) && (infp == stdin))
758 /* If we get an end of file, just wait */
760 while (feof(infp) && (line[i] != '\n')) {
763 fseek(infp, 0, SEEK_CUR);
768 fread(&line[i], 1, 1, infp);
769 } while(line[i] != '\n');
773 /* fprintf(stderr, "Got word %s\n", line); */
774 DBG(5, fprintf(outfp, "Got word %s\n", line));
778 void my_perror(char *msg)
780 char *errmsg = strerror(errno);
782 DBG(2, fprintf(outfp, "%s: %s\n", msg, errmsg));
785 /* Static list of flag names */
786 struct var_mapping flags_map[] = {
787 {"O_RDONLY", O_RDONLY, UINT },
788 {"O_WRONLY", O_WRONLY, UINT },
789 {"O_RDWR", O_RDWR, UINT },
790 {"O_CREAT", O_CREAT, UINT },
791 {"O_EXCL", O_EXCL, UINT },
792 {"O_NOCTTY", O_NOCTTY, UINT },
793 {"O_TRUNC", O_TRUNC, UINT },
794 {"O_APPEND", O_APPEND, UINT },
795 {"O_SYNC", O_NONBLOCK, UINT },
796 {"O_NDELAY", O_NDELAY, UINT },
797 {"O_SYNC", O_SYNC, UINT },
798 {"O_FSYNC", O_FSYNC, UINT },
799 {"O_ASYNC", O_ASYNC, UINT },
800 {"SEEK_SET", SEEK_SET, UINT },
801 {"SEEK_CUR", SEEK_CUR, UINT },
802 {"SEEK_END", SEEK_END, UINT },
803 {"S_ISUID", S_ISUID, UINT },
804 {"S_ISGID", S_ISGID, UINT },
805 {"S_ISVTX", S_ISVTX, UINT },
806 {"S_IRWXU", S_IRWXU, UINT },
807 {"S_IRUSR", S_IRUSR, UINT },
808 {"S_IREAD", S_IREAD, UINT },
809 {"S_IWUSR", S_IWUSR, UINT },
810 {"S_IWRITE", S_IWRITE, UINT },
811 {"S_IXUSR", S_IXUSR, UINT },
812 {"S_IEXEC", S_IEXEC, UINT },
813 {"S_IRWXG", S_IRWXG, UINT },
814 {"S_IRGRP", S_IRGRP, UINT },
815 {"S_IWGRP", S_IWGRP, UINT },
816 {"S_IXGRP", S_IXGRP, UINT },
817 {"S_IRWXO", S_IRWXO, UINT },
818 {"S_IROTH", S_IROTH, UINT },
819 {"S_IWOTH", S_IWOTH, UINT },
820 {"S_IXOTH", S_IXOTH, UINT },
821 {"S_IFCHR", S_IFCHR, UINT },
822 {"S_IFMT", S_IFMT, UINT },
823 {"S_IFBLK", S_IFBLK, UINT },
824 {"S_IFREG", S_IFREG, UINT },
825 {"S_IFIFO", S_IFIFO, UINT },
826 {"S_IFLNK", S_IFLNK, UINT },
834 while (flags_map[index].obj != -1) {
835 store_result(flags_map[index].name, flags_map[index].obj);
840 int getquotedlen(char *str)
844 if (str[0] != '"' && str[0] != '\'')
847 for (i=1; str[i] != '\0' && str[i] != '"' && str[i] != '\''; i++);
852 int perform_op(int num1, int num2, char op)
882 int get_constant_val(char **str_ptr, int type)
886 char *str = *str_ptr;
888 int i, j, num1, num2, size;
890 printf("Getting constant val from %s\n", str);
893 size = getquotedlen(str);
894 buf = (struct buf_t *)malloc(sizeof(struct buf_t));
895 buf->buf = alloc_buff32(size, 8);
900 for (i=1; i < size; i++) {
906 DBG(3, fprintf(outfp, "Your buffer (%p) (%p) is at index %d\n",
907 (void *)buf, buf->buf, next));
911 last_ret_val = next-1;
923 if ((ch == '+') || (ch == '/') || (ch == '*') ||
924 (ch == '-') || (ch == '%')) {
925 if (str_ptr[2][0] == '$')
926 num2 = get_obj(str_ptr[2]);
928 num2 = atoi(str_ptr[2]);
929 num1 = perform_op(num1, num2, ch);
938 DBG(2, fprintf(outfp, "Can't understand type of %d\n", type));
945 int is_constant(char *str)
947 if ((str[0] == '"') || (str[0] == '\''))
951 if ( (str[0] == '$') ||
952 ( ((int)str[0] > 47) && ((int)str[0] < 57) ) )
958 int main(int argc, char *argv[])
960 int count, err, i, orig_count;
964 extern int _test_sysio_startup(void);
969 err = _test_sysio_startup();
971 /* Temp. hack until I do the right thing to fix this...*/
972 open("/dev/stdin",O_RDONLY);
973 open("/dev/stdout",O_WRONLY);
974 open("/dev/stderr",O_WRONLY);
982 /* Get the input/output streams */
983 for (i = 1; i < argc; i++) {
984 if (!strcmp(argv[i], "--input")) {
986 infp = fopen(argv[i], "r");
988 fprintf(outfp, "Unable to open file %s for reading\n", argv[i]);
991 } else if (!strcmp(argv[i], "--output")) {
993 outfp = fopen(argv[i], "w");
995 fprintf(stderr, "Unable to open file %s for writing\n", argv[i]);
998 } else if (!strcmp(argv[i], "--np")) {
1001 fprintf(stderr, "%s: Invalid arg\n", argv[i]);
1005 /* Initilize the mapping */
1006 for (i=0; i < MAX_VARS; i++)
1007 map[i].map.obj = -1;
1009 /* Debug defaults */
1015 /* sysio defaults */
1016 strcpy(root_driver, DEFAULT_DRIVER);
1017 strcpy(mntpath, "/");
1023 /* Set up line buffering */
1028 * This sets up some common flags so that the string
1029 * names can be used (for instance 0_RDWR, SEEK_SET, etc
1035 bzero(output, 4096);
1037 input = getline("> ");
1038 cmd = malloc(MAX_COMMAND * sizeof(char *));
1039 count = orig_count = parser(input, cmd);
1041 if ((!count) || (count > MAX_COMMAND)){
1042 fprintf(outfp, "%s: invalid command\n", input);
1045 if (cmd[0][0] == '$') {
1046 /* Need to store output of command in var name */
1048 DBG(4, fprintf(outfp, "name is %s\n", name));
1050 /* The '=' is not necessary, but available */
1051 if (!strcmp(cmd[1], "=")){
1056 if ((err=is_constant(cmd[i])) != 0) {
1057 store_result((char *)(&cmd[0][1]), get_constant_val(&cmd[i], err));
1062 tree = build_tree(&cmd[i], &count, 0);
1064 err = run_cmd(tree);
1065 store_result((char *)(&cmd[0][1]), last_ret_val);
1070 tree = build_tree(cmd, &count, 0);
1072 err = run_cmd(tree);
1074 /* Print out return code and any string from command */
1075 fprintf(outfp, "%#04x %s\n", err, output);
1078 /* fprintf(stderr, "%#04x %s\n", err, output); */
1079 for (i=0; i < count; i++)