1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gio.Subprocess;
26 
27 private import gio.AsyncResultIF;
28 private import gio.Cancellable;
29 private import gio.InitableIF;
30 private import gio.InitableT;
31 private import gio.InputStream;
32 private import gio.OutputStream;
33 private import glib.Bytes;
34 private import glib.ConstructionException;
35 private import glib.ErrorG;
36 private import glib.GException;
37 private import glib.Str;
38 private import gobject.ObjectG;
39 private import gtkc.gio;
40 public  import gtkc.giotypes;
41 
42 
43 /**
44  * #GSubprocess allows the creation of and interaction with child
45  * processes.
46  * 
47  * Processes can be communicated with using standard GIO-style APIs (ie:
48  * #GInputStream, #GOutputStream).  There are GIO-style APIs to wait for
49  * process termination (ie: cancellable and with an asynchronous
50  * variant).
51  * 
52  * There is an API to force a process to terminate, as well as a
53  * race-free API for sending UNIX signals to a subprocess.
54  * 
55  * One major advantage that GIO brings over the core GLib library is
56  * comprehensive API for asynchronous I/O, such
57  * g_output_stream_splice_async().  This makes GSubprocess
58  * significantly more powerful and flexible than equivalent APIs in
59  * some other languages such as the `subprocess.py`
60  * included with Python.  For example, using #GSubprocess one could
61  * create two child processes, reading standard output from the first,
62  * processing it, and writing to the input stream of the second, all
63  * without blocking the main loop.
64  * 
65  * A powerful g_subprocess_communicate() API is provided similar to the
66  * `communicate()` method of `subprocess.py`. This enables very easy
67  * interaction with a subprocess that has been opened with pipes.
68  * 
69  * #GSubprocess defaults to tight control over the file descriptors open
70  * in the child process, avoiding dangling-fd issues that are caused by
71  * a simple fork()/exec().  The only open file descriptors in the
72  * spawned process are ones that were explicitly specified by the
73  * #GSubprocess API (unless %G_SUBPROCESS_FLAGS_INHERIT_FDS was
74  * specified).
75  * 
76  * #GSubprocess will quickly reap all child processes as they exit,
77  * avoiding "zombie processes" remaining around for long periods of
78  * time.  g_subprocess_wait() can be used to wait for this to happen,
79  * but it will happen even without the call being explicitly made.
80  * 
81  * As a matter of principle, #GSubprocess has no API that accepts
82  * shell-style space-separated strings.  It will, however, match the
83  * typical shell behaviour of searching the PATH for executables that do
84  * not contain a directory separator in their name.
85  * 
86  * #GSubprocess attempts to have a very simple API for most uses (ie:
87  * spawning a subprocess with arguments and support for most typical
88  * kinds of input and output redirection).  See g_subprocess_new(). The
89  * #GSubprocessLauncher API is provided for more complicated cases
90  * (advanced types of redirection, environment variable manipulation,
91  * change of working directory, child setup functions, etc).
92  * 
93  * A typical use of #GSubprocess will involve calling
94  * g_subprocess_new(), followed by g_subprocess_wait_async() or
95  * g_subprocess_wait().  After the process exits, the status can be
96  * checked using functions such as g_subprocess_get_if_exited() (which
97  * are similar to the familiar WIFEXITED-style POSIX macros).
98  *
99  * Since: 2.40
100  */
101 public class Subprocess : ObjectG, InitableIF
102 {
103 	/** the main Gtk struct */
104 	protected GSubprocess* gSubprocess;
105 
106 	/** Get the main Gtk struct */
107 	public GSubprocess* getSubprocessStruct(bool transferOwnership = false)
108 	{
109 		if (transferOwnership)
110 			ownedRef = false;
111 		return gSubprocess;
112 	}
113 
114 	/** the main Gtk struct as a void* */
115 	protected override void* getStruct()
116 	{
117 		return cast(void*)gSubprocess;
118 	}
119 
120 	protected override void setStruct(GObject* obj)
121 	{
122 		gSubprocess = cast(GSubprocess*)obj;
123 		super.setStruct(obj);
124 	}
125 
126 	/**
127 	 * Sets our main struct and passes it to the parent class.
128 	 */
129 	public this (GSubprocess* gSubprocess, bool ownedRef = false)
130 	{
131 		this.gSubprocess = gSubprocess;
132 		super(cast(GObject*)gSubprocess, ownedRef);
133 	}
134 
135 	// add the Initable capabilities
136 	mixin InitableT!(GSubprocess);
137 
138 
139 	/** */
140 	public static GType getType()
141 	{
142 		return g_subprocess_get_type();
143 	}
144 
145 	/**
146 	 * Create a new process with the given flags and argument list.
147 	 *
148 	 * The argument list is expected to be %NULL-terminated.
149 	 *
150 	 * Params:
151 	 *     argv = commandline arguments for the subprocess
152 	 *     flags = flags that define the behaviour of the subprocess
153 	 *
154 	 * Returns: A newly created #GSubprocess, or %NULL on error (and @error
155 	 *     will be set)
156 	 *
157 	 * Since: 2.40
158 	 *
159 	 * Throws: GException on failure.
160 	 * Throws: ConstructionException GTK+ fails to create the object.
161 	 */
162 	public this(string[] argv, GSubprocessFlags flags)
163 	{
164 		GError* err = null;
165 		
166 		auto p = g_subprocess_newv(Str.toStringzArray(argv), flags, &err);
167 		
168 		if (err !is null)
169 		{
170 			throw new GException( new ErrorG(err) );
171 		}
172 		
173 		if(p is null)
174 		{
175 			throw new ConstructionException("null returned by newv");
176 		}
177 		
178 		this(cast(GSubprocess*) p, true);
179 	}
180 
181 	/**
182 	 * Communicate with the subprocess until it terminates, and all input
183 	 * and output has been completed.
184 	 *
185 	 * If @stdin_buf is given, the subprocess must have been created with
186 	 * %G_SUBPROCESS_FLAGS_STDIN_PIPE.  The given data is fed to the
187 	 * stdin of the subprocess and the pipe is closed (ie: EOF).
188 	 *
189 	 * At the same time (as not to cause blocking when dealing with large
190 	 * amounts of data), if %G_SUBPROCESS_FLAGS_STDOUT_PIPE or
191 	 * %G_SUBPROCESS_FLAGS_STDERR_PIPE were used, reads from those
192 	 * streams.  The data that was read is returned in @stdout and/or
193 	 * the @stderr.
194 	 *
195 	 * If the subprocess was created with %G_SUBPROCESS_FLAGS_STDOUT_PIPE,
196 	 * @stdout_buf will contain the data read from stdout.  Otherwise, for
197 	 * subprocesses not created with %G_SUBPROCESS_FLAGS_STDOUT_PIPE,
198 	 * @stdout_buf will be set to %NULL.  Similar provisions apply to
199 	 * @stderr_buf and %G_SUBPROCESS_FLAGS_STDERR_PIPE.
200 	 *
201 	 * As usual, any output variable may be given as %NULL to ignore it.
202 	 *
203 	 * If you desire the stdout and stderr data to be interleaved, create
204 	 * the subprocess with %G_SUBPROCESS_FLAGS_STDOUT_PIPE and
205 	 * %G_SUBPROCESS_FLAGS_STDERR_MERGE.  The merged result will be returned
206 	 * in @stdout_buf and @stderr_buf will be set to %NULL.
207 	 *
208 	 * In case of any error (including cancellation), %FALSE will be
209 	 * returned with @error set.  Some or all of the stdin data may have
210 	 * been written.  Any stdout or stderr data that has been read will be
211 	 * discarded. None of the out variables (aside from @error) will have
212 	 * been set to anything in particular and should not be inspected.
213 	 *
214 	 * In the case that %TRUE is returned, the subprocess has exited and the
215 	 * exit status inspection APIs (eg: g_subprocess_get_if_exited(),
216 	 * g_subprocess_get_exit_status()) may be used.
217 	 *
218 	 * You should not attempt to use any of the subprocess pipes after
219 	 * starting this function, since they may be left in strange states,
220 	 * even if the operation was cancelled.  You should especially not
221 	 * attempt to interact with the pipes while the operation is in progress
222 	 * (either from another thread or if using the asynchronous version).
223 	 *
224 	 * Params:
225 	 *     stdinBuf = data to send to the stdin of the subprocess, or %NULL
226 	 *     cancellable = a #GCancellable
227 	 *     stdoutBuf = data read from the subprocess stdout
228 	 *     stderrBuf = data read from the subprocess stderr
229 	 *
230 	 * Returns: %TRUE if successful
231 	 *
232 	 * Since: 2.40
233 	 *
234 	 * Throws: GException on failure.
235 	 */
236 	public bool communicate(Bytes stdinBuf, Cancellable cancellable, out Bytes stdoutBuf, out Bytes stderrBuf)
237 	{
238 		GBytes* outstdoutBuf = null;
239 		GBytes* outstderrBuf = null;
240 		GError* err = null;
241 		
242 		auto p = g_subprocess_communicate(gSubprocess, (stdinBuf is null) ? null : stdinBuf.getBytesStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), &outstdoutBuf, &outstderrBuf, &err) != 0;
243 		
244 		if (err !is null)
245 		{
246 			throw new GException( new ErrorG(err) );
247 		}
248 		
249 		stdoutBuf = new Bytes(outstdoutBuf);
250 		stderrBuf = new Bytes(outstderrBuf);
251 		
252 		return p;
253 	}
254 
255 	/**
256 	 * Asynchronous version of g_subprocess_communicate().  Complete
257 	 * invocation with g_subprocess_communicate_finish().
258 	 *
259 	 * Params:
260 	 *     stdinBuf = Input data, or %NULL
261 	 *     cancellable = Cancellable
262 	 *     callback = Callback
263 	 *     userData = User data
264 	 */
265 	public void communicateAsync(Bytes stdinBuf, Cancellable cancellable, GAsyncReadyCallback callback, void* userData)
266 	{
267 		g_subprocess_communicate_async(gSubprocess, (stdinBuf is null) ? null : stdinBuf.getBytesStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData);
268 	}
269 
270 	/**
271 	 * Complete an invocation of g_subprocess_communicate_async().
272 	 *
273 	 * Params:
274 	 *     result = Result
275 	 *     stdoutBuf = Return location for stdout data
276 	 *     stderrBuf = Return location for stderr data
277 	 *
278 	 * Throws: GException on failure.
279 	 */
280 	public bool communicateFinish(AsyncResultIF result, out Bytes stdoutBuf, out Bytes stderrBuf)
281 	{
282 		GBytes* outstdoutBuf = null;
283 		GBytes* outstderrBuf = null;
284 		GError* err = null;
285 		
286 		auto p = g_subprocess_communicate_finish(gSubprocess, (result is null) ? null : result.getAsyncResultStruct(), &outstdoutBuf, &outstderrBuf, &err) != 0;
287 		
288 		if (err !is null)
289 		{
290 			throw new GException( new ErrorG(err) );
291 		}
292 		
293 		stdoutBuf = new Bytes(outstdoutBuf);
294 		stderrBuf = new Bytes(outstderrBuf);
295 		
296 		return p;
297 	}
298 
299 	/**
300 	 * Like g_subprocess_communicate(), but validates the output of the
301 	 * process as UTF-8, and returns it as a regular NUL terminated string.
302 	 *
303 	 * Params:
304 	 *     stdinBuf = data to send to the stdin of the subprocess, or %NULL
305 	 *     cancellable = a #GCancellable
306 	 *     stdoutBuf = data read from the subprocess stdout
307 	 *     stderrBuf = data read from the subprocess stderr
308 	 *
309 	 * Throws: GException on failure.
310 	 */
311 	public bool communicateUtf8(string stdinBuf, Cancellable cancellable, out string stdoutBuf, out string stderrBuf)
312 	{
313 		char* outstdoutBuf = null;
314 		char* outstderrBuf = null;
315 		GError* err = null;
316 		
317 		auto p = g_subprocess_communicate_utf8(gSubprocess, Str.toStringz(stdinBuf), (cancellable is null) ? null : cancellable.getCancellableStruct(), &outstdoutBuf, &outstderrBuf, &err) != 0;
318 		
319 		if (err !is null)
320 		{
321 			throw new GException( new ErrorG(err) );
322 		}
323 		
324 		stdoutBuf = Str.toString(outstdoutBuf);
325 		stderrBuf = Str.toString(outstderrBuf);
326 		
327 		return p;
328 	}
329 
330 	/**
331 	 * Asynchronous version of g_subprocess_communicate_utf8().  Complete
332 	 * invocation with g_subprocess_communicate_utf8_finish().
333 	 *
334 	 * Params:
335 	 *     stdinBuf = Input data, or %NULL
336 	 *     cancellable = Cancellable
337 	 *     callback = Callback
338 	 *     userData = User data
339 	 */
340 	public void communicateUtf8Async(string stdinBuf, Cancellable cancellable, GAsyncReadyCallback callback, void* userData)
341 	{
342 		g_subprocess_communicate_utf8_async(gSubprocess, Str.toStringz(stdinBuf), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData);
343 	}
344 
345 	/**
346 	 * Complete an invocation of g_subprocess_communicate_utf8_async().
347 	 *
348 	 * Params:
349 	 *     result = Result
350 	 *     stdoutBuf = Return location for stdout data
351 	 *     stderrBuf = Return location for stderr data
352 	 *
353 	 * Throws: GException on failure.
354 	 */
355 	public bool communicateUtf8Finish(AsyncResultIF result, out string stdoutBuf, out string stderrBuf)
356 	{
357 		char* outstdoutBuf = null;
358 		char* outstderrBuf = null;
359 		GError* err = null;
360 		
361 		auto p = g_subprocess_communicate_utf8_finish(gSubprocess, (result is null) ? null : result.getAsyncResultStruct(), &outstdoutBuf, &outstderrBuf, &err) != 0;
362 		
363 		if (err !is null)
364 		{
365 			throw new GException( new ErrorG(err) );
366 		}
367 		
368 		stdoutBuf = Str.toString(outstdoutBuf);
369 		stderrBuf = Str.toString(outstderrBuf);
370 		
371 		return p;
372 	}
373 
374 	/**
375 	 * Use an operating-system specific method to attempt an immediate,
376 	 * forceful termination of the process.  There is no mechanism to
377 	 * determine whether or not the request itself was successful;
378 	 * however, you can use g_subprocess_wait() to monitor the status of
379 	 * the process after calling this function.
380 	 *
381 	 * On Unix, this function sends %SIGKILL.
382 	 *
383 	 * Since: 2.40
384 	 */
385 	public void forceExit()
386 	{
387 		g_subprocess_force_exit(gSubprocess);
388 	}
389 
390 	/**
391 	 * Check the exit status of the subprocess, given that it exited
392 	 * normally.  This is the value passed to the exit() system call or the
393 	 * return value from main.
394 	 *
395 	 * This is equivalent to the system WEXITSTATUS macro.
396 	 *
397 	 * It is an error to call this function before g_subprocess_wait() and
398 	 * unless g_subprocess_get_if_exited() returned %TRUE.
399 	 *
400 	 * Returns: the exit status
401 	 *
402 	 * Since: 2.40
403 	 */
404 	public int getExitStatus()
405 	{
406 		return g_subprocess_get_exit_status(gSubprocess);
407 	}
408 
409 	/**
410 	 * On UNIX, returns the process ID as a decimal string.
411 	 * On Windows, returns the result of GetProcessId() also as a string.
412 	 */
413 	public string getIdentifier()
414 	{
415 		return Str.toString(g_subprocess_get_identifier(gSubprocess));
416 	}
417 
418 	/**
419 	 * Check if the given subprocess exited normally (ie: by way of exit()
420 	 * or return from main()).
421 	 *
422 	 * This is equivalent to the system WIFEXITED macro.
423 	 *
424 	 * It is an error to call this function before g_subprocess_wait() has
425 	 * returned.
426 	 *
427 	 * Returns: %TRUE if the case of a normal exit
428 	 *
429 	 * Since: 2.40
430 	 */
431 	public bool getIfExited()
432 	{
433 		return g_subprocess_get_if_exited(gSubprocess) != 0;
434 	}
435 
436 	/**
437 	 * Check if the given subprocess terminated in response to a signal.
438 	 *
439 	 * This is equivalent to the system WIFSIGNALED macro.
440 	 *
441 	 * It is an error to call this function before g_subprocess_wait() has
442 	 * returned.
443 	 *
444 	 * Returns: %TRUE if the case of termination due to a signal
445 	 *
446 	 * Since: 2.40
447 	 */
448 	public bool getIfSignaled()
449 	{
450 		return g_subprocess_get_if_signaled(gSubprocess) != 0;
451 	}
452 
453 	/**
454 	 * Gets the raw status code of the process, as from waitpid().
455 	 *
456 	 * This value has no particular meaning, but it can be used with the
457 	 * macros defined by the system headers such as WIFEXITED.  It can also
458 	 * be used with g_spawn_check_exit_status().
459 	 *
460 	 * It is more likely that you want to use g_subprocess_get_if_exited()
461 	 * followed by g_subprocess_get_exit_status().
462 	 *
463 	 * It is an error to call this function before g_subprocess_wait() has
464 	 * returned.
465 	 *
466 	 * Returns: the (meaningless) waitpid() exit status from the kernel
467 	 *
468 	 * Since: 2.40
469 	 */
470 	public int getStatus()
471 	{
472 		return g_subprocess_get_status(gSubprocess);
473 	}
474 
475 	/**
476 	 * Gets the #GInputStream from which to read the stderr output of
477 	 * @subprocess.
478 	 *
479 	 * The process must have been created with
480 	 * %G_SUBPROCESS_FLAGS_STDERR_PIPE.
481 	 *
482 	 * Returns: the stderr pipe
483 	 *
484 	 * Since: 2.40
485 	 */
486 	public InputStream getStderrPipe()
487 	{
488 		auto p = g_subprocess_get_stderr_pipe(gSubprocess);
489 		
490 		if(p is null)
491 		{
492 			return null;
493 		}
494 		
495 		return ObjectG.getDObject!(InputStream)(cast(GInputStream*) p);
496 	}
497 
498 	/**
499 	 * Gets the #GOutputStream that you can write to in order to give data
500 	 * to the stdin of @subprocess.
501 	 *
502 	 * The process must have been created with
503 	 * %G_SUBPROCESS_FLAGS_STDIN_PIPE.
504 	 *
505 	 * Returns: the stdout pipe
506 	 *
507 	 * Since: 2.40
508 	 */
509 	public OutputStream getStdinPipe()
510 	{
511 		auto p = g_subprocess_get_stdin_pipe(gSubprocess);
512 		
513 		if(p is null)
514 		{
515 			return null;
516 		}
517 		
518 		return ObjectG.getDObject!(OutputStream)(cast(GOutputStream*) p);
519 	}
520 
521 	/**
522 	 * Gets the #GInputStream from which to read the stdout output of
523 	 * @subprocess.
524 	 *
525 	 * The process must have been created with
526 	 * %G_SUBPROCESS_FLAGS_STDOUT_PIPE.
527 	 *
528 	 * Returns: the stdout pipe
529 	 *
530 	 * Since: 2.40
531 	 */
532 	public InputStream getStdoutPipe()
533 	{
534 		auto p = g_subprocess_get_stdout_pipe(gSubprocess);
535 		
536 		if(p is null)
537 		{
538 			return null;
539 		}
540 		
541 		return ObjectG.getDObject!(InputStream)(cast(GInputStream*) p);
542 	}
543 
544 	/**
545 	 * Checks if the process was "successful".  A process is considered
546 	 * successful if it exited cleanly with an exit status of 0, either by
547 	 * way of the exit() system call or return from main().
548 	 *
549 	 * It is an error to call this function before g_subprocess_wait() has
550 	 * returned.
551 	 *
552 	 * Returns: %TRUE if the process exited cleanly with a exit status of 0
553 	 *
554 	 * Since: 2.40
555 	 */
556 	public bool getSuccessful()
557 	{
558 		return g_subprocess_get_successful(gSubprocess) != 0;
559 	}
560 
561 	/**
562 	 * Get the signal number that caused the subprocess to terminate, given
563 	 * that it terminated due to a signal.
564 	 *
565 	 * This is equivalent to the system WTERMSIG macro.
566 	 *
567 	 * It is an error to call this function before g_subprocess_wait() and
568 	 * unless g_subprocess_get_if_signaled() returned %TRUE.
569 	 *
570 	 * Returns: the signal causing termination
571 	 *
572 	 * Since: 2.40
573 	 */
574 	public int getTermSig()
575 	{
576 		return g_subprocess_get_term_sig(gSubprocess);
577 	}
578 
579 	/**
580 	 * Sends the UNIX signal @signal_num to the subprocess, if it is still
581 	 * running.
582 	 *
583 	 * This API is race-free.  If the subprocess has terminated, it will not
584 	 * be signalled.
585 	 *
586 	 * This API is not available on Windows.
587 	 *
588 	 * Params:
589 	 *     signalNum = the signal number to send
590 	 *
591 	 * Since: 2.40
592 	 */
593 	public void sendSignal(int signalNum)
594 	{
595 		g_subprocess_send_signal(gSubprocess, signalNum);
596 	}
597 
598 	/**
599 	 * Synchronously wait for the subprocess to terminate.
600 	 *
601 	 * After the process terminates you can query its exit status with
602 	 * functions such as g_subprocess_get_if_exited() and
603 	 * g_subprocess_get_exit_status().
604 	 *
605 	 * This function does not fail in the case of the subprocess having
606 	 * abnormal termination.  See g_subprocess_wait_check() for that.
607 	 *
608 	 * Cancelling @cancellable doesn't kill the subprocess.  Call
609 	 * g_subprocess_force_exit() if it is desirable.
610 	 *
611 	 * Params:
612 	 *     cancellable = a #GCancellable
613 	 *
614 	 * Returns: %TRUE on success, %FALSE if @cancellable was cancelled
615 	 *
616 	 * Since: 2.40
617 	 *
618 	 * Throws: GException on failure.
619 	 */
620 	public bool wait(Cancellable cancellable)
621 	{
622 		GError* err = null;
623 		
624 		auto p = g_subprocess_wait(gSubprocess, (cancellable is null) ? null : cancellable.getCancellableStruct(), &err) != 0;
625 		
626 		if (err !is null)
627 		{
628 			throw new GException( new ErrorG(err) );
629 		}
630 		
631 		return p;
632 	}
633 
634 	/**
635 	 * Wait for the subprocess to terminate.
636 	 *
637 	 * This is the asynchronous version of g_subprocess_wait().
638 	 *
639 	 * Params:
640 	 *     cancellable = a #GCancellable, or %NULL
641 	 *     callback = a #GAsyncReadyCallback to call when the operation is complete
642 	 *     userData = user_data for @callback
643 	 *
644 	 * Since: 2.40
645 	 */
646 	public void waitAsync(Cancellable cancellable, GAsyncReadyCallback callback, void* userData)
647 	{
648 		g_subprocess_wait_async(gSubprocess, (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData);
649 	}
650 
651 	/**
652 	 * Combines g_subprocess_wait() with g_spawn_check_exit_status().
653 	 *
654 	 * Params:
655 	 *     cancellable = a #GCancellable
656 	 *
657 	 * Returns: %TRUE on success, %FALSE if process exited abnormally, or
658 	 *     @cancellable was cancelled
659 	 *
660 	 * Since: 2.40
661 	 *
662 	 * Throws: GException on failure.
663 	 */
664 	public bool waitCheck(Cancellable cancellable)
665 	{
666 		GError* err = null;
667 		
668 		auto p = g_subprocess_wait_check(gSubprocess, (cancellable is null) ? null : cancellable.getCancellableStruct(), &err) != 0;
669 		
670 		if (err !is null)
671 		{
672 			throw new GException( new ErrorG(err) );
673 		}
674 		
675 		return p;
676 	}
677 
678 	/**
679 	 * Combines g_subprocess_wait_async() with g_spawn_check_exit_status().
680 	 *
681 	 * This is the asynchronous version of g_subprocess_wait_check().
682 	 *
683 	 * Params:
684 	 *     cancellable = a #GCancellable, or %NULL
685 	 *     callback = a #GAsyncReadyCallback to call when the operation is complete
686 	 *     userData = user_data for @callback
687 	 *
688 	 * Since: 2.40
689 	 */
690 	public void waitCheckAsync(Cancellable cancellable, GAsyncReadyCallback callback, void* userData)
691 	{
692 		g_subprocess_wait_check_async(gSubprocess, (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData);
693 	}
694 
695 	/**
696 	 * Collects the result of a previous call to
697 	 * g_subprocess_wait_check_async().
698 	 *
699 	 * Params:
700 	 *     result = the #GAsyncResult passed to your #GAsyncReadyCallback
701 	 *
702 	 * Returns: %TRUE if successful, or %FALSE with @error set
703 	 *
704 	 * Since: 2.40
705 	 *
706 	 * Throws: GException on failure.
707 	 */
708 	public bool waitCheckFinish(AsyncResultIF result)
709 	{
710 		GError* err = null;
711 		
712 		auto p = g_subprocess_wait_check_finish(gSubprocess, (result is null) ? null : result.getAsyncResultStruct(), &err) != 0;
713 		
714 		if (err !is null)
715 		{
716 			throw new GException( new ErrorG(err) );
717 		}
718 		
719 		return p;
720 	}
721 
722 	/**
723 	 * Collects the result of a previous call to
724 	 * g_subprocess_wait_async().
725 	 *
726 	 * Params:
727 	 *     result = the #GAsyncResult passed to your #GAsyncReadyCallback
728 	 *
729 	 * Returns: %TRUE if successful, or %FALSE with @error set
730 	 *
731 	 * Since: 2.40
732 	 *
733 	 * Throws: GException on failure.
734 	 */
735 	public bool waitFinish(AsyncResultIF result)
736 	{
737 		GError* err = null;
738 		
739 		auto p = g_subprocess_wait_finish(gSubprocess, (result is null) ? null : result.getAsyncResultStruct(), &err) != 0;
740 		
741 		if (err !is null)
742 		{
743 			throw new GException( new ErrorG(err) );
744 		}
745 		
746 		return p;
747 	}
748 }