Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "rc.h"
2
#include "getflags.h"
3
#include "exec.h"
4
#include "io.h"
5
#include "fns.h"
6
#include <String.h>
7
 
8
int havefork = 1;
9
 
10
void
11
Xasync(void)
12
{
13
	int null = open("/dev/null", 0);
14
	int pid;
15
	char npid[10];
16
	if(null<0){
17
		Xerror("Can't open /dev/null\n");
18
		return;
19
	}
20
	switch(pid = rfork(RFFDG|RFPROC|RFNOTEG)){
21
	case -1:
22
		close(null);
23
		Xerror("try again");
24
		break;
25
	case 0:
26
		clearwaitpids();
27
		pushredir(ROPEN, null, 0);
28
		start(runq->code, runq->pc+1, runq->local);
29
		runq->ret = 0;
30
		break;
31
	default:
32
		addwaitpid(pid);
33
		close(null);
34
		runq->pc = runq->code[runq->pc].i;
35
		inttoascii(npid, pid);
36
		setvar("apid", newword(npid, (word *)0));
37
		break;
38
	}
39
}
40
 
41
void
42
Xpipe(void)
43
{
44
	struct thread *p = runq;
45
	int pc = p->pc, forkid;
46
	int lfd = p->code[pc++].i;
47
	int rfd = p->code[pc++].i;
48
	int pfd[2];
49
	if(pipe(pfd)<0){
50
		Xerror("can't get pipe");
51
		return;
52
	}
53
	switch(forkid = fork()){
54
	case -1:
55
		Xerror("try again");
56
		break;
57
	case 0:
58
		clearwaitpids();
59
		start(p->code, pc+2, runq->local);
60
		runq->ret = 0;
61
		close(pfd[PRD]);
62
		pushredir(ROPEN, pfd[PWR], lfd);
63
		break;
64
	default:
65
		addwaitpid(forkid);
66
		start(p->code, p->code[pc].i, runq->local);
67
		close(pfd[PWR]);
68
		pushredir(ROPEN, pfd[PRD], rfd);
69
		p->pc = p->code[pc+1].i;
70
		p->pid = forkid;
71
		break;
72
	}
73
}
74
 
75
/*
76
 * Who should wait for the exit from the fork?
77
 */
78
 
79
void
80
Xbackq(void)
81
{
82
	int n, pid;
83
	int pfd[2];
84
	char *stop;
85
	char utf[UTFmax+1];
86
	struct io *f;
87
	var *ifs = vlook("ifs");
88
	word *v, *nextv;
89
	Rune r;
90
	String *word;
91
 
92
	stop = ifs->val? ifs->val->word: "";
93
	if(pipe(pfd)<0){
94
		Xerror("can't make pipe");
95
		return;
96
	}
97
	switch(pid = fork()){
98
	case -1:
99
		Xerror("try again");
100
		close(pfd[PRD]);
101
		close(pfd[PWR]);
102
		return;
103
	case 0:
104
		clearwaitpids();
105
		close(pfd[PRD]);
106
		start(runq->code, runq->pc+1, runq->local);
107
		pushredir(ROPEN, pfd[PWR], 1);
108
		return;
109
	default:
110
		addwaitpid(pid);
111
		close(pfd[PWR]);
112
		f = openfd(pfd[PRD]);
113
		word = s_new();
114
		v = nil;
115
		/* rutf requires at least UTFmax+1 bytes in utf */
116
		while((n = rutf(f, utf, &r)) != EOF){
117
			utf[n] = '\0';
118
			if(utfutf(stop, utf) == nil)
119
				s_nappend(word, utf, n);
120
			else
121
				/*
122
				 * utf/r is an ifs rune (e.g., \t, \n), thus
123
				 * ends the current word, if any.
124
				 */
125
				if(s_len(word) > 0){
126
					v = newword(s_to_c(word), v);
127
					s_reset(word);
128
				}
129
		}
130
		if(s_len(word) > 0)
131
			v = newword(s_to_c(word), v);
132
		s_free(word);
133
		closeio(f);
134
		Waitfor(pid, 0);
135
		/* v points to reversed arglist -- reverse it onto argv */
136
		while(v){
137
			nextv = v->next;
138
			v->next = runq->argv->words;
139
			runq->argv->words = v;
140
			v = nextv;
141
		}
142
		runq->pc = runq->code[runq->pc].i;
143
		return;
144
	}
145
}
146
 
147
void
148
Xpipefd(void)
149
{
150
	struct thread *p = runq;
151
	int pc = p->pc, pid;
152
	char name[40];
153
	int pfd[2];
154
	int sidefd, mainfd;
155
	if(pipe(pfd)<0){
156
		Xerror("can't get pipe");
157
		return;
158
	}
159
	if(p->code[pc].i==READ){
160
		sidefd = pfd[PWR];
161
		mainfd = pfd[PRD];
162
	}
163
	else{
164
		sidefd = pfd[PRD];
165
		mainfd = pfd[PWR];
166
	}
167
	switch(pid = fork()){
168
	case -1:
169
		Xerror("try again");
170
		break;
171
	case 0:
172
		clearwaitpids();
173
		start(p->code, pc+2, runq->local);
174
		close(mainfd);
175
		pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0);
176
		runq->ret = 0;
177
		break;
178
	default:
179
		addwaitpid(pid);
180
		close(sidefd);
181
		pushredir(ROPEN, mainfd, mainfd);	/* isn't this a noop? */
182
		strcpy(name, Fdprefix);
183
		inttoascii(name+strlen(name), mainfd);
184
		pushword(name);
185
		p->pc = p->code[pc+1].i;
186
		break;
187
	}
188
}
189
 
190
void
191
Xsubshell(void)
192
{
193
	int pid;
194
	switch(pid = fork()){
195
	case -1:
196
		Xerror("try again");
197
		break;
198
	case 0:
199
		clearwaitpids();
200
		start(runq->code, runq->pc+1, runq->local);
201
		runq->ret = 0;
202
		break;
203
	default:
204
		addwaitpid(pid);
205
		Waitfor(pid, 1);
206
		runq->pc = runq->code[runq->pc].i;
207
		break;
208
	}
209
}
210
 
211
int
212
execforkexec(void)
213
{
214
	int pid;
215
	int n;
216
	char buf[ERRMAX];
217
 
218
	switch(pid = fork()){
219
	case -1:
220
		return -1;
221
	case 0:
222
		clearwaitpids();
223
		pushword("exec");
224
		execexec();
225
		strcpy(buf, "can't exec: ");
226
		n = strlen(buf);
227
		errstr(buf+n, ERRMAX-n);
228
		Exit(buf);
229
	}
230
	addwaitpid(pid);
231
	return pid;
232
}