-
Notifications
You must be signed in to change notification settings - Fork 2
/
sh.c
79 lines (75 loc) · 1.89 KB
/
sh.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "shlib.h"
int
main(void)
{
static char buf[100];
static char nbuf[256];
int fd;
if(fork1() == 0)
runcmd(parsecmd("msh STARTCOMMAND"));
wait();
// Ensure that three file descriptors are open.
while((fd = open("console", O_RDWR)) >= 0){
if(fd >= 3){
close(fd);
break;
}
}
// Read and run input commands.
while(getcmd(buf, sizeof(buf)) >= 0){
// clear space chars in the beginning of buf
shparsedollar(nbuf, buf);
int len =strlen(nbuf);
nbuf[len++] = '\n';
if(strprefix(nbuf, "cd ")){
// Chdir must be called by the parent, not the child.
nbuf[len-1] = 0; // chop \n
if(chdir(nbuf+3) < 0)
printf(2, "cannot cd %s\n", nbuf+3);
continue;
}
if (strprefix(nbuf, "if ") || strprefix(nbuf, "while ")) {
printf(2, "\"if\" and \"while\" statements can only used in msh.\nPlease write it in files and run \"msh FILENAME\"\n");
continue;
}
if(len >= 2 && nbuf[len-2] == '?'){
nbuf[len-2] = 0;
if(cmplt(nbuf) < 0)
printf(2, "auto complete %s failed\n", nbuf);
continue;
}
int run = 1;
// check equal
for (int j = 0; nbuf[j]; j++) {
if (strchr(" \t\v\r\n", nbuf[j])) {
break;
}
if (nbuf[j] == '=') {
run = 0;
nbuf[len - 1] = 0;
nbuf[j] = 0;
if (setenv(-1, nbuf, (char**)(int)(nbuf + j + 1), 1) > 0) {
printf(2, "Set variable fail! Too many variables now!\n");
}
}
}
if (strprefix(nbuf, "calculator ")) {
// replace () with {}
int mlen = (int)strlen(nbuf);
for (int temp = 0; temp < mlen; temp++) {
if (nbuf[temp] == '(') {
nbuf[temp] = '{';
}
if (nbuf[temp] == ')') {
nbuf[temp] = '}';
}
}
}
if (run) {
if(fork1() == 0)
runcmd(parsecmd(nbuf));
wait();
}
}
exit();
}