annotate src/usr/sh.c @ 48:58ec26c64601

fix_makefile.inc use *.cbc files
author anatofuz
date Wed, 13 Mar 2019 11:29:46 +0900
parents 83c23a36980d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 // Shell.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
2
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 #include "types.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 #include "user.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 #include "fcntl.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
6
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 // Parsed command representation
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 #define EXEC 1
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 #define REDIR 2
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 #define PIPE 3
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 #define LIST 4
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 #define BACK 5
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
13
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 #define MAXARGS 10
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
15
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 struct cmd {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 int type;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 };
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
19
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 struct execcmd {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 int type;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 char *argv[MAXARGS];
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 char *eargv[MAXARGS];
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 };
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
25
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 struct redircmd {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 int type;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 struct cmd *cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 char *file;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 char *efile;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 int mode;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 int fd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 };
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
34
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 struct pipecmd {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 int type;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 struct cmd *left;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 struct cmd *right;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 };
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
40
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 struct listcmd {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 int type;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 struct cmd *left;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 struct cmd *right;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 };
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
46
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 struct backcmd {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 int type;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 struct cmd *cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 };
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
51
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 int fork1(void); // Fork but panics on failure.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 void panic(char*);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 struct cmd *parsecmd(char*);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
55
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 // Execute cmd. Never returns.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 void
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 runcmd(struct cmd *cmd)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 int p[2];
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 struct backcmd *bcmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 struct execcmd *ecmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 struct listcmd *lcmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 struct pipecmd *pcmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 struct redircmd *rcmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
66
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 if(cmd == 0)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 exit();
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
69
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 switch(cmd->type){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 default:
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 panic("runcmd");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
73
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 case EXEC:
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 ecmd = (struct execcmd*)cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 if(ecmd->argv[0] == 0)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 exit();
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 exec(ecmd->argv[0], ecmd->argv);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 printf(2, "exec %s failed\n", ecmd->argv[0]);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
81
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 case REDIR:
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 rcmd = (struct redircmd*)cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 close(rcmd->fd);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 if(open(rcmd->file, rcmd->mode) < 0){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 printf(2, "open %s failed\n", rcmd->file);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 exit();
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 runcmd(rcmd->cmd);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
91
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 case LIST:
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 lcmd = (struct listcmd*)cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 if(fork1() == 0)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 runcmd(lcmd->left);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 wait();
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 runcmd(lcmd->right);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
99
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 case PIPE:
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 pcmd = (struct pipecmd*)cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 if(pipe(p) < 0)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 panic("pipe");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 if(fork1() == 0){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 close(1);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 dup(p[1]);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 close(p[0]);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 close(p[1]);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 runcmd(pcmd->left);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 if(fork1() == 0){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 close(0);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 dup(p[0]);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 close(p[0]);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 close(p[1]);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 runcmd(pcmd->right);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 close(p[0]);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 close(p[1]);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 wait();
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 wait();
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
123
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 case BACK:
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 bcmd = (struct backcmd*)cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 if(fork1() == 0)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 runcmd(bcmd->cmd);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 exit();
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
132
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 int
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 getcmd(char *buf, int nbuf)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 printf(2, "$ ");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 memset(buf, 0, nbuf);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 gets(buf, nbuf);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 if(buf[0] == 0) // EOF
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 return -1;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 return 0;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
143
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 int
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 main(void)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 static char buf[100];
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 int fd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
149
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 // Assumes three file descriptors open.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 while((fd = open("console", O_RDWR)) >= 0){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 if(fd >= 3){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 close(fd);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
156 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
157
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 // Read and run input commands.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
159 while(getcmd(buf, sizeof(buf)) >= 0){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 if(buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' '){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 // Clumsy but will have to do for now.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
162 // Chdir has no effect on the parent if run in the child.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 buf[strlen(buf)-1] = 0; // chop \n
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
164 if(chdir(buf+3) < 0)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
165 printf(2, "cannot cd %s\n", buf+3);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 continue;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
167 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 if(fork1() == 0)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
169 runcmd(parsecmd(buf));
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
170 wait();
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
171 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
172 exit();
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
173 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
174
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
175 void
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 panic(char *s)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
177 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
178 printf(2, "%s\n", s);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
179 exit();
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
180 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
181
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
182 int
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
183 fork1(void)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
184 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
185 int pid;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
186
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 pid = fork();
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
188 if(pid == -1)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
189 panic("fork");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 return pid;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
192
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
193 //PAGEBREAK!
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 // Constructors
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
195
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 struct cmd*
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 execcmd(void)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
198 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
199 struct execcmd *cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
200
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
201 cmd = malloc(sizeof(*cmd));
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
202 memset(cmd, 0, sizeof(*cmd));
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 cmd->type = EXEC;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
204 return (struct cmd*)cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
205 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
206
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
207 struct cmd*
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 redircmd(struct cmd *subcmd, char *file, char *efile, int mode, int fd)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
209 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
210 struct redircmd *cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
211
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 cmd = malloc(sizeof(*cmd));
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 memset(cmd, 0, sizeof(*cmd));
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
214 cmd->type = REDIR;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
215 cmd->cmd = subcmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
216 cmd->file = file;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 cmd->efile = efile;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
218 cmd->mode = mode;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
219 cmd->fd = fd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
220 return (struct cmd*)cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
221 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
222
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
223 struct cmd*
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
224 pipecmd(struct cmd *left, struct cmd *right)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
226 struct pipecmd *cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
227
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
228 cmd = malloc(sizeof(*cmd));
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
229 memset(cmd, 0, sizeof(*cmd));
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
230 cmd->type = PIPE;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
231 cmd->left = left;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
232 cmd->right = right;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
233 return (struct cmd*)cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
235
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
236 struct cmd*
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
237 listcmd(struct cmd *left, struct cmd *right)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
238 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
239 struct listcmd *cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
240
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
241 cmd = malloc(sizeof(*cmd));
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
242 memset(cmd, 0, sizeof(*cmd));
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
243 cmd->type = LIST;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
244 cmd->left = left;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
245 cmd->right = right;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 return (struct cmd*)cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
248
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
249 struct cmd*
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
250 backcmd(struct cmd *subcmd)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
251 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
252 struct backcmd *cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
253
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 cmd = malloc(sizeof(*cmd));
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 memset(cmd, 0, sizeof(*cmd));
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
256 cmd->type = BACK;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
257 cmd->cmd = subcmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
258 return (struct cmd*)cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
259 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
260 //PAGEBREAK!
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
261 // Parsing
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
262
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
263 char whitespace[] = " \t\r\n\v";
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
264 char symbols[] = "<|>&;()";
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
265
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
266 int
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
267 gettoken(char **ps, char *es, char **q, char **eq)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
268 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
269 char *s;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
270 int ret;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
271
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
272 s = *ps;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
273 while(s < es && strchr(whitespace, *s))
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
274 s++;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
275 if(q)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
276 *q = s;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
277 ret = *s;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
278 switch(*s){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
279 case 0:
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
280 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
281 case '|':
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
282 case '(':
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
283 case ')':
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
284 case ';':
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
285 case '&':
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
286 case '<':
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
287 s++;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
288 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
289 case '>':
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
290 s++;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
291 if(*s == '>'){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
292 ret = '+';
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
293 s++;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
294 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
296 default:
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 ret = 'a';
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
298 while(s < es && !strchr(whitespace, *s) && !strchr(symbols, *s))
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
299 s++;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
300 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
301 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
302 if(eq)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
303 *eq = s;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
304
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
305 while(s < es && strchr(whitespace, *s))
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
306 s++;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
307 *ps = s;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
308 return ret;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
309 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
310
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
311 int
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
312 peek(char **ps, char *es, char *toks)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
313 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
314 char *s;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
315
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
316 s = *ps;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
317 while(s < es && strchr(whitespace, *s))
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
318 s++;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
319 *ps = s;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
320 return *s && strchr(toks, *s);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
321 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
322
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
323 struct cmd *parseline(char**, char*);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
324 struct cmd *parsepipe(char**, char*);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
325 struct cmd *parseexec(char**, char*);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
326 struct cmd *nulterminate(struct cmd*);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
327
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
328 struct cmd*
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
329 parsecmd(char *s)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
330 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
331 char *es;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
332 struct cmd *cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
333
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
334 es = s + strlen(s);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
335 cmd = parseline(&s, es);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
336 peek(&s, es, "");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
337 if(s != es){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
338 printf(2, "leftovers: %s\n", s);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
339 panic("syntax");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
340 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
341 nulterminate(cmd);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
342 return cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
343 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
344
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
345 struct cmd*
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
346 parseline(char **ps, char *es)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
347 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
348 struct cmd *cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
349
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
350 cmd = parsepipe(ps, es);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
351 while(peek(ps, es, "&")){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
352 gettoken(ps, es, 0, 0);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
353 cmd = backcmd(cmd);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
354 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
355 if(peek(ps, es, ";")){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
356 gettoken(ps, es, 0, 0);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
357 cmd = listcmd(cmd, parseline(ps, es));
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
358 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
359 return cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
360 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
361
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
362 struct cmd*
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
363 parsepipe(char **ps, char *es)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
364 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
365 struct cmd *cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
366
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
367 cmd = parseexec(ps, es);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
368 if(peek(ps, es, "|")){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
369 gettoken(ps, es, 0, 0);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
370 cmd = pipecmd(cmd, parsepipe(ps, es));
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
371 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
372 return cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
373 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
374
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
375 struct cmd*
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
376 parseredirs(struct cmd *cmd, char **ps, char *es)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
377 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
378 int tok;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
379 char *q, *eq;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
380
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
381 while(peek(ps, es, "<>")){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
382 tok = gettoken(ps, es, 0, 0);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
383 if(gettoken(ps, es, &q, &eq) != 'a')
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
384 panic("missing file for redirection");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
385 switch(tok){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
386 case '<':
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
387 cmd = redircmd(cmd, q, eq, O_RDONLY, 0);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
388 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
389 case '>':
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
390 cmd = redircmd(cmd, q, eq, O_WRONLY|O_CREATE, 1);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
391 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
392 case '+': // >>
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
393 cmd = redircmd(cmd, q, eq, O_WRONLY|O_CREATE, 1);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
394 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
395 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
396 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
397 return cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
398 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
399
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
400 struct cmd*
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
401 parseblock(char **ps, char *es)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
402 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
403 struct cmd *cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
404
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
405 if(!peek(ps, es, "("))
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
406 panic("parseblock");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
407 gettoken(ps, es, 0, 0);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
408 cmd = parseline(ps, es);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
409 if(!peek(ps, es, ")"))
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
410 panic("syntax - missing )");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
411 gettoken(ps, es, 0, 0);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
412 cmd = parseredirs(cmd, ps, es);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
413 return cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
414 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
415
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
416 struct cmd*
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
417 parseexec(char **ps, char *es)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
418 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
419 char *q, *eq;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
420 int tok, argc;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
421 struct execcmd *cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
422 struct cmd *ret;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
423
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
424 if(peek(ps, es, "("))
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
425 return parseblock(ps, es);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
426
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
427 ret = execcmd();
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
428 cmd = (struct execcmd*)ret;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
429
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
430 argc = 0;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
431 ret = parseredirs(ret, ps, es);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
432 while(!peek(ps, es, "|)&;")){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
433 if((tok=gettoken(ps, es, &q, &eq)) == 0)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
434 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
435 if(tok != 'a')
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
436 panic("syntax");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
437 cmd->argv[argc] = q;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
438 cmd->eargv[argc] = eq;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
439 argc++;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
440 if(argc >= MAXARGS)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
441 panic("too many args");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
442 ret = parseredirs(ret, ps, es);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
443 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
444 cmd->argv[argc] = 0;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
445 cmd->eargv[argc] = 0;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
446 return ret;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
447 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
448
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
449 // NUL-terminate all the counted strings.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
450 struct cmd*
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
451 nulterminate(struct cmd *cmd)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
452 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
453 int i;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
454 struct backcmd *bcmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
455 struct execcmd *ecmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
456 struct listcmd *lcmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
457 struct pipecmd *pcmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
458 struct redircmd *rcmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
459
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
460 if(cmd == 0)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
461 return 0;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
462
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
463 switch(cmd->type){
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
464 case EXEC:
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
465 ecmd = (struct execcmd*)cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
466 for(i=0; ecmd->argv[i]; i++)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
467 *ecmd->eargv[i] = 0;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
468 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
469
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
470 case REDIR:
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
471 rcmd = (struct redircmd*)cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
472 nulterminate(rcmd->cmd);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
473 *rcmd->efile = 0;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
474 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
475
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
476 case PIPE:
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
477 pcmd = (struct pipecmd*)cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
478 nulterminate(pcmd->left);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
479 nulterminate(pcmd->right);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
480 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
481
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
482 case LIST:
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
483 lcmd = (struct listcmd*)cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
484 nulterminate(lcmd->left);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
485 nulterminate(lcmd->right);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
486 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
487
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
488 case BACK:
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
489 bcmd = (struct backcmd*)cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
490 nulterminate(bcmd->cmd);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
491 break;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
492 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
493 return cmd;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
494 }