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