1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include <sys/dirent.h>
7 #include <sys/wait.h>
8 #include <sys/syscall.h>
9 #include <unistd.h>
10 #include <syscall.h>
11
12 #define SHELL_MAX_ARGS 5
13 #define SHELL_MAX_LINE 256
14
15 void DispatchCommand(char *buf);
16
17 int
main(int argc,const char * argv[])18 main(int argc, const char *argv[])
19 {
20 char buf[256];
21
22 printf("System Shell\n");
23
24 while (1) {
25 fputs("Shell> ", stdout);
26 fgets(buf, sizeof(buf), stdin);
27
28 DispatchCommand(buf);
29 }
30 }
31
32 void
Cmd_Help(int argc,const char * argv[])33 Cmd_Help(int argc, const char *argv[])
34 {
35 printf("bkpt Trigger a kernel breakpoint\n");
36 printf("exit Exit shell\n");
37 printf("help Display the list of commands\n");
38 }
39
40 void
Cmd_Exit(int argc,const char * argv[])41 Cmd_Exit(int argc, const char *argv[])
42 {
43 int val = 0;
44
45 if (argc != 1 && argc != 2) {
46 printf("Invalid number of arguments\n");
47 return;
48 }
49
50 if (argc == 2) {
51 val = atoi(argv[1]);
52 }
53
54 exit(val);
55 }
56
57 const char *searchpath[] = {
58 "",
59 "/sbin/",
60 "/bin/",
61 "/tests/",
62 NULL
63 };
64
65 void
Cmd_Run(int argc,const char * argv[])66 Cmd_Run(int argc, const char *argv[])
67 {
68 int i, status;
69 char path[256];
70 struct stat sb;
71
72 if (argc == 0)
73 return;
74
75 i = 0;
76 while (searchpath[i] != NULL) {
77 strcpy(path, searchpath[i]);
78 strcat(path, argv[0]);
79
80 status = OSStat(path, &sb);
81 if (status != 0) {
82 i++;
83 continue;
84 }
85
86 argv[argc] = NULL;
87 status = spawn(path, &argv[0]);
88 if (status > 100000) {
89 printf("Spawn failed!\n");
90 }
91 #if 0
92 status = OSWait(status);
93 printf("Process result: %d\n", status);
94 #endif
95 return;
96 }
97
98 printf("Unknown command '%s'\n", argv[0]);
99 }
100
101 void
DispatchCommand(char * buf)102 DispatchCommand(char *buf)
103 {
104 int i;
105 int argc;
106 char *argv[SHELL_MAX_ARGS+1];
107 char *nextArg;
108
109 // Remove newline
110 for (i = 0; buf[i] != 0; i++) {
111 if (buf[i] == '\n') {
112 buf[i] = '\0';
113 break;
114 }
115 }
116
117 // parse input
118 nextArg = strtok(buf, " \t\r\n");
119 for (argc = 0; argc < SHELL_MAX_ARGS; argc++) {
120 if (nextArg == NULL)
121 break;
122
123 argv[argc] = nextArg;
124 nextArg = strtok(NULL, " \t\r\n");
125 }
126
127 // execute command
128 if (strcmp(argv[0], "help") == 0) {
129 Cmd_Help(argc, (const char **)argv);
130 } else if (strcmp(argv[0], "bkpt") == 0) {
131 asm volatile("int3");
132 } else if (strcmp(argv[0], "exit") == 0) {
133 Cmd_Exit(argc, (const char **)argv);
134 } else if (strcmp(argv[0], "#") == 0) {
135 // Ignore comments
136 } else if (buf[0] == '\0') {
137 // Ignore empty lines
138 } else {
139 Cmd_Run(argc, (const char **)argv);
140 }
141 }
142
143