haventfork.c - 9base - revived minimalist port of Plan 9 userland to Unix
(HTM) git clone git://git.suckless.org/9base
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
haventfork.c (3436B)
---
1 #include "rc.h"
2 #include "getflags.h"
3 #include "exec.h"
4 #include "io.h"
5 #include "fns.h"
6
7 int havefork = 0;
8
9 static char **
10 rcargv(char *s)
11 {
12 int argc;
13 char **argv;
14 word *p;
15
16 p = vlook("*")->val;
17 argv = malloc((count(p)+6)*sizeof(char*));
18 argc = 0;
19 argv[argc++] = argv0;
20 if(flag['e'])
21 argv[argc++] = "-Se";
22 else
23 argv[argc++] = "-S";
24 argv[argc++] = "-c";
25 argv[argc++] = s;
26 for(p = vlook("*")->val; p; p = p->next)
27 argv[argc++] = p->word;
28 argv[argc] = 0;
29 return argv;
30 }
31
32 void
33 Xasync(void)
34 {
35 uint pid;
36 char buf[20], **argv;
37
38 Updenv();
39
40 argv = rcargv(runq->code[runq->pc].s);
41 pid = ForkExecute(argv0, argv, -1, 1, 2);
42 free(argv);
43
44 if(pid == 0) {
45 Xerror("proc failed");
46 return;
47 }
48
49 runq->pc++;
50 sprint(buf, "%d", pid);
51 setvar("apid", newword(buf, (word *)0));
52 }
53
54 char*
55 erealloc(char *p, long n)
56 {
57 p = realloc(p, n); /* botch, should be Realloc */
58 if(p==0)
59 panic("Can't realloc %d bytes\n", n);
60 return p;
61 }
62
63 enum { Stralloc = 100, };
64
65 void
66 Xbackq(void)
67 {
68 char **argv;
69 int c, l;
70 char *s, *wd, *ewd, *stop;
71 struct io *f;
72 var *ifs = vlook("ifs");
73 word *v, *nextv;
74 int pfd[2];
75 int pid;
76
77 stop = ifs->val?ifs->val->word:"";
78 if(pipe(pfd)<0){
79 Xerror("can't make pipe");
80 return;
81 }
82
83 Updenv();
84
85 argv = rcargv(runq->code[runq->pc].s);
86 pid = ForkExecute(argv0, argv, -1, pfd[1], 2);
87 free(argv);
88
89 close(pfd[1]);
90
91 if(pid == 0) {
92 Xerror("proc failed");
93 close(pfd[0]);
94 return;
95 }
96
97 f = openfd(pfd[0]);
98 s = wd = ewd = 0;
99 v = 0;
100 while((c=rchr(f))!=EOF){
101 if(s==ewd){
102 l = s-wd;
103 wd = erealloc(wd, l+Stralloc);
104 ewd = wd+l+Stralloc-1;
105 s = wd+l;
106 }
107 if(strchr(stop, c)){
108 if(s!=wd){
109 *s='\0';
110 v = newword(wd, v);
111 s = wd;
112 }
113 }
114 else *s++=c;
115 }
116 if(s!=wd){
117 *s='\0';
118 v=newword(wd, v);
119 }
120 if(wd)
121 efree(wd);
122 closeio(f);
123 Waitfor(pid, 1);
124 /* v points to reversed arglist -- reverse it onto argv */
125 while(v){
126 nextv=v->next;
127 v->next=runq->argv->words;
128 runq->argv->words=v;
129 v=nextv;
130 }
131 runq->pc++;
132 }
133
134 void
135 Xpipe(void)
136 {
137 thread *p=runq;
138 int pc=p->pc, pid;
139 int rfd=p->code[pc+1].i;
140 int pfd[2];
141 char **argv;
142
143 if(pipe(pfd)<0){
144 Xerror1("can't get pipe");
145 return;
146 }
147
148 Updenv();
149
150 argv = rcargv(runq->code[pc+2].s);
151 pid = ForkExecute(argv0, argv, 0, pfd[1], 2);
152 free(argv);
153 close(pfd[1]);
154
155 if(pid == 0) {
156 Xerror("proc failed");
157 close(pfd[0]);
158 return;
159 }
160
161 start(p->code, pc+4, runq->local);
162 pushredir(ROPEN, pfd[0], rfd);
163 p->pc=p->code[pc+3].i;
164 p->pid=pid;
165 }
166
167 void
168 Xpipefd(void)
169 {
170 Abort();
171 }
172
173 void
174 Xsubshell(void)
175 {
176 char **argv;
177 int pid;
178
179 Updenv();
180
181 argv = rcargv(runq->code[runq->pc].s);
182 pid = ForkExecute(argv0, argv, -1, 1, 2);
183 free(argv);
184
185 if(pid < 0) {
186 Xerror("proc failed");
187 return;
188 }
189
190 Waitfor(pid, 1);
191 runq->pc++;
192 }
193
194 /*
195 * start a process running the cmd on the stack and return its pid.
196 */
197 int
198 execforkexec(void)
199 {
200 char **argv;
201 char file[1024];
202 int nc;
203 word *path;
204 int pid;
205
206 if(runq->argv->words==0)
207 return -1;
208 argv = mkargv(runq->argv->words);
209
210 for(path = searchpath(runq->argv->words->word);path;path = path->next){
211 nc = strlen(path->word);
212 if(nc < sizeof file - 1){ /* 1 for / */
213 strcpy(file, path->word);
214 if(file[0]){
215 strcat(file, "/");
216 nc++;
217 }
218 if(nc+strlen(argv[1])<sizeof(file)){
219 strcat(file, argv[1]);
220 pid = ForkExecute(file, argv+1, mapfd(0), mapfd(1), mapfd(2));
221 if(pid >= 0){
222 free(argv);
223 return pid;
224 }
225 }
226 }
227 }
228 free(argv);
229 return -1;
230 }