21 char *mnt = "/mnt/term/cmd";
26 int nice, foreground = 1;
32 postnote(PNPROC, pid[Pcopyin], "kill");
39 write(fd[Fctl], "kill", 4);
43 catch(void*, char *msg)
45 if(strcmp(msg, "interrupt") == 0
46 || strcmp(msg, "hangup") == 0
47 || strcmp(msg, "kill") == 0){
55 fd01(int fd0, int fd1)
59 if(fd0 >= 0 && fd0 != 0){
63 if(fd1 >= 0 && fd1 != 1){
67 for(i = 0; i<Nfd; i++){
84 while((n = read(0, buf, sizeof(buf))) > 0)
85 if(write(1, buf, n) != n)
92 fprint(2, "%s: [ -b ] [ -m mountpoint ] [ -d dir ] [ -n ] [ -N level ] cmd [ arg... ]\n", argv0);
97 main(int argc, char **argv)
110 mnt = cleanname(EARGF(usage()));
113 dir = EARGF(usage());
119 nice = atoi(EARGF(usage()));
128 seprint(buf, &buf[sizeof(buf)], "%s/clone", mnt);
129 if((fd[Fctl] = open(buf, ORDWR)) < 0)
130 sysfatal("open: %r");
131 s = &buf[strlen(mnt)+1];
132 if((n = read(fd[Fctl], s, &buf[sizeof(buf)-1]-s)) < 0)
133 sysfatal("read clone: %r");
134 while(n > 0 && buf[n-1] == '\n')
138 seprint(s, &buf[sizeof(buf)], "/wait");
139 if((fd[Fwait] = open(buf, OREAD)) < 0)
140 sysfatal("open: %r");
143 seprint(s, &buf[sizeof(buf)], "/data");
144 if((fd[Fstdin] = open(buf, OWRITE)) < 0)
145 sysfatal("open: %r");
147 seprint(s, &buf[sizeof(buf)], "/data");
148 if((fd[Fstdout] = open(buf, OREAD)) < 0)
149 sysfatal("open: %r");
151 seprint(s, &buf[sizeof(buf)], "/stderr");
152 if((fd[Fstderr] = open(buf, OREAD)) < 0)
153 sysfatal("open: %r");
157 if(fprint(fd[Fctl], "dir %q", dir) < 0)
158 sysfatal("cannot change directory: %r");
161 * try to automatically change directory if we are in
162 * /mnt/term or /mnt/term/root, but unlike -d flag,
163 * do not error when the dir ctl command fails.
165 if((s = strrchr(mnt, '/')) != nil){
167 dir = getwd(buf, sizeof(buf));
168 if(strncmp(dir, mnt, n) == 0 && (dir[n] == 0 || dir[n] == '/')){
170 if(strncmp(dir, "/root", 5) == 0 && (dir[5] == 0 || dir[5] == '/'))
174 /* hack for win32: /C:... -> C:/... */
175 if(dir[1] >= 'A' && dir[1] <= 'Z' && dir[2] == ':')
176 dir[0] = dir[1], dir[1] = ':', dir[2] = '/';
177 fprint(fd[Fctl], "dir %q", dir);
183 fprint(fd[Fctl], "nice %d", nice);
186 fprint(fd[Fctl], "killonclose");
188 s = seprint(buf, &buf[sizeof(buf)], "exec");
190 s = seprint(s, &buf[sizeof(buf)], " %q", *argv++);
191 if(s >= &buf[sizeof(buf)-1])
192 sysfatal("too many arguments");
195 if(write(fd[Fctl], buf, s - buf) < 0)
196 sysfatal("write: %r");
198 if((pid[Preadwait] = fork()) == -1)
199 sysfatal("fork: %r");
200 if(pid[Preadwait] == 0){
202 if((n = read(0, buf, sizeof(buf)-1)) < 0)
203 rerrstr(buf, sizeof(buf));
207 while(n > 0 && buf[n-1] == '\n')
210 if(tokenize(buf, f, 5) == 5)
217 if((pid[Pcopyerr] = fork()) == -1)
218 sysfatal("fork: %r");
219 if(pid[Pcopyerr] == 0){
220 fd01(fd[Fstderr], 2);
222 rerrstr(buf, sizeof(buf));
225 if((pid[Pcopyout] = fork()) == -1)
226 sysfatal("fork: %r");
227 if(pid[Pcopyout] == 0){
228 fd01(fd[Fstdout], 1);
230 rerrstr(buf, sizeof(buf));
233 if((pid[Pcopyin] = fork()) == -1)
234 sysfatal("fork: %r");
235 if(pid[Pcopyin] == 0){
238 rerrstr(buf, sizeof(buf));
246 while((w = wait()) != nil){
247 if((s = strstr(w->msg, ": ")) == nil)
251 for(n = 0; n < Npid; n++){
252 if(pid[n] == w->pid){