stdlib/strings: Moved Buffer to FlatBuffer, Buffer is now abstract.
[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 init from_a(command: String, arguments: Array[String])
55 do
56 execute(command, arguments, 0)
57 end
58
59 # Internal code to handle execution
60 protected init execute(command: String, arguments: nullable Array[String], pipeflags: Int)
61 do
62 var args = new FlatBuffer
63 var l = 1 # Number of elements in args
64 args.append(command)
65 if arguments != null then
66 for a in arguments do
67 args.add('\0')
68 args.append(a)
69 end
70 l += arguments.length
71 end
72 data = basic_exec_execute(command.to_cstring, args.to_s.to_cstring, l, pipeflags)
73 end
74
75 private var data: NativeProcess
76 private fun basic_exec_execute(p: NativeString, av: NativeString, ac: Int, pf: Int): NativeProcess is extern "exec_Process_Process_basic_exec_execute_4"
77 end
78
79 # stdout of the process is readable
80 class IProcess
81 super Process
82 super IStream
83 var stream_in: FDIStream
84
85 redef fun close do stream_in.close
86
87 redef fun read_char do return stream_in.read_char
88
89 redef fun eof do return stream_in.eof
90
91 init(command: String, arguments: String...)
92 do
93 execute(command, arguments, 2)
94 stream_in = new FDIStream(data.out_fd)
95 end
96
97 init init_(command: String)
98 do
99 execute(command, null, 2)
100 stream_in = new FDIStream(data.out_fd)
101 end
102
103 init from_a(command: String, arguments: Array[String])
104 do
105 execute(command, arguments, 2)
106 stream_in = new FDIStream(data.out_fd)
107 end
108 end
109
110 # stdin of the process is writable
111 class OProcess
112 super Process
113 super OStream
114 var stream_out: OStream
115
116 redef fun close do stream_out.close
117
118 redef fun is_writable do return stream_out.is_writable
119
120 redef fun write(s) do stream_out.write(s)
121
122 init(command: String, arguments: String...)
123 do
124 execute(command, arguments, 1)
125 stream_out = new FDOStream(data.in_fd)
126 end
127
128 init init_(command: String)
129 do
130 execute(command, null, 1)
131 stream_out = new FDOStream(data.in_fd)
132 end
133
134 init from_a(command: String, arguments: Array[String])
135 do
136 execute(command, arguments, 1)
137 stream_out = new FDOStream(data.in_fd)
138 end
139 end
140
141 # stdin and stdout are both accessible
142 class IOProcess
143 super IProcess
144 super OProcess
145 super IOStream
146
147 redef fun close
148 do
149 stream_in.close
150 stream_out.close
151 end
152
153 init(command: String, arguments: String...)
154 do
155 execute(command, arguments, 3)
156 stream_in = new FDIStream(data.out_fd)
157 stream_out = new FDOStream(data.in_fd)
158 end
159
160 init init_(command: String)
161 do
162 execute(command, null, 3)
163 stream_in = new FDIStream(data.out_fd)
164 stream_out = new FDOStream(data.in_fd)
165 end
166
167 init from_a(command: String, arguments: Array[String])
168 do
169 execute(command, arguments, 3)
170 stream_in = new FDIStream(data.out_fd)
171 stream_out = new FDOStream(data.in_fd)
172 end
173 end
174
175 redef class Sys
176 # Execute a shell command and return its error code
177 fun system(command: String): Int
178 do
179 return command.to_cstring.system
180 end
181 end
182
183 redef class NativeString
184 fun system: Int is extern "string_NativeString_NativeString_system_0"
185 end
186
187 private extern NativeProcess
188 fun id: Int is extern "exec_NativeProcess_NativeProcess_id_0"
189 fun is_finished: Bool is extern "exec_NativeProcess_NativeProcess_is_finished_0"
190 fun status: Int is extern "exec_NativeProcess_NativeProcess_status_0"
191 fun wait is extern "exec_NativeProcess_NativeProcess_wait_0"
192
193 fun in_fd: Int is extern "exec_NativeProcess_NativeProcess_in_fd_0"
194 fun out_fd: Int is extern "exec_NativeProcess_NativeProcess_out_fd_0"
195 fun err_fd: Int is extern "exec_NativeProcess_NativeProcess_err_fd_0"
196 end
197