-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprocess.py
63 lines (54 loc) · 2 KB
/
process.py
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
import os
import subprocess
import sys
from buildin import build_in
def sub_exec(args):
try:
os.execvp(args[0], args)
except FileNotFoundError:
print('xsh: {}: Command not found'.format(args[0]))
exit() # still in child process, needs an extra exit()
def sub_process(args):
try:
subprocess.run(args)
except FileNotFoundError:
print('xsh: {}: Command not found'.format(args[0]))
def execute_bak(args_list):
length = len(args_list)
if length == 1: # no pipeline case
args = args_list[0]
if not args[0]:
return True
# exec build in command first
if args[0] in build_in:
return build_in[args[0]](args)
else:
pid = os.fork()
sub_exec(args) if pid == 0 else os.waitpid(pid, os.WUNTRACED)
return True
else:
new_in, new_out = 0, 0
old_in, old_out = 0, 0
for i in range(length):
if i < length - 1: # if not the last command, create pipe
new_in, new_out = os.pipe()
pid = os.fork()
if pid == 0:
if i < length - 1:
os.dup2(new_out, sys.stdout.fileno()) # point current out to new pipe out
os.close(new_out)
os.close(new_in) # do not need it, close
if i > 0:
os.dup2(old_in, sys.stdin.fileno()) # point current in to new pipe in, to get prev command out
os.close(old_in)
os.close(old_out) # do not need it, close
args = args_list[i]
sub_exec(args)
else: # in father process
if i > 0:
os.close(old_out)
os.close(old_in)
if i < length - 1: # if not the last command, copy the pipeline, prepare for next child process
old_in, old_out = new_in, new_out
os.waitpid(pid, os.WUNTRACED)
return True