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