alternative to assert
[gtkD.git] / src / glib / Spawn.d
blob48d16102b2ef6898540231320f210c6df8b910e0
1 /*
2 * This file is part of duit.
4 * duit is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; either version 2.1 of the License, or
7 * (at your option) any later version.
9 * duit is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with duit; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 // generated automatically - do not change
20 // find conversion definition on APILookup.txt
21 // implement new conversion functionalities on the wrap.utils pakage
24 * Conversion parameters:
25 * inFile = glib-Spawning-Processes.html
26 * outPack = glib
27 * outFile = Spawn
28 * strct =
29 * realStrct=
30 * ctorStrct=
31 * clss = Spawn
32 * interf =
33 * class Code: Yes
34 * interface Code: No
35 * template for:
36 * extend =
37 * implements:
38 * prefixes:
39 * - g_spawn_
40 * omit structs:
41 * omit prefixes:
42 * omit code:
43 * - g_spawn_async_with_pipes
44 * imports:
45 * - glib.ErrorG
46 * - glib.MainLoop
47 * - glib.Str
48 * - std.thread
49 * - std.stdio
50 * - std.string;
51 * - std.c.string;
52 * structWrap:
53 * - GMainLoop* -> MainLoop
54 * local aliases:
57 module glib.Spawn;
59 private import glib.glibtypes;
61 private import lib.glib;
63 private import glib.ErrorG;
64 private import glib.MainLoop;
65 private import glib.Str;
66 private import std.thread;
67 private import std.stdio;
68 private import std.string;;
69 private import std.c.string;;
71 /**
72 * Description
74 public class Spawn
77 char[] workingDirectory = ".";
78 char[][] argv;
79 char[][] envp;
80 GSpawnFlags flags = SpawnFlags.SEARCH_PATH;
81 GSpawnChildSetupFunc childSetup;
82 void* userData;
83 GPid childPid;
84 FILE* standardInput;
85 FILE* standardOutput;
86 FILE* standardError;
87 GError* error;
88 int stdIn;
89 int stdOut;
90 int stdErr;
92 // for commandLineSync
93 int exitStatus;
94 char* strOutput;
95 char* strError;
97 alias bool delegate(Spawn) ChildWatch;
98 ChildWatch externalWatch;
101 * Creates a Spawn for execution.
103 public this(char[] program, char[][] envp=null)
105 argv ~= program;
106 this.envp = envp;
110 * Creates a Spawn for execution.
112 public this(char[][] program, char[][] envp=null)
114 argv = program;
115 this.envp = envp;
119 * Adds a delegate to be notified on the end of the child process.
120 * Params:
121 * delegate(int =
122 * dlg =
124 public void addChildWatch(ChildWatch dlg)
126 externalWatch = dlg;
130 * Closes all open streams and child process.
132 public void close()
134 if (stdIn != 0 )
136 fclose(standardInput);
137 stdIn = 0;
139 if (stdOut != 0 )
141 fclose(standardOutput);
142 stdOut = 0;
144 if (stdErr != 0 )
146 fclose(standardError);
147 stdErr = 0;
149 if ( childPid != 0 )
151 closePid(childPid);
152 childPid = 0;
157 * Adds a parameter to the execution program
159 public void addParm(char[] parm)
161 argv ~= parm;
165 * Gets the last error message
167 public char[] getLastError()
169 if ( error != null )
171 return Str.toString(error.message);
173 return "";
178 * Executes the prepared process
180 public int execAsyncWithPipes(
181 ChildWatch externalWatch = null,
182 bool delegate(char[]) readOutput = null,
183 bool delegate(char[]) readError = null )
185 int result = g_spawn_async_with_pipes(
186 Str.toStringz(workingDirectory),
187 Str.toStringzArray(argv),
188 Str.toStringzArray(envp),
189 flags,
190 childSetup,
191 userData,
192 &childPid,
193 &stdIn,
194 &stdOut,
195 &stdErr,
196 &error
199 if ( result != 0 )
201 this.externalWatch = externalWatch;
202 g_child_watch_add(childPid, cast(GChildWatchFunc)(&childWatchCallback), this);
203 standardInput = fdopen(stdIn, "w");
204 standardOutput = fdopen(stdOut, "r");
205 standardError = fdopen(stdErr, "r");
207 if ( readOutput !is null )
209 (new ReadFile(standardOutput, readOutput)).start();
211 if ( readError !is null )
213 (new ReadFile(standardError, readError)).start();
217 return result;
220 class ReadFile : Thread
222 bool delegate(char[]) read;
223 FILE* file;
225 int lineCount;
227 this(FILE* file, bool delegate (char[]) read )
229 this.file = file;
230 this.read = read;
233 public int run()
235 char[] line = readLine(file);
236 while( line !is null )
238 ++lineCount;
239 //writefln("Spawn.ReadFile.run line (%s) ========== >>>%s<<<", lineCount, line);
240 //printf("Spawn.ReadFile.run line (%d) ========== >>>%.*s<<<", lineCount, line);
241 if ( read !is null )
243 read(line);
245 line = readLine(file);
247 return 0;
251 private char[] readLine(FILE* stream, int max=4096)
253 if ( feof(stream) )
255 if ( externalWatch !is null )
257 externalWatch(this);
259 return null;
261 char[] line;
262 line.length = max+1;
263 char* lineP = fgets(line.ptr, max, stream);
264 if ( lineP is null )
266 return "";
268 int l = strlen(line.ptr);
269 if ( l > 0 ) --l;
270 //printf("\nreadLine\n");
271 //foreach ( char c ; line )
273 // printf("%c", c);
275 //printf("\n\n");
276 return line[0..l];
279 extern(C) static void childWatchCallback(int pid, int status, Spawn spawn)
281 //writefln("Spawn.childWatchCallback %s %s", pid, status);
282 spawn.exitStatus = status;
283 if ( spawn.externalWatch !is null )
285 spawn.externalWatch(spawn);
287 spawn.close();
291 public bool endOfOutput()
293 if ( standardOutput is null ) return true;
294 return feof(standardOutput) != 0;
297 public bool endOfError()
299 if ( standardError is null ) return true;
300 return feof(standardError) != 0;
303 char[] getOutputString()
305 return Str.toString(strOutput);
308 char[] getErrorString()
310 return Str.toString(strError);
313 int getExitStatus()
315 return exitStatus;
318 // old version
319 // public int commandLineSync()
320 // {
321 // char[] commandLine;
322 // foreach ( int count, char[] arg; argv)
323 // {
324 // if ( count > 0 )
325 // {
326 // commandLine ~= ' ';
327 // }
328 // commandLine ~= arg;
329 // }
330 // return g_spawn_command_line_sync(
332 // Str.toStringz(commandLine),
333 // &strOutput,
334 // &strError,
335 // &exitStatus,
336 // &error);
337 // }
340 * Executes a command synchronasly and
341 * optionally calls delegates for sysout, syserr and end of job
344 public int commandLineSync(
345 ChildWatch externalWatch = null,
346 bool delegate(char[]) readOutput = null,
347 bool delegate(char[]) readError = null )
349 char[] commandLine;
350 foreach ( int count, char[] arg; argv)
352 if ( count > 0 )
354 commandLine ~= ' ';
356 commandLine ~= arg;
358 int status = g_spawn_command_line_sync(
359 Str.toStringz(commandLine),
360 &strOutput,
361 &strError,
362 &exitStatus,
363 &error);
364 if ( readOutput != null )
366 foreach ( char[] line ; splitlines(Str.toString(strOutput)) )
368 readOutput(line);
371 if ( readError != null )
373 foreach ( char[] line ; splitlines(Str.toString(strError)) )
375 readError(line);
378 if ( externalWatch != null )
380 externalWatch(this);
382 return status;
397 * See g_spawn_async_with_pipes() for a full description; this function
398 * simply calls the g_spawn_async_with_pipes() without any pipes.
399 * working_directory:
400 * child's current working directory, or NULL to inherit parent's
401 * argv:
402 * child's argument vector
403 * envp:
404 * child's environment, or NULL to inherit parent's
405 * flags:
406 * flags from GSpawnFlags
407 * child_setup:
408 * function to run in the child just before exec()
409 * user_data:
410 * user data for child_setup
411 * child_pid:
412 * return location for child process ID, or NULL
413 * error:
414 * return location for error
415 * Returns:
416 * TRUE on success, FALSE if error is set
418 public static int async(char[] workingDirectory, char** argv, char** envp, GSpawnFlags flags, GSpawnChildSetupFunc childSetup, void* userData, GPid* childPid, GError** error)
420 // gboolean g_spawn_async (const gchar *working_directory, gchar **argv, gchar **envp, GSpawnFlags flags, GSpawnChildSetupFunc child_setup, gpointer user_data, GPid *child_pid, GError **error);
421 return g_spawn_async(Str.toStringz(workingDirectory), argv, envp, flags, childSetup, userData, childPid, error);
425 * Executes a child synchronously (waits for the child to exit before returning).
426 * All output from the child is stored in standard_output and standard_error,
427 * if those parameters are non-NULL. If exit_status is non-NULL, the exit
428 * status of the child is stored there as it would be returned by
429 * waitpid(); standard UNIX macros such as WIFEXITED() and WEXITSTATUS()
430 * must be used to evaluate the exit status. If an error occurs, no data is
431 * returned in standard_output, standard_error, or exit_status.
432 * This function calls g_spawn_async_with_pipes() internally; see that
433 * function for full details on the other parameters and details on
434 * how these functions work on Windows.
435 * working_directory:
436 * child's current working directory, or NULL to inherit parent's
437 * argv:
438 * child's argument vector
439 * envp:
440 * child's environment, or NULL to inherit parent's
441 * flags:
442 * flags from GSpawnFlags
443 * child_setup:
444 * function to run in the child just before exec()
445 * user_data:
446 * user data for child_setup
447 * standard_output:
448 * return location for child output
449 * standard_error:
450 * return location for child error messages
451 * exit_status:
452 * return location for child exit status, as returned by waitpid()
453 * error:
454 * return location for error
455 * Returns:
456 * TRUE on success, FALSE if an error was set.
458 public static int sync(char[] workingDirectory, char** argv, char** envp, GSpawnFlags flags, GSpawnChildSetupFunc childSetup, void* userData, char** standardOutput, char** standardError, int* exitStatus, GError** error)
460 // gboolean g_spawn_sync (const gchar *working_directory, gchar **argv, gchar **envp, GSpawnFlags flags, GSpawnChildSetupFunc child_setup, gpointer user_data, gchar **standard_output, gchar **standard_error, gint *exit_status, GError **error);
461 return g_spawn_sync(Str.toStringz(workingDirectory), argv, envp, flags, childSetup, userData, standardOutput, standardError, exitStatus, error);
465 * A simple version of g_spawn_async() that parses a command line with
466 * g_shell_parse_argv() and passes it to g_spawn_async(). Runs a
467 * command line in the background. Unlike g_spawn_async(), the
468 * G_SPAWN_SEARCH_PATH flag is enabled, other flags are not. Note
469 * that G_SPAWN_SEARCH_PATH can have security implications, so
470 * consider using g_spawn_async() directly if appropriate. Possible
471 * errors are those from g_shell_parse_argv() and g_spawn_async().
472 * The same concerns on Windows apply as for g_spawn_command_line_sync().
473 * command_line:
474 * a command line
475 * error:
476 * return location for errors
477 * Returns:
478 * TRUE on success, FALSE if error is set.
480 public static int commandLineAsync(char[] commandLine, GError** error)
482 // gboolean g_spawn_command_line_async (const gchar *command_line, GError **error);
483 return g_spawn_command_line_async(Str.toStringz(commandLine), error);
487 * A simple version of g_spawn_sync() with little-used parameters
488 * removed, taking a command line instead of an argument vector. See
489 * g_spawn_sync() for full details. command_line will be parsed by
490 * g_shell_parse_argv(). Unlike g_spawn_sync(), the G_SPAWN_SEARCH_PATH flag
491 * is enabled. Note that G_SPAWN_SEARCH_PATH can have security
492 * implications, so consider using g_spawn_sync() directly if
493 * appropriate. Possible errors are those from g_spawn_sync() and those
494 * from g_shell_parse_argv().
495 * If exit_status is non-NULL, the exit status of the child is stored there as
496 * it would be returned by waitpid(); standard UNIX macros such as WIFEXITED()
497 * and WEXITSTATUS() must be used to evaluate the exit status.
498 * On Windows, please note the implications of g_shell_parse_argv()
499 * parsing command_line. Parsing is done according to Unix shell rules, not
500 * Windows command interpreter rules.
501 * Space is a separator, and backslashes are
502 * special. Thus you cannot simply pass a command_line containing
503 * canonical Windows paths, like "c:\\program files\\app\\app.exe", as
504 * the backslashes will be eaten, and the space will act as a
505 * separator. You need to enclose such paths with single quotes, like
506 * "'c:\\program files\\app\\app.exe' 'e:\\folder\\argument.txt'".
507 * command_line:
508 * a command line
509 * standard_output:
510 * return location for child output
511 * standard_error:
512 * return location for child errors
513 * exit_status:
514 * return location for child exit status, as returned by waitpid()
515 * error:
516 * return location for errors
517 * Returns:
518 * TRUE on success, FALSE if an error was set
520 public static int commandLineSync(char[] commandLine, char** standardOutput, char** standardError, int* exitStatus, GError** error)
522 // gboolean g_spawn_command_line_sync (const gchar *command_line, gchar **standard_output, gchar **standard_error, gint *exit_status, GError **error);
523 return g_spawn_command_line_sync(Str.toStringz(commandLine), standardOutput, standardError, exitStatus, error);
527 * On some platforms, notably WIN32, the GPid type represents a resource
528 * which must be closed to prevent resource leaking. g_spawn_close_pid()
529 * is provided for this purpose. It should be used on all platforms, even
530 * though it doesn't do anything under UNIX.
531 * pid:
532 * The process identifier to close
534 public static void closePid(GPid pid)
536 // void g_spawn_close_pid (GPid pid);
537 g_spawn_close_pid(pid);