alternative to assert
[gtkD.git] / gtkD / src / glib / Spawn.d
blob4de8622b6e2ccd0ba66a823d2252eca939457c7b
1 /*
2 * This file is part of gtkD.
4 * gtkD 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 * gtkD 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 gtkD; 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.c.stdio
51 * - std.string
52 * - std.c.string
53 * structWrap:
54 * - GMainLoop* -> MainLoop
55 * module aliases:
56 * local aliases:
59 module glib.Spawn;
61 version(noAssert)
63 version(Tango)
65 import tango.io.Stdout; // use the tango loging?
69 private import gtkc.glibtypes;
71 private import gtkc.glib;
74 private import glib.ErrorG;
75 private import glib.MainLoop;
76 private import glib.Str;
79 version(Tango) {
80 private import tango.core.Thread;
81 private import tango.stdc.stdio;
82 private import tango.stdc.posix.stdio;
83 private import tango.text.Util;
84 private import tango.stdc.string;
85 } else {
86 private import std.thread;
87 private import std.stdio;
88 private import std.c.stdio;
89 private import std.string;
90 private import std.c.string;
96 /**
97 * Description
99 public class Spawn
102 version(Tango) alias splitLines splitlines;
105 char[] workingDirectory = ".";
106 char[][] argv;
107 char[][] envp;
108 GSpawnFlags flags = SpawnFlags.SEARCH_PATH;
109 GSpawnChildSetupFunc childSetup;
110 void* userData;
111 GPid childPid;
112 FILE* standardInput;
113 FILE* standardOutput;
114 FILE* standardError;
115 GError* error;
116 int stdIn;
117 int stdOut;
118 int stdErr;
120 // for commandLineSync
121 int exitStatus;
122 char* strOutput;
123 char* strError;
125 alias bool delegate(Spawn) ChildWatch;
126 ChildWatch externalWatch;
129 * Creates a Spawn for execution.
131 public this(char[] program, char[][] envp=null)
133 argv ~= program;
134 this.envp = envp;
138 * Creates a Spawn for execution.
140 public this(char[][] program, char[][] envp=null)
142 argv = program;
143 this.envp = envp;
147 * Adds a delegate to be notified on the end of the child process.
148 * Params:
149 * delegate(int =
150 * dlg =
152 public void addChildWatch(ChildWatch dlg)
154 externalWatch = dlg;
158 * Closes all open streams and child process.
160 public void close()
162 if (stdIn != 0 )
164 fclose(standardInput);
165 stdIn = 0;
167 if (stdOut != 0 )
169 fclose(standardOutput);
170 stdOut = 0;
172 if (stdErr != 0 )
174 fclose(standardError);
175 stdErr = 0;
177 if ( childPid != 0 )
179 closePid(childPid);
180 childPid = 0;
185 * Adds a parameter to the execution program
187 public void addParm(char[] parm)
189 argv ~= parm;
193 * Gets the last error message
195 public char[] getLastError()
197 if ( error != null )
199 return Str.toString(error.message);
201 return "";
206 * Executes the prepared process
208 public int execAsyncWithPipes(
209 ChildWatch externalWatch = null,
210 bool delegate(char[]) readOutput = null,
211 bool delegate(char[]) readError = null )
213 int result = g_spawn_async_with_pipes(
214 Str.toStringz(workingDirectory),
215 Str.toStringzArray(argv),
216 Str.toStringzArray(envp),
217 flags,
218 childSetup,
219 userData,
220 &childPid,
221 &stdIn,
222 &stdOut,
223 &stdErr,
224 &error
227 if ( result != 0 )
229 this.externalWatch = externalWatch;
230 g_child_watch_add(childPid, cast(GChildWatchFunc)(&childWatchCallback), cast(void*)this);
231 standardInput = fdopen(stdIn, "w");
232 standardOutput = fdopen(stdOut, "r");
233 standardError = fdopen(stdErr, "r");
235 if ( readOutput !is null )
237 (new ReadFile(standardOutput, readOutput)).start();
239 if ( readError !is null )
241 (new ReadFile(standardError, readError)).start();
245 return result;
248 class ReadFile : Thread
250 bool delegate(char[]) read;
251 FILE* file;
253 int lineCount;
255 this(FILE* file, bool delegate (char[]) read )
257 this.file = file;
258 this.read = read;
261 public int run()
263 char[] line = readLine(file);
264 while( line !is null )
266 ++lineCount;
267 //writefln("Spawn.ReadFile.run line (%s) ========== >>>%s<<<", lineCount, line);
268 //printf("Spawn.ReadFile.run line (%d) ========== >>>%.*s<<<", lineCount, line);
269 if ( read !is null )
271 read(line);
273 line = readLine(file);
275 return 0;
279 private char[] readLine(FILE* stream, int max=4096)
281 if ( feof(stream) )
283 if ( externalWatch !is null )
285 externalWatch(this);
287 return null;
289 char[] line;
290 line.length = max+1;
291 char* lineP = fgets(line.ptr, max, stream);
292 if ( lineP is null )
294 return "";
296 int l = strlen(line.ptr);
297 if ( l > 0 ) --l;
298 //printf("\nreadLine\n");
299 //foreach ( char c ; line )
301 // printf("%c", c);
303 //printf("\n\n");
304 return line[0..l];
307 extern(C) static void childWatchCallback(int pid, int status, Spawn spawn)
309 //writefln("Spawn.childWatchCallback %s %s", pid, status);
310 spawn.exitStatus = status;
311 if ( spawn.externalWatch !is null )
313 spawn.externalWatch(spawn);
315 spawn.close();
319 public bool endOfOutput()
321 if ( standardOutput is null ) return true;
322 return feof(standardOutput) != 0;
325 public bool endOfError()
327 if ( standardError is null ) return true;
328 return feof(standardError) != 0;
331 char[] getOutputString()
333 return Str.toString(strOutput);
336 char[] getErrorString()
338 return Str.toString(strError);
341 int getExitStatus()
343 return exitStatus;
346 // old version
347 // public int commandLineSync()
348 // {
349 // char[] commandLine;
350 // foreach ( int count, char[] arg; argv)
351 // {
352 // if ( count > 0 )
353 // {
354 // commandLine ~= ' ';
355 // }
356 // commandLine ~= arg;
357 // }
358 // return g_spawn_command_line_sync(
360 // Str.toStringz(commandLine),
361 // &strOutput,
362 // &strError,
363 // &exitStatus,
364 // &error);
365 // }
368 * Executes a command synchronasly and
369 * optionally calls delegates for sysout, syserr and end of job
372 public int commandLineSync(
373 ChildWatch externalWatch = null,
374 bool delegate(char[]) readOutput = null,
375 bool delegate(char[]) readError = null )
377 char[] commandLine;
378 foreach ( int count, char[] arg; argv)
380 if ( count > 0 )
382 commandLine ~= ' ';
384 commandLine ~= arg;
386 int status = g_spawn_command_line_sync(
387 Str.toStringz(commandLine),
388 &strOutput,
389 &strError,
390 &exitStatus,
391 &error);
392 if ( readOutput != null )
394 foreach ( char[] line ; splitlines(Str.toString(strOutput)) )
396 readOutput(line);
399 if ( readError != null )
401 foreach ( char[] line ; splitlines(Str.toString(strError)) )
403 readError(line);
406 if ( externalWatch != null )
408 externalWatch(this);
410 return status;
425 * See g_spawn_async_with_pipes() for a full description; this function
426 * simply calls the g_spawn_async_with_pipes() without any pipes.
427 * Note
428 * If you are writing a GTK+ application, and the program you
429 * are spawning is a graphical application, too, then you may
430 * want to use gdk_spawn_on_screen() instead to ensure that
431 * the spawned program opens its windows no the right screen.
432 * working_directory:
433 * child's current working directory, or NULL to inherit parent's
434 * argv:
435 * child's argument vector
436 * envp:
437 * child's environment, or NULL to inherit parent's
438 * flags:
439 * flags from GSpawnFlags
440 * child_setup:
441 * function to run in the child just before exec()
442 * user_data:
443 * user data for child_setup
444 * child_pid:
445 * return location for child process ID, or NULL
446 * error:
447 * return location for error
448 * Returns:
449 * TRUE on success, FALSE if error is set
451 public static int async(char[] workingDirectory, char** argv, char** envp, GSpawnFlags flags, GSpawnChildSetupFunc childSetup, void* userData, GPid* childPid, GError** error)
453 // 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);
454 return g_spawn_async(Str.toStringz(workingDirectory), argv, envp, flags, childSetup, userData, childPid, error);
458 * Executes a child synchronously (waits for the child to exit before returning).
459 * All output from the child is stored in standard_output and standard_error,
460 * if those parameters are non-NULL. If exit_status is non-NULL, the exit
461 * status of the child is stored there as it would be returned by
462 * waitpid(); standard UNIX macros such as WIFEXITED() and WEXITSTATUS()
463 * must be used to evaluate the exit status. If an error occurs, no data is
464 * returned in standard_output, standard_error, or exit_status.
465 * This function calls g_spawn_async_with_pipes() internally; see that
466 * function for full details on the other parameters and details on
467 * how these functions work on Windows.
468 * working_directory:
469 * child's current working directory, or NULL to inherit parent's
470 * argv:
471 * child's argument vector
472 * envp:
473 * child's environment, or NULL to inherit parent's
474 * flags:
475 * flags from GSpawnFlags
476 * child_setup:
477 * function to run in the child just before exec()
478 * user_data:
479 * user data for child_setup
480 * standard_output:
481 * return location for child output
482 * standard_error:
483 * return location for child error messages
484 * exit_status:
485 * return location for child exit status, as returned by waitpid()
486 * error:
487 * return location for error
488 * Returns:
489 * TRUE on success, FALSE if an error was set.
491 public static int sync(char[] workingDirectory, char** argv, char** envp, GSpawnFlags flags, GSpawnChildSetupFunc childSetup, void* userData, char** standardOutput, char** standardError, int* exitStatus, GError** error)
493 // 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);
494 return g_spawn_sync(Str.toStringz(workingDirectory), argv, envp, flags, childSetup, userData, standardOutput, standardError, exitStatus, error);
498 * A simple version of g_spawn_async() that parses a command line with
499 * g_shell_parse_argv() and passes it to g_spawn_async(). Runs a
500 * command line in the background. Unlike g_spawn_async(), the
501 * G_SPAWN_SEARCH_PATH flag is enabled, other flags are not. Note
502 * that G_SPAWN_SEARCH_PATH can have security implications, so
503 * consider using g_spawn_async() directly if appropriate. Possible
504 * errors are those from g_shell_parse_argv() and g_spawn_async().
505 * The same concerns on Windows apply as for g_spawn_command_line_sync().
506 * command_line:
507 * a command line
508 * error:
509 * return location for errors
510 * Returns:
511 * TRUE on success, FALSE if error is set.
513 public static int commandLineAsync(char[] commandLine, GError** error)
515 // gboolean g_spawn_command_line_async (const gchar *command_line, GError **error);
516 return g_spawn_command_line_async(Str.toStringz(commandLine), error);
520 * A simple version of g_spawn_sync() with little-used parameters
521 * removed, taking a command line instead of an argument vector. See
522 * g_spawn_sync() for full details. command_line will be parsed by
523 * g_shell_parse_argv(). Unlike g_spawn_sync(), the G_SPAWN_SEARCH_PATH flag
524 * is enabled. Note that G_SPAWN_SEARCH_PATH can have security
525 * implications, so consider using g_spawn_sync() directly if
526 * appropriate. Possible errors are those from g_spawn_sync() and those
527 * from g_shell_parse_argv().
528 * If exit_status is non-NULL, the exit status of the child is stored there as
529 * it would be returned by waitpid(); standard UNIX macros such as WIFEXITED()
530 * and WEXITSTATUS() must be used to evaluate the exit status.
531 * On Windows, please note the implications of g_shell_parse_argv()
532 * parsing command_line. Parsing is done according to Unix shell rules, not
533 * Windows command interpreter rules.
534 * Space is a separator, and backslashes are
535 * special. Thus you cannot simply pass a command_line containing
536 * canonical Windows paths, like "c:\\program files\\app\\app.exe", as
537 * the backslashes will be eaten, and the space will act as a
538 * separator. You need to enclose such paths with single quotes, like
539 * "'c:\\program files\\app\\app.exe' 'e:\\folder\\argument.txt'".
540 * command_line:
541 * a command line
542 * standard_output:
543 * return location for child output
544 * standard_error:
545 * return location for child errors
546 * exit_status:
547 * return location for child exit status, as returned by waitpid()
548 * error:
549 * return location for errors
550 * Returns:
551 * TRUE on success, FALSE if an error was set
553 public static int commandLineSync(char[] commandLine, char** standardOutput, char** standardError, int* exitStatus, GError** error)
555 // gboolean g_spawn_command_line_sync (const gchar *command_line, gchar **standard_output, gchar **standard_error, gint *exit_status, GError **error);
556 return g_spawn_command_line_sync(Str.toStringz(commandLine), standardOutput, standardError, exitStatus, error);
560 * On some platforms, notably WIN32, the GPid type represents a resource
561 * which must be closed to prevent resource leaking. g_spawn_close_pid()
562 * is provided for this purpose. It should be used on all platforms, even
563 * though it doesn't do anything under UNIX.
564 * pid:
565 * The process identifier to close
567 public static void closePid(GPid pid)
569 // void g_spawn_close_pid (GPid pid);
570 g_spawn_close_pid(pid);