]> gitweb.factorcode.org Git - factor.git/blob - basis/io/launcher/launcher-docs.factor
io.launcher-docs: fix example code to match its description
[factor.git] / basis / io / launcher / launcher-docs.factor
1 ! Copyright (C) 2007, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: assocs calendar help.markup help.syntax io io.files
4 io.launcher.private kernel literals quotations splitting ;
5 IN: io.launcher
6
7 ARTICLE: "io.launcher.command" "Specifying a command"
8 "The " { $snippet "command" } " slot of a " { $link process } " can contain either a string or a sequence of strings. In the first case, the string is processed in an operating system-specific manner. In the second case, the first element is a program name and the remaining elements are passed to the program as command-line arguments." ;
9
10 ARTICLE: "io.launcher.detached" "Running processes in the background"
11 "By default, " { $link run-process } " waits for the process to complete. To run a process without waiting for it to finish, set the " { $snippet "detached" } " slot of a " { $link process } ", or use the following word:"
12 { $subsections run-detached } ;
13
14 ARTICLE: "io.launcher.hidden" "Running hidden processes"
15 "By default, child processes can create and display their own (console and other) windows. To signal to a process that it should stay hidden, set the " { $slot "hidden" } " slot of the " { $link process } " before running it. The processes are free to ignore this signal."
16 $nl
17 "The " { $link <process-stream> } " and " { $link with-process-stream } " words set this flag. On Windows this helps to run console applications without flashing their windows in the foreground." ;
18
19 ARTICLE: "io.launcher.environment" "Setting environment variables"
20 "The " { $snippet "environment" } " slot of a " { $link process } " contains an association mapping environment variable names to values. The interpretation of environment variables is operating system-specific."
21 $nl
22 "The " { $snippet "environment-mode" } " slot controls how the environment of the current Factor instance is composed with the value of the " { $snippet "environment" } " slot:"
23 { $subsections
24     +prepend-environment+
25     +replace-environment+
26     +append-environment+
27 }
28 "The default value is " { $link +append-environment+ } "." ;
29
30 ARTICLE: "io.launcher.redirection" "Input/output redirection"
31 "On all operating systems, the default input/output/error streams can be redirected."
32 $nl
33 "To specify redirection, set the " { $snippet "stdin" } ", " { $snippet "stdout" } " and " { $snippet "stderr" } " slots of a " { $link process } " to one of the following values:"
34 { $list
35     { { $link f } " - default value; the stream is either inherited from the current process, or is a " { $link <process-stream> } " pipe" }
36     { { $link +closed+ } " - the stream is closed; reads will return end of file and writes will fail" }
37     { { $link +stdout+ } " - a special value for the " { $snippet "stderr" } " slot only, indicating that the standard output and standard error streams should be merged" }
38     { "a path name - the stream is sent to the given file, which must exist for input and is created automatically on output" }
39     { "an " { $link appender } " wrapping a path name - output is sent to the end of the given file, as with " { $link <file-appender> } }
40     { "a file stream or a socket - the stream is connected to the given Factor stream, which cannot be used again from within Factor and must be closed after the process has been started" }
41 } ;
42
43 ARTICLE: "io.launcher.group" "Setting process groups"
44 "The process group of a child process can be controlled by setting the " { $snippet "group" } " slot of a " { $link process } " tuple:"
45 { $list
46     { $link +same-group+ }
47     { $link +new-group+ }
48     { $link +new-session+ }
49 }
50 "The default value is " { $link +same-group+ } ", which denotes that the child process should be part of the process group of the parent process. The " { $link +new-group+ } " option creates a new process group, while the " { $link +new-session+ } " creates a new session." ;
51
52 ARTICLE: "io.launcher.priority" "Setting process priority"
53 "The priority of the child process can be set by storing one of the below symbols in the " { $snippet "priority" } " slot of a " { $link process } " tuple:"
54 { $list
55     { $link +lowest-priority+ }
56     { $link +low-priority+ }
57     { $link +normal-priority+ }
58     { $link +high-priority+ }
59     { $link +highest-priority+ }
60 }
61 "The default value is " { $link f } ", which denotes that the child process should inherit the current process priority." ;
62
63 HELP: +closed+
64 { $description "Possible value for the " { $snippet "stdin" } ", " { $snippet "stdout" } ", and " { $snippet "stderr" } " slots of a " { $link process } "." } ;
65
66 HELP: +stdout+
67 { $description "Possible value for the " { $snippet "stderr" } " slot of a " { $link process } "." } ;
68
69 HELP: appender
70 { $class-description "An object representing a file to append to. Instances are created with " { $link <appender> } "." } ;
71
72 HELP: <appender>
73 { $values { "path" "a pathname string" } { "appender" appender } }
74 { $description "Creates an object which may be stored in the " { $snippet "stdout" } " or " { $snippet "stderr" } " slot of a " { $link process } " instance." } ;
75
76 HELP: +prepend-environment+
77 { $description "Possible value of " { $snippet "environment-mode" } " slot of a " { $link process } "."
78 $nl
79 "If this value is set, the child process environment consists of the value of the " { $snippet "environment" } " slot together with the current environment, with entries from the current environment taking precedence."
80 $nl
81 "This is used in situations where you want to spawn a child process with some default environment variables set, but allowing the user to override these defaults by changing the environment before launching Factor." } ;
82
83 HELP: +replace-environment+
84 { $description "Possible value of " { $snippet "environment-mode" } " slot of a " { $link process } "."
85 $nl
86 "The child process environment consists of the value of the " { $snippet "environment" } " slot."
87 $nl
88 "This is used in situations where you want full control over a child process environment, perhaps for security or testing." } ;
89
90 HELP: +append-environment+
91 { $description "Possible value of " { $snippet "environment-mode" } " slot of a " { $link process } "."
92 $nl
93 "The child process environment consists of the current environment together with the value of the " { $snippet "environment" } " key, with entries from the " { $snippet "environment" } " key taking precedence."
94 $nl
95 "This is used in situations where you want a spawn child process with some overridden environment variables." } ;
96
97 ARTICLE: "io.launcher.timeouts" "Process run-time timeouts"
98 "The " { $snippet "timeout" } " slot of a " { $link process } " can be set to a " { $link duration } " specifying a maximum running time for the process. If " { $link wait-for-process } " is called and the process does not exit before the duration expires, it will be killed." ;
99
100 HELP: get-environment
101 { $values { "process" process } { "env" assoc } }
102 { $description "Combines the current environment with the value of the " { $snippet "environment" } " slot of the " { $link process } " using the " { $snippet "environment-mode" } " slot." } ;
103
104 HELP: (current-process)
105 { $values { "handle" "a process handle" } }
106 { $description "Returns the handle of the current process." }
107 { $examples
108   { $example
109     "USING: io.launcher math prettyprint ;"
110     "(current-process) number? ."
111     "t"
112   }
113 } ;
114
115 HELP: (run-process)
116 { $values { "process" process } { "handle" "a process handle" } }
117 { $contract "Launches a process." }
118 { $notes "User code should call " { $link run-process } " instead." } ;
119
120 HELP: run-process
121 { $values { "desc" "a launch descriptor" } { "process" process } }
122 { $description "Launches a process. The object can either be a string, a sequence of strings or a " { $link process } ". See " { $link "io.launcher.descriptors" } " for details." }
123 { $examples
124   { $unchecked-example
125     "USING: io.launcher prettyprint ;"
126     "\"pwd\" run-process ."
127     "T{ process\n    { command \"pwd\" }\n    { environment H{ } }\n    { environment-mode +append-environment+ }\n    { group +same-group+ }\n    { status 0 }\n}"
128   }
129 }
130 { $notes "The output value can be passed to " { $link wait-for-process } " to get an exit code." } ;
131
132 HELP: run-detached
133 { $values { "desc" "a launch descriptor" } { "process" process } }
134 { $contract "Launches a process without waiting for it to complete. The object can either be a string, a sequence of strings or a " { $link process } ". See " { $link "io.launcher.descriptors" } " for details." }
135 { $notes
136     "This word is functionally identical to passing a " { $link process } " to " { $link run-process } " having the " { $snippet "detached" } " slot set."
137     $nl
138     "The output value can be passed to " { $link wait-for-process } " to get an exit code."
139 } ;
140
141 HELP: process-failed
142 { $values { "code" "an exit status" } }
143 { $description "Throws a " { $link process-failed } " error." }
144 { $error-description "Thrown by " { $link try-process } " if the process exited with a non-zero status code." } ;
145
146 HELP: try-process
147 { $values { "desc" "a launch descriptor" } }
148 { $description "Launches a process and waits for it to complete. If it exits with a non-zero status code, throws a " { $link process-failed } " error." }
149 { $examples
150   { $unchecked-example
151     "USING: continuations io.launcher prettyprint ;"
152     "[ \"i-dont-exist\" try-process ] [ ] recover ."
153     $[
154         {
155             "T{ process-failed"
156             "    { process"
157             "        T{ process"
158             "            { command \"i-dont-exist\" }"
159             "            { environment H{ } }"
160             "            { environment-mode +append-environment+ }"
161             "            { group +same-group+ }"
162             "            { status 255 }"
163             "        }"
164             "    }"
165             "}"
166         } join-lines
167     ]
168   }
169 } ;
170
171 { run-process try-process run-detached } related-words
172
173 HELP: kill-process
174 { $values { "process" process } }
175 { $description "Kills a running process. Does nothing if the process has already exited." }
176 { $examples
177   { $unchecked-example
178     "USING: io.launcher ;"
179     "\"cat\" run-detached kill-process"
180     ""
181   }
182 } ;
183
184 HELP: (kill-process)
185 { $values { "process" "process" } }
186 { $contract "Kills a running process." }
187 { $notes "User code should call " { $link kill-process } " instead." } ;
188
189 HELP: process
190 { $class-description "A class representing a process. Instances are created by calling " { $link <process> } "." } ;
191
192 HELP: <process>
193 { $values { "process" process } }
194 { $description "Creates a new, empty process. It must be filled in before being passed to " { $link run-process } "." } ;
195
196 HELP: <process-stream>
197 { $values
198   { "desc" "a launch descriptor" }
199   { "encoding" "an encoding descriptor" }
200   { "stream" "a bidirectional stream" } }
201 { $description "Launches a process and redirects its input and output via a pair of pipes which may be read and written as a stream with the given encoding." }
202 { $notes "The process is started with the " { $slot "hidden" } " slot set to " { $link t } "." }
203 { $see-also "io.launcher.hidden" } ;
204
205 HELP: <process-reader>
206 { $values
207   { "desc" "a launch descriptor" }
208   { "encoding" "an encoding descriptor" }
209   { "stream" "an input stream" } }
210 { $description "Launches a process and redirects its output via a pipe which may be read as a stream with the given encoding." } ;
211
212 HELP: <process-writer>
213 { $values
214   { "desc" "a launch descriptor" }
215   { "encoding" "an encoding descriptor" }
216   { "stream" "an output stream" }
217 }
218 { $description "Launches a process and redirects its input via a pipe which may be written to as a stream with the given encoding." } ;
219
220 HELP: with-process-stream
221 { $values
222   { "desc" "a launch descriptor" }
223   { "encoding" "an encoding descriptor" }
224   { "quot" quotation }
225 }
226 { $description "Launches a process and redirects its input and output via a pair of pipes. The quotation is called with " { $link input-stream } " and " { $link output-stream } " rebound to these pipes." }
227 { $notes "The process is started with the " { $slot "hidden" } " slot set to " { $link t } "." }
228 { $see-also "io.launcher.hidden" } ;
229
230 HELP: with-process-reader
231 { $values
232   { "desc" "a launch descriptor" }
233   { "encoding" "an encoding descriptor" }
234   { "quot" quotation }
235 }
236 { $description "Launches a process and redirects its output via a pipe. The quotation is called with " { $link input-stream } " rebound to this pipe." }
237 { $examples
238   { $unchecked-example
239     "USING: io.launcher prettyprint io.encodings.utf8 ;"
240     "\"ls -dl /etc\" utf8 [ read-contents ] with-process-reader ."
241     "\"drwxr-xr-x 213 root root 12288 mar 11 18:52 /etc\\n\""
242   }
243 } ;
244
245 HELP: with-process-writer
246 { $values
247   { "desc" "a launch descriptor" }
248   { "encoding" "an encoding descriptor" }
249   { "quot" quotation }
250 }
251 { $description "Launches a process and redirects its input via a pipe. The quotation is called with " { $link output-stream } " rebound to this pipe." } ;
252
253 HELP: wait-for-process
254 { $values { "process" process } { "status" object } }
255 { $description "If the process is still running, waits for it to exit, otherwise outputs the status code immediately. Can be called multiple times on the same process." }
256 { $notes "The status code is operating system specific; it may be an integer, or another object (the latter is the case on Unix if the process was killed by a signal). However, one cross-platform behavior code can rely on is that a status code of 0 indicates success." } ;
257
258 ARTICLE: "io.launcher.descriptors" "Launch descriptors"
259 "Words which launch processes can take either a command line string, a sequence of command line arguments, or a " { $link process } "."
260 $nl
261 "Strings and string arrays are wrapped in a new empty " { $link process } " with the " { $snippet "command" } " slot set. This covers basic use-cases where no launch parameters need to be set."
262 $nl
263 "A " { $link process } " instance can be created directly and passed to launching words for more control. It must be a fresh instance which has never been spawned before. To spawn a process several times from the same descriptor, " { $link clone } " the descriptor first." ;
264
265 ARTICLE: "io.launcher.lifecycle" "The process lifecycle"
266 "A freshly instantiated " { $link process } " represents a set of launch parameters."
267 { $subsections
268     process
269     <process>
270 }
271 "Words for launching processes take a fresh process which has never been started before as input, and output a copy as output."
272 { $subsections process-started? }
273 "The " { $link process } " instance output by launching words contains all original slot values in addition to the " { $snippet "handle" } " slot, which indicates the process is currently running."
274 { $subsections process-running? }
275 "It is possible to wait for a process to exit:"
276 { $subsections wait-for-process }
277 "A running process can also be killed:"
278 { $subsections kill-process } ;
279
280 ARTICLE: "io.launcher.launch" "Launching processes"
281 "Launching processes:"
282 { $subsections
283     run-process
284     try-process
285     run-detached
286 }
287 "Redirecting standard input and output to a pipe:"
288 { $subsections
289     <process-reader>
290     <process-writer>
291     <process-stream>
292 }
293 "Combinators built on top of the above:"
294 { $subsections
295     with-process-reader
296     with-process-writer
297     with-process-stream
298 } ;
299
300 ARTICLE: "io.launcher.examples" "Launcher examples"
301 "Starting a command and waiting for it to finish:"
302 { $code
303     "\"ls /etc\" run-process wait-for-process"
304 }
305 "Starting a program in the background:"
306 { $code
307     "{ \"emacs\" \"foo.txt\" } run-detached"
308 }
309 "Running a command, throwing an exception if it exits unsuccessfully:"
310 { $code
311     "\"make clean all\" try-process"
312 }
313 "Running a command, throwing an exception if it exits unsuccessfully or if it takes too long to run:"
314 { $code
315     "<process>"
316     "    \"make test\" >>command"
317     "    5 minutes >>timeout"
318     "try-process"
319 }
320 "Running a command, throwing an exception if it exits unsuccessfully, and redirecting output and error messages to a log file:"
321 { $code
322     "<process>"
323     "    \"make clean all\" >>command"
324     "    \"log.txt\" >>stdout"
325     "    +stdout+ >>stderr"
326     "try-process"
327 }
328 "Running a command, appending error messages to a log file, and reading the output for further processing:"
329 { $code
330     "\"log.txt\" ascii <file-appender> ["
331     "    <process>"
332     "        swap >>stderr"
333     "        \"report\" >>command"
334     "    ascii <process-reader> stream-lines sort reverse [ print ] each"
335     "] with-disposal"
336 } ;
337
338 ARTICLE: "io.launcher" "Operating system processes"
339 "The " { $vocab-link "io.launcher" } " vocabulary implements cross-platform process launching."
340 { $subsections
341     "io.launcher.examples"
342     "io.launcher.descriptors"
343     "io.launcher.launch"
344 }
345 "Advanced topics:"
346 { $subsections
347     "io.launcher.lifecycle"
348     "io.launcher.command"
349     "io.launcher.detached"
350     "io.launcher.hidden"
351     "io.launcher.environment"
352     "io.launcher.redirection"
353     "io.launcher.priority"
354     "io.launcher.group"
355     "io.launcher.timeouts"
356 } ;
357
358 ABOUT: "io.launcher"