rename 'package' to 'module'
[nit.git] / lib / standard / exec.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2004-2008 Jean Privat <jean@pryen.org>
4 # Copyright 2008 Floréal Morandat <morandat@lirmm.fr>
5 #
6 # This file is free software, which comes along with NIT. This software is
7 # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
8 # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
9 # PARTICULAR PURPOSE. You can modify it is you want, provided this header
10 # is kept unaltered, and a notification of the changes is added.
11 # You are allowed to redistribute it and sell it, alone or is a part of
12 # another product.
13
14 # Invocation and management of operating system sub-processes.
15 # Standard input and output can be handled through streams.
16 module exec
17
18 import stream
19
20 # Simple sub-process
21 class Process
22 # The pid of the process
23 fun id: Int do return data.id
24
25 # Is the process finished?
26 fun is_finished: Bool do return data.is_finished
27
28 # Wait the termination of the process
29 fun wait
30 do
31 data.wait
32 assert is_finished
33 end
34
35 # The status once finished
36 fun status: Int
37 do
38 assert is_finished
39 return data.status
40 end
41
42 # Launch a command with some arguments
43 init(command: String, arguments: String...)
44 do
45 execute(command, arguments, 0)
46 end
47
48 # Launch a simple command without arguments
49 init init_(command: String)
50 do
51 execute(command, null, 0)
52 end
53
54 # Internal code to handle execution
55 protected init execute(command: String, arguments: nullable Array[String], pipeflags: Int)
56 do
57 var args = new Buffer
58 var l = 1 # Number of elements in args
59 args.append(command)
60 if arguments != null then
61 for a in arguments do
62 args.add('\0')
63 args.append(a)
64 end
65 l += arguments.length
66 end
67 data = basic_exec_execute(command.to_cstring, args.to_s.to_cstring, l, pipeflags)
68 end
69
70 private var data: NativeProcess
71 private fun basic_exec_execute(p: NativeString, av: NativeString, ac: Int, pf: Int): NativeProcess is extern "exec_Process_Process_basic_exec_execute_4"
72 end
73
74 # stdout of the process is readable
75 class IProcess
76 super Process
77 super IStream
78 var stream_in: FDIStream
79
80 redef fun close do stream_in.close
81
82 redef fun read_char do return stream_in.read_char
83
84 redef fun eof do return stream_in.eof
85
86 init(command: String, arguments: String...)
87 do
88 execute(command, arguments, 2)
89 stream_in = new FDIStream(data.out_fd)
90 end
91
92 init init_(command: String)
93 do
94 execute(command, null, 2)
95 stream_in = new FDIStream(data.out_fd)
96 end
97 end
98
99 # stdin of the process is writable
100 class OProcess
101 super Process
102 super OStream
103 var stream_out: OStream
104
105 redef fun close do stream_out.close
106
107 redef fun is_writable do return stream_out.is_writable
108
109 redef fun write(s) do stream_out.write(s)
110
111 init(command: String, arguments: String...)
112 do
113 execute(command, arguments, 1)
114 stream_out = new FDOStream(data.in_fd)
115 end
116
117 init init_(command: String)
118 do
119 execute(command, null, 1)
120 stream_out = new FDOStream(data.in_fd)
121 end
122 end
123
124 # stdin and stdout are both accessible
125 class IOProcess
126 super IProcess
127 super OProcess
128 super IOStream
129
130 redef fun close
131 do
132 stream_in.close
133 stream_out.close
134 end
135
136 init(command: String, arguments: String...)
137 do
138 execute(command, arguments, 3)
139 stream_in = new FDIStream(data.out_fd)
140 stream_out = new FDOStream(data.in_fd)
141 end
142
143 init init_(command: String)
144 do
145 execute(command, null, 3)
146 stream_in = new FDIStream(data.out_fd)
147 stream_out = new FDOStream(data.in_fd)
148 end
149 end
150
151 redef class Sys
152 # Execute a shell command and return its error code
153 fun system(command: String): Int
154 do
155 return command.to_cstring.system
156 end
157 end
158
159 redef class NativeString
160 fun system: Int is extern "string_NativeString_NativeString_system_0"
161 end
162
163 private extern NativeProcess
164 fun id: Int is extern "exec_NativeProcess_NativeProcess_id_0"
165 fun is_finished: Bool is extern "exec_NativeProcess_NativeProcess_is_finished_0"
166 fun status: Int is extern "exec_NativeProcess_NativeProcess_status_0"
167 fun wait is extern "exec_NativeProcess_NativeProcess_wait_0"
168
169 fun in_fd: Int is extern "exec_NativeProcess_NativeProcess_in_fd_0"
170 fun out_fd: Int is extern "exec_NativeProcess_NativeProcess_out_fd_0"
171 fun err_fd: Int is extern "exec_NativeProcess_NativeProcess_err_fd_0"
172 end
173