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()
108 	{
109 		return gSubprocess;
110 	}
111 
112 	/** the main Gtk struct as a void* */
113 	protected override void* getStruct()
114 	{
115 		return cast(void*)gSubprocess;
116 	}
117 
118 	protected override void setStruct(GObject* obj)
119 	{
120 		gSubprocess = cast(GSubprocess*)obj;
121 		super.setStruct(obj);
122 	}
123 
124 	/**
125 	 * Sets our main struct and passes it to the parent class.
126 	 */
127 	public this (GSubprocess* gSubprocess, bool ownedRef = false)
128 	{
129 		this.gSubprocess = gSubprocess;
130 		super(cast(GObject*)gSubprocess, ownedRef);
131 	}
132 
133 	// add the Initable capabilities
134 	mixin InitableT!(GSubprocess);
135 
136 	/**
137 	 */
138 
139 	public static GType getType()
140 	{
141 		return g_subprocess_get_type();
142 	}
143 
144 	/**
145 	 * Create a new process with the given flags and argument list.
146 	 *
147 	 * The argument list is expected to be %NULL-terminated.
148 	 *
149 	 * Params:
150 	 *     argv = commandline arguments for the subprocess
151 	 *     flags = flags that define the behaviour of the subprocess
152 	 *
153 	 * Return: A newly created #GSubprocess, or %NULL on error (and @error
154 	 *     will be set)
155 	 *
156 	 * Since: 2.40
157 	 *
158 	 * Throws: GException on failure.
159 	 * Throws: ConstructionException GTK+ fails to create the object.
160 	 */
161 	public this(string[] argv, GSubprocessFlags flags)
162 	{
163 		GError* err = null;
164 		
165 		auto p = g_subprocess_newv(Str.toStringzArray(argv), flags, &err);
166 		
167 		if(p is null)
168 		{
169 			throw new ConstructionException("null returned by newv");
170 		}
171 		
172 		if (err !is null)
173 		{
174 			throw new GException( new ErrorG(err) );
175 		}
176 		
177 		this(cast(GSubprocess*) p, true);
178 	}
179 
180 	/**
181 	 * Communicate with the subprocess until it terminates, and all input
182 	 * and output has been completed.
183 	 *
184 	 * If @stdin_buf is given, the subprocess must have been created with
185 	 * %G_SUBPROCESS_FLAGS_STDIN_PIPE.  The given data is fed to the
186 	 * stdin of the subprocess and the pipe is closed (ie: EOF).
187 	 *
188 	 * At the same time (as not to cause blocking when dealing with large
189 	 * amounts of data), if %G_SUBPROCESS_FLAGS_STDOUT_PIPE or
190 	 * %G_SUBPROCESS_FLAGS_STDERR_PIPE were used, reads from those
191 	 * streams.  The data that was read is returned in @stdout and/or
192 	 * the @stderr.
193 	 *
194 	 * If the subprocess was created with %G_SUBPROCESS_FLAGS_STDOUT_PIPE,
195 	 * @stdout_buf will contain the data read from stdout.  Otherwise, for
196 	 * subprocesses not created with %G_SUBPROCESS_FLAGS_STDOUT_PIPE,
197 	 * @stdout_buf will be set to %NULL.  Similar provisions apply to
198 	 * @stderr_buf and %G_SUBPROCESS_FLAGS_STDERR_PIPE.
199 	 *
200 	 * As usual, any output variable may be given as %NULL to ignore it.
201 	 *
202 	 * If you desire the stdout and stderr data to be interleaved, create
203 	 * the subprocess with %G_SUBPROCESS_FLAGS_STDOUT_PIPE and
204 	 * %G_SUBPROCESS_FLAGS_STDERR_MERGE.  The merged result will be returned
205 	 * in @stdout_buf and @stderr_buf will be set to %NULL.
206 	 *
207 	 * In case of any error (including cancellation), %FALSE will be
208 	 * returned with @error set.  Some or all of the stdin data may have
209 	 * been written.  Any stdout or stderr data that has been read will be
210 	 * discarded. None of the out variables (aside from @error) will have
211 	 * been set to anything in particular and should not be inspected.
212 	 *
213 	 * In the case that %TRUE is returned, the subprocess has exited and the
214 	 * exit status inspection APIs (eg: g_subprocess_get_if_exited(),
215 	 * g_subprocess_get_exit_status()) may be used.
216 	 *
217 	 * You should not attempt to use any of the subprocess pipes after
218 	 * starting this function, since they may be left in strange states,
219 	 * even if the operation was cancelled.  You should especially not
220 	 * attempt to interact with the pipes while the operation is in progress
221 	 * (either from another thread or if using the asynchronous version).
222 	 *
223 	 * Params:
224 	 *     stdinBuf = data to send to the stdin of the subprocess, or %NULL
225 	 *     cancellable = a #GCancellable
226 	 *     stdoutBuf = data read from the subprocess stdout
227 	 *     stderrBuf = data read from the subprocess stderr
228 	 *
229 	 * Return: %TRUE if successful
230 	 *
231 	 * Since: 2.40
232 	 *
233 	 * Throws: GException on failure.
234 	 */
235 	public bool communicate(Bytes stdinBuf, Cancellable cancellable, out Bytes stdoutBuf, out Bytes stderrBuf)
236 	{
237 		GBytes* outstdoutBuf = null;
238 		GBytes* outstderrBuf = null;
239 		GError* err = null;
240 		
241 		auto p = g_subprocess_communicate(gSubprocess, (stdinBuf is null) ? null : stdinBuf.getBytesStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), &outstdoutBuf, &outstderrBuf, &err) != 0;
242 		
243 		if (err !is null)
244 		{
245 			throw new GException( new ErrorG(err) );
246 		}
247 		
248 		stdoutBuf = new Bytes(outstdoutBuf);
249 		stderrBuf = new Bytes(outstderrBuf);
250 		
251 		return p;
252 	}
253 
254 	/**
255 	 * Asynchronous version of g_subprocess_communicate().  Complete
256 	 * invocation with g_subprocess_communicate_finish().
257 	 *
258 	 * Params:
259 	 *     stdinBuf = Input data, or %NULL
260 	 *     cancellable = Cancellable
261 	 *     callback = Callback
262 	 *     userData = User data
263 	 */
264 	public void communicateAsync(Bytes stdinBuf, Cancellable cancellable, GAsyncReadyCallback callback, void* userData)
265 	{
266 		g_subprocess_communicate_async(gSubprocess, (stdinBuf is null) ? null : stdinBuf.getBytesStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData);
267 	}
268 
269 	/**
270 	 * Complete an invocation of g_subprocess_communicate_async().
271 	 *
272 	 * Params:
273 	 *     result = Result
274 	 *     stdoutBuf = Return location for stdout data
275 	 *     stderrBuf = Return location for stderr data
276 	 *
277 	 * Throws: GException on failure.
278 	 */
279 	public bool communicateFinish(AsyncResultIF result, out Bytes stdoutBuf, out Bytes stderrBuf)
280 	{
281 		GBytes* outstdoutBuf = null;
282 		GBytes* outstderrBuf = null;
283 		GError* err = null;
284 		
285 		auto p = g_subprocess_communicate_finish(gSubprocess, (result is null) ? null : result.getAsyncResultStruct(), &outstdoutBuf, &outstderrBuf, &err) != 0;
286 		
287 		if (err !is null)
288 		{
289 			throw new GException( new ErrorG(err) );
290 		}
291 		
292 		stdoutBuf = new Bytes(outstdoutBuf);
293 		stderrBuf = new Bytes(outstderrBuf);
294 		
295 		return p;
296 	}
297 
298 	/**
299 	 * Like g_subprocess_communicate(), but validates the output of the
300 	 * process as UTF-8, and returns it as a regular NUL terminated string.
301 	 *
302 	 * Params:
303 	 *     stdinBuf = data to send to the stdin of the subprocess, or %NULL
304 	 *     cancellable = a #GCancellable
305 	 *     stdoutBuf = data read from the subprocess stdout
306 	 *     stderrBuf = data read from the subprocess stderr
307 	 *
308 	 * Throws: GException on failure.
309 	 */
310 	public bool communicateUtf8(string stdinBuf, Cancellable cancellable, out string stdoutBuf, out string stderrBuf)
311 	{
312 		char* outstdoutBuf = null;
313 		char* outstderrBuf = null;
314 		GError* err = null;
315 		
316 		auto p = g_subprocess_communicate_utf8(gSubprocess, Str.toStringz(stdinBuf), (cancellable is null) ? null : cancellable.getCancellableStruct(), &outstdoutBuf, &outstderrBuf, &err) != 0;
317 		
318 		if (err !is null)
319 		{
320 			throw new GException( new ErrorG(err) );
321 		}
322 		
323 		stdoutBuf = Str.toString(outstdoutBuf);
324 		stderrBuf = Str.toString(outstderrBuf);
325 		
326 		return p;
327 	}
328 
329 	/**
330 	 * Asynchronous version of g_subprocess_communicate_utf8().  Complete
331 	 * invocation with g_subprocess_communicate_utf8_finish().
332 	 *
333 	 * Params:
334 	 *     stdinBuf = Input data, or %NULL
335 	 *     cancellable = Cancellable
336 	 *     callback = Callback
337 	 *     userData = User data
338 	 */
339 	public void communicateUtf8Async(string stdinBuf, Cancellable cancellable, GAsyncReadyCallback callback, void* userData)
340 	{
341 		g_subprocess_communicate_utf8_async(gSubprocess, Str.toStringz(stdinBuf), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData);
342 	}
343 
344 	/**
345 	 * Complete an invocation of g_subprocess_communicate_utf8_async().
346 	 *
347 	 * Params:
348 	 *     result = Result
349 	 *     stdoutBuf = Return location for stdout data
350 	 *     stderrBuf = Return location for stderr data
351 	 *
352 	 * Throws: GException on failure.
353 	 */
354 	public bool communicateUtf8Finish(AsyncResultIF result, out string stdoutBuf, out string stderrBuf)
355 	{
356 		char* outstdoutBuf = null;
357 		char* outstderrBuf = null;
358 		GError* err = null;
359 		
360 		auto p = g_subprocess_communicate_utf8_finish(gSubprocess, (result is null) ? null : result.getAsyncResultStruct(), &outstdoutBuf, &outstderrBuf, &err) != 0;
361 		
362 		if (err !is null)
363 		{
364 			throw new GException( new ErrorG(err) );
365 		}
366 		
367 		stdoutBuf = Str.toString(outstdoutBuf);
368 		stderrBuf = Str.toString(outstderrBuf);
369 		
370 		return p;
371 	}
372 
373 	/**
374 	 * Use an operating-system specific method to attempt an immediate,
375 	 * forceful termination of the process.  There is no mechanism to
376 	 * determine whether or not the request itself was successful;
377 	 * however, you can use g_subprocess_wait() to monitor the status of
378 	 * the process after calling this function.
379 	 *
380 	 * On Unix, this function sends %SIGKILL.
381 	 *
382 	 * Since: 2.40
383 	 */
384 	public void forceExit()
385 	{
386 		g_subprocess_force_exit(gSubprocess);
387 	}
388 
389 	/**
390 	 * Check the exit status of the subprocess, given that it exited
391 	 * normally.  This is the value passed to the exit() system call or the
392 	 * return value from main.
393 	 *
394 	 * This is equivalent to the system WEXITSTATUS macro.
395 	 *
396 	 * It is an error to call this function before g_subprocess_wait() and
397 	 * unless g_subprocess_get_if_exited() returned %TRUE.
398 	 *
399 	 * Return: the exit status
400 	 *
401 	 * Since: 2.40
402 	 */
403 	public int getExitStatus()
404 	{
405 		return g_subprocess_get_exit_status(gSubprocess);
406 	}
407 
408 	/**
409 	 * On UNIX, returns the process ID as a decimal string.
410 	 * On Windows, returns the result of GetProcessId() also as a string.
411 	 */
412 	public string getIdentifier()
413 	{
414 		return Str.toString(g_subprocess_get_identifier(gSubprocess));
415 	}
416 
417 	/**
418 	 * Check if the given subprocess exited normally (ie: by way of exit()
419 	 * or return from main()).
420 	 *
421 	 * This is equivalent to the system WIFEXITED macro.
422 	 *
423 	 * It is an error to call this function before g_subprocess_wait() has
424 	 * returned.
425 	 *
426 	 * Return: %TRUE if the case of a normal exit
427 	 *
428 	 * Since: 2.40
429 	 */
430 	public bool getIfExited()
431 	{
432 		return g_subprocess_get_if_exited(gSubprocess) != 0;
433 	}
434 
435 	/**
436 	 * Check if the given subprocess terminated in response to a signal.
437 	 *
438 	 * This is equivalent to the system WIFSIGNALED macro.
439 	 *
440 	 * It is an error to call this function before g_subprocess_wait() has
441 	 * returned.
442 	 *
443 	 * Return: %TRUE if the case of termination due to a signal
444 	 *
445 	 * Since: 2.40
446 	 */
447 	public bool getIfSignaled()
448 	{
449 		return g_subprocess_get_if_signaled(gSubprocess) != 0;
450 	}
451 
452 	/**
453 	 * Gets the raw status code of the process, as from waitpid().
454 	 *
455 	 * This value has no particular meaning, but it can be used with the
456 	 * macros defined by the system headers such as WIFEXITED.  It can also
457 	 * be used with g_spawn_check_exit_status().
458 	 *
459 	 * It is more likely that you want to use g_subprocess_get_if_exited()
460 	 * followed by g_subprocess_get_exit_status().
461 	 *
462 	 * It is an error to call this function before g_subprocess_wait() has
463 	 * returned.
464 	 *
465 	 * Return: the (meaningless) waitpid() exit status from the kernel
466 	 *
467 	 * Since: 2.40
468 	 */
469 	public int getStatus()
470 	{
471 		return g_subprocess_get_status(gSubprocess);
472 	}
473 
474 	/**
475 	 * Gets the #GInputStream from which to read the stderr output of
476 	 * @subprocess.
477 	 *
478 	 * The process must have been created with
479 	 * %G_SUBPROCESS_FLAGS_STDERR_PIPE.
480 	 *
481 	 * Return: the stderr pipe
482 	 *
483 	 * Since: 2.40
484 	 */
485 	public InputStream getStderrPipe()
486 	{
487 		auto p = g_subprocess_get_stderr_pipe(gSubprocess);
488 		
489 		if(p is null)
490 		{
491 			return null;
492 		}
493 		
494 		return ObjectG.getDObject!(InputStream)(cast(GInputStream*) p);
495 	}
496 
497 	/**
498 	 * Gets the #GOutputStream that you can write to in order to give data
499 	 * to the stdin of @subprocess.
500 	 *
501 	 * The process must have been created with
502 	 * %G_SUBPROCESS_FLAGS_STDIN_PIPE.
503 	 *
504 	 * Return: the stdout pipe
505 	 *
506 	 * Since: 2.40
507 	 */
508 	public OutputStream getStdinPipe()
509 	{
510 		auto p = g_subprocess_get_stdin_pipe(gSubprocess);
511 		
512 		if(p is null)
513 		{
514 			return null;
515 		}
516 		
517 		return ObjectG.getDObject!(OutputStream)(cast(GOutputStream*) p);
518 	}
519 
520 	/**
521 	 * Gets the #GInputStream from which to read the stdout output of
522 	 * @subprocess.
523 	 *
524 	 * The process must have been created with
525 	 * %G_SUBPROCESS_FLAGS_STDOUT_PIPE.
526 	 *
527 	 * Return: the stdout pipe
528 	 *
529 	 * Since: 2.40
530 	 */
531 	public InputStream getStdoutPipe()
532 	{
533 		auto p = g_subprocess_get_stdout_pipe(gSubprocess);
534 		
535 		if(p is null)
536 		{
537 			return null;
538 		}
539 		
540 		return ObjectG.getDObject!(InputStream)(cast(GInputStream*) p);
541 	}
542 
543 	/**
544 	 * Checks if the process was "successful".  A process is considered
545 	 * successful if it exited cleanly with an exit status of 0, either by
546 	 * way of the exit() system call or return from main().
547 	 *
548 	 * It is an error to call this function before g_subprocess_wait() has
549 	 * returned.
550 	 *
551 	 * Return: %TRUE if the process exited cleanly with a exit status of 0
552 	 *
553 	 * Since: 2.40
554 	 */
555 	public bool getSuccessful()
556 	{
557 		return g_subprocess_get_successful(gSubprocess) != 0;
558 	}
559 
560 	/**
561 	 * Get the signal number that caused the subprocess to terminate, given
562 	 * that it terminated due to a signal.
563 	 *
564 	 * This is equivalent to the system WTERMSIG macro.
565 	 *
566 	 * It is an error to call this function before g_subprocess_wait() and
567 	 * unless g_subprocess_get_if_signaled() returned %TRUE.
568 	 *
569 	 * Return: the signal causing termination
570 	 *
571 	 * Since: 2.40
572 	 */
573 	public int getTermSig()
574 	{
575 		return g_subprocess_get_term_sig(gSubprocess);
576 	}
577 
578 	/**
579 	 * Sends the UNIX signal @signal_num to the subprocess, if it is still
580 	 * running.
581 	 *
582 	 * This API is race-free.  If the subprocess has terminated, it will not
583 	 * be signalled.
584 	 *
585 	 * This API is not available on Windows.
586 	 *
587 	 * Params:
588 	 *     signalNum = the signal number to send
589 	 *
590 	 * Since: 2.40
591 	 */
592 	public void sendSignal(int signalNum)
593 	{
594 		g_subprocess_send_signal(gSubprocess, signalNum);
595 	}
596 
597 	/**
598 	 * Synchronously wait for the subprocess to terminate.
599 	 *
600 	 * After the process terminates you can query its exit status with
601 	 * functions such as g_subprocess_get_if_exited() and
602 	 * g_subprocess_get_exit_status().
603 	 *
604 	 * This function does not fail in the case of the subprocess having
605 	 * abnormal termination.  See g_subprocess_wait_check() for that.
606 	 *
607 	 * Cancelling @cancellable doesn't kill the subprocess.  Call
608 	 * g_subprocess_force_exit() if it is desirable.
609 	 *
610 	 * Params:
611 	 *     cancellable = a #GCancellable
612 	 *
613 	 * Return: %TRUE on success, %FALSE if @cancellable was cancelled
614 	 *
615 	 * Since: 2.40
616 	 *
617 	 * Throws: GException on failure.
618 	 */
619 	public bool wait(Cancellable cancellable)
620 	{
621 		GError* err = null;
622 		
623 		auto p = g_subprocess_wait(gSubprocess, (cancellable is null) ? null : cancellable.getCancellableStruct(), &err) != 0;
624 		
625 		if (err !is null)
626 		{
627 			throw new GException( new ErrorG(err) );
628 		}
629 		
630 		return p;
631 	}
632 
633 	/**
634 	 * Wait for the subprocess to terminate.
635 	 *
636 	 * This is the asynchronous version of g_subprocess_wait().
637 	 *
638 	 * Params:
639 	 *     cancellable = a #GCancellable, or %NULL
640 	 *     callback = a #GAsyncReadyCallback to call when the operation is complete
641 	 *     userData = user_data for @callback
642 	 *
643 	 * Since: 2.40
644 	 */
645 	public void waitAsync(Cancellable cancellable, GAsyncReadyCallback callback, void* userData)
646 	{
647 		g_subprocess_wait_async(gSubprocess, (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData);
648 	}
649 
650 	/**
651 	 * Combines g_subprocess_wait() with g_spawn_check_exit_status().
652 	 *
653 	 * Params:
654 	 *     cancellable = a #GCancellable
655 	 *
656 	 * Return: %TRUE on success, %FALSE if process exited abnormally, or
657 	 *     @cancellable was cancelled
658 	 *
659 	 * Since: 2.40
660 	 *
661 	 * Throws: GException on failure.
662 	 */
663 	public bool waitCheck(Cancellable cancellable)
664 	{
665 		GError* err = null;
666 		
667 		auto p = g_subprocess_wait_check(gSubprocess, (cancellable is null) ? null : cancellable.getCancellableStruct(), &err) != 0;
668 		
669 		if (err !is null)
670 		{
671 			throw new GException( new ErrorG(err) );
672 		}
673 		
674 		return p;
675 	}
676 
677 	/**
678 	 * Combines g_subprocess_wait_async() with g_spawn_check_exit_status().
679 	 *
680 	 * This is the asynchronous version of g_subprocess_wait_check().
681 	 *
682 	 * Params:
683 	 *     cancellable = a #GCancellable, or %NULL
684 	 *     callback = a #GAsyncReadyCallback to call when the operation is complete
685 	 *     userData = user_data for @callback
686 	 *
687 	 * Since: 2.40
688 	 */
689 	public void waitCheckAsync(Cancellable cancellable, GAsyncReadyCallback callback, void* userData)
690 	{
691 		g_subprocess_wait_check_async(gSubprocess, (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData);
692 	}
693 
694 	/**
695 	 * Collects the result of a previous call to
696 	 * g_subprocess_wait_check_async().
697 	 *
698 	 * Params:
699 	 *     result = the #GAsyncResult passed to your #GAsyncReadyCallback
700 	 *
701 	 * Return: %TRUE if successful, or %FALSE with @error set
702 	 *
703 	 * Since: 2.40
704 	 *
705 	 * Throws: GException on failure.
706 	 */
707 	public bool waitCheckFinish(AsyncResultIF result)
708 	{
709 		GError* err = null;
710 		
711 		auto p = g_subprocess_wait_check_finish(gSubprocess, (result is null) ? null : result.getAsyncResultStruct(), &err) != 0;
712 		
713 		if (err !is null)
714 		{
715 			throw new GException( new ErrorG(err) );
716 		}
717 		
718 		return p;
719 	}
720 
721 	/**
722 	 * Collects the result of a previous call to
723 	 * g_subprocess_wait_async().
724 	 *
725 	 * Params:
726 	 *     result = the #GAsyncResult passed to your #GAsyncReadyCallback
727 	 *
728 	 * Return: %TRUE if successful, or %FALSE with @error set
729 	 *
730 	 * Since: 2.40
731 	 *
732 	 * Throws: GException on failure.
733 	 */
734 	public bool waitFinish(AsyncResultIF result)
735 	{
736 		GError* err = null;
737 		
738 		auto p = g_subprocess_wait_finish(gSubprocess, (result is null) ? null : result.getAsyncResultStruct(), &err) != 0;
739 		
740 		if (err !is null)
741 		{
742 			throw new GException( new ErrorG(err) );
743 		}
744 		
745 		return p;
746 	}
747 }