1// Package glib was automatically generated by github.com/bnema/puregotk DO NOT EDIT
2package glib
3
4import (
5 "unsafe"
6
7 "github.com/ebitengine/purego"
8
9 "github.com/bnema/puregotk/pkg/core"
10)
11
12// Specifies the type of the setup function passed to g_spawn_async(),
13// g_spawn_sync() and g_spawn_async_with_pipes(), which can, in very
14// limited ways, be used to affect the child's execution.
15//
16// On POSIX platforms, the function is called in the child after GLib
17// has performed all the setup it plans to perform, but before calling
18// exec(). Actions taken in this function will only affect the child,
19// not the parent.
20//
21// On Windows, the function is called in the parent. Its usefulness on
22// Windows is thus questionable. In many cases executing the child setup
23// function in the parent can have ill effects, and you should be very
24// careful when porting software to Windows that uses child setup
25// functions.
26//
27// However, even on POSIX, you are extremely limited in what you can
28// safely do from a #GSpawnChildSetupFunc, because any mutexes that were
29// held by other threads in the parent process at the time of the fork()
30// will still be locked in the child process, and they will never be
31// unlocked (since the threads that held them don't exist in the child).
32// POSIX allows only async-signal-safe functions (see signal(7)) to be
33// called in the child between fork() and exec(), which drastically limits
34// the usefulness of child setup functions.
35//
36// In particular, it is not safe to call any function which may
37// call malloc(), which includes POSIX functions such as setenv().
38// If you need to set up the child environment differently from
39// the parent, you should use g_get_environ(), g_environ_setenv(),
40// and g_environ_unsetenv(), and then pass the complete environment
41// list to the `g_spawn...` function.
42type SpawnChildSetupFunc func(uintptr)
43
44// Flags passed to g_spawn_sync(), g_spawn_async() and g_spawn_async_with_pipes().
45type SpawnFlags int
46
47const (
48
49 // no flags, default behaviour
50 GSpawnDefaultValue SpawnFlags = 0
51 // the parent's open file descriptors will
52 // be inherited by the child; otherwise all descriptors except stdin,
53 // stdout and stderr will be closed before calling exec() in the child.
54 GSpawnLeaveDescriptorsOpenValue SpawnFlags = 1
55 // the child will not be automatically reaped;
56 // you must use g_child_watch_add() yourself (or call waitpid() or handle
57 // `SIGCHLD` yourself), or the child will become a zombie.
58 GSpawnDoNotReapChildValue SpawnFlags = 2
59 // `argv[0]` need not be an absolute path, it will be
60 // looked for in the user's `PATH`.
61 GSpawnSearchPathValue SpawnFlags = 4
62 // the child's standard output will be discarded,
63 // instead of going to the same location as the parent's standard output.
64 GSpawnStdoutToDevNullValue SpawnFlags = 8
65 // the child's standard error will be discarded.
66 GSpawnStderrToDevNullValue SpawnFlags = 16
67 // the child will inherit the parent's standard
68 // input (by default, the child's standard input is attached to `/dev/null`).
69 GSpawnChildInheritsStdinValue SpawnFlags = 32
70 // the first element of `argv` is the file to
71 // execute, while the remaining elements are the actual argument vector
72 // to pass to the file. Normally g_spawn_async_with_pipes() uses `argv[0]`
73 // as the file to execute, and passes all of `argv` to the child.
74 GSpawnFileAndArgvZeroValue SpawnFlags = 64
75 // if `argv[0]` is not an absolute path,
76 // it will be looked for in the `PATH` from the passed child environment.
77 // Since: 2.34
78 GSpawnSearchPathFromEnvpValue SpawnFlags = 128
79 // create all pipes with the `O_CLOEXEC` flag set.
80 // Since: 2.40
81 GSpawnCloexecPipesValue SpawnFlags = 256
82 // The child will inherit the parent's standard output.
83 GSpawnChildInheritsStdoutValue SpawnFlags = 512
84 // The child will inherit the parent's standard error.
85 GSpawnChildInheritsStderrValue SpawnFlags = 1024
86 // The child's standard input is attached to `/dev/null`.
87 GSpawnStdinFromDevNullValue SpawnFlags = 2048
88)
89
90// Error codes returned by spawning processes.
91type SpawnError int
92
93const (
94
95 // Fork failed due to lack of memory.
96 GSpawnErrorForkValue SpawnError = 0
97 // Read or select on pipes failed.
98 GSpawnErrorReadValue SpawnError = 1
99 // Changing to working directory failed.
100 GSpawnErrorChdirValue SpawnError = 2
101 // execv() returned `EACCES`
102 GSpawnErrorAccesValue SpawnError = 3
103 // execv() returned `EPERM`
104 GSpawnErrorPermValue SpawnError = 4
105 // execv() returned `E2BIG`
106 GSpawnErrorTooBigValue SpawnError = 5
107 // deprecated alias for %G_SPAWN_ERROR_TOO_BIG (deprecated since GLib 2.32)
108 GSpawnError2bigValue SpawnError = 5
109 // execv() returned `ENOEXEC`
110 GSpawnErrorNoexecValue SpawnError = 6
111 // execv() returned `ENAMETOOLONG`
112 GSpawnErrorNametoolongValue SpawnError = 7
113 // execv() returned `ENOENT`
114 GSpawnErrorNoentValue SpawnError = 8
115 // execv() returned `ENOMEM`
116 GSpawnErrorNomemValue SpawnError = 9
117 // execv() returned `ENOTDIR`
118 GSpawnErrorNotdirValue SpawnError = 10
119 // execv() returned `ELOOP`
120 GSpawnErrorLoopValue SpawnError = 11
121 // execv() returned `ETXTBUSY`
122 GSpawnErrorTxtbusyValue SpawnError = 12
123 // execv() returned `EIO`
124 GSpawnErrorIoValue SpawnError = 13
125 // execv() returned `ENFILE`
126 GSpawnErrorNfileValue SpawnError = 14
127 // execv() returned `EMFILE`
128 GSpawnErrorMfileValue SpawnError = 15
129 // execv() returned `EINVAL`
130 GSpawnErrorInvalValue SpawnError = 16
131 // execv() returned `EISDIR`
132 GSpawnErrorIsdirValue SpawnError = 17
133 // execv() returned `ELIBBAD`
134 GSpawnErrorLibbadValue SpawnError = 18
135 // Some other fatal failure,
136 // `error->message` should explain.
137 GSpawnErrorFailedValue SpawnError = 19
138)
139
140var xSpawnAsync func(uintptr, []string, []string, SpawnFlags, uintptr, uintptr, *Pid, **Error) bool
141
142// Executes a child program asynchronously.
143//
144// See g_spawn_async_with_pipes_and_fds() for a full description; this function
145// simply calls the g_spawn_async_with_pipes() without any pipes, which in turn
146// calls g_spawn_async_with_pipes_and_fds().
147//
148// You should call g_spawn_close_pid() on the returned child process
149// reference when you don't need it any more.
150//
151// If you are writing a GTK application, and the program you are spawning is a
152// graphical application too, then to ensure that the spawned program opens its
153// windows on the right screen, you may want to use #GdkAppLaunchContext,
154// #GAppLaunchContext, or set the %DISPLAY environment variable.
155//
156// Note that the returned @child_pid on Windows is a handle to the child
157// process and not its identifier. Process handles and process identifiers
158// are different concepts on Windows.
159func SpawnAsync(WorkingDirectoryVar *string, ArgvVar []string, EnvpVar []string, FlagsVar SpawnFlags, ChildSetupVar *SpawnChildSetupFunc, UserDataVar uintptr, ChildPidVar *Pid) (bool, error) {
160 var cerr *Error
161
162 var ChildSetupVarRef uintptr
163 if ChildSetupVar != nil {
164 ChildSetupVarPtr := uintptr(unsafe.Pointer(ChildSetupVar))
165 if cbRefPtr, ok := GetCallback(ChildSetupVarPtr); ok {
166 ChildSetupVarRef = cbRefPtr
167 } else {
168 fcb := func(arg0 uintptr) {
169 cbFn := *ChildSetupVar
170 cbFn(arg0)
171 }
172 ChildSetupVarRef = purego.NewCallback(fcb)
173 SaveCallbackWithClosure(ChildSetupVarPtr, ChildSetupVarRef, ChildSetupVar)
174 }
175 }
176
177 WorkingDirectoryVarPtr := core.GStrdupNullable(WorkingDirectoryVar)
178 defer core.GFreeNullable(WorkingDirectoryVarPtr)
179
180 cret := xSpawnAsync(WorkingDirectoryVarPtr, ArgvVar, EnvpVar, FlagsVar, ChildSetupVarRef, UserDataVar, ChildPidVar, &cerr)
181
182 if cerr == nil {
183 return cret, nil
184 }
185 return cret, cerr
186
187}
188
189var xSpawnAsyncWithFds func(uintptr, []string, []string, SpawnFlags, uintptr, uintptr, *Pid, int, int, int, **Error) bool
190
191// Executes a child program asynchronously.
192//
193// Identical to g_spawn_async_with_pipes_and_fds() but with `n_fds` set to zero,
194// so no FD assignments are used.
195func SpawnAsyncWithFds(WorkingDirectoryVar *string, ArgvVar []string, EnvpVar []string, FlagsVar SpawnFlags, ChildSetupVar *SpawnChildSetupFunc, UserDataVar uintptr, ChildPidVar *Pid, StdinFdVar int, StdoutFdVar int, StderrFdVar int) (bool, error) {
196 var cerr *Error
197
198 var ChildSetupVarRef uintptr
199 if ChildSetupVar != nil {
200 ChildSetupVarPtr := uintptr(unsafe.Pointer(ChildSetupVar))
201 if cbRefPtr, ok := GetCallback(ChildSetupVarPtr); ok {
202 ChildSetupVarRef = cbRefPtr
203 } else {
204 fcb := func(arg0 uintptr) {
205 cbFn := *ChildSetupVar
206 cbFn(arg0)
207 }
208 ChildSetupVarRef = purego.NewCallback(fcb)
209 SaveCallbackWithClosure(ChildSetupVarPtr, ChildSetupVarRef, ChildSetupVar)
210 }
211 }
212
213 WorkingDirectoryVarPtr := core.GStrdupNullable(WorkingDirectoryVar)
214 defer core.GFreeNullable(WorkingDirectoryVarPtr)
215
216 cret := xSpawnAsyncWithFds(WorkingDirectoryVarPtr, ArgvVar, EnvpVar, FlagsVar, ChildSetupVarRef, UserDataVar, ChildPidVar, StdinFdVar, StdoutFdVar, StderrFdVar, &cerr)
217
218 if cerr == nil {
219 return cret, nil
220 }
221 return cret, cerr
222
223}
224
225var xSpawnAsyncWithPipes func(uintptr, []string, []string, SpawnFlags, uintptr, uintptr, *Pid, *int, *int, *int, **Error) bool
226
227// Identical to g_spawn_async_with_pipes_and_fds() but with `n_fds` set to zero,
228// so no FD assignments are used.
229func SpawnAsyncWithPipes(WorkingDirectoryVar *string, ArgvVar []string, EnvpVar []string, FlagsVar SpawnFlags, ChildSetupVar *SpawnChildSetupFunc, UserDataVar uintptr, ChildPidVar *Pid, StandardInputVar *int, StandardOutputVar *int, StandardErrorVar *int) (bool, error) {
230 var cerr *Error
231
232 var ChildSetupVarRef uintptr
233 if ChildSetupVar != nil {
234 ChildSetupVarPtr := uintptr(unsafe.Pointer(ChildSetupVar))
235 if cbRefPtr, ok := GetCallback(ChildSetupVarPtr); ok {
236 ChildSetupVarRef = cbRefPtr
237 } else {
238 fcb := func(arg0 uintptr) {
239 cbFn := *ChildSetupVar
240 cbFn(arg0)
241 }
242 ChildSetupVarRef = purego.NewCallback(fcb)
243 SaveCallbackWithClosure(ChildSetupVarPtr, ChildSetupVarRef, ChildSetupVar)
244 }
245 }
246
247 WorkingDirectoryVarPtr := core.GStrdupNullable(WorkingDirectoryVar)
248 defer core.GFreeNullable(WorkingDirectoryVarPtr)
249
250 cret := xSpawnAsyncWithPipes(WorkingDirectoryVarPtr, ArgvVar, EnvpVar, FlagsVar, ChildSetupVarRef, UserDataVar, ChildPidVar, StandardInputVar, StandardOutputVar, StandardErrorVar, &cerr)
251
252 if cerr == nil {
253 return cret, nil
254 }
255 return cret, cerr
256
257}
258
259var xSpawnAsyncWithPipesAndFds func(uintptr, []string, []string, SpawnFlags, uintptr, uintptr, int, int, int, []int, []int, uint, *Pid, *int, *int, *int, **Error) bool
260
261// Executes a child program asynchronously (your program will not
262// block waiting for the child to exit).
263//
264// The child program is specified by the only argument that must be
265// provided, @argv. @argv should be a %NULL-terminated array of strings,
266// to be passed as the argument vector for the child. The first string
267// in @argv is of course the name of the program to execute. By default,
268// the name of the program must be a full path. If @flags contains the
269// %G_SPAWN_SEARCH_PATH flag, the `PATH` environment variable is used to
270// search for the executable. If @flags contains the
271// %G_SPAWN_SEARCH_PATH_FROM_ENVP flag, the `PATH` variable from @envp
272// is used to search for the executable. If both the
273// %G_SPAWN_SEARCH_PATH and %G_SPAWN_SEARCH_PATH_FROM_ENVP flags are
274// set, the `PATH` variable from @envp takes precedence over the
275// environment variable.
276//
277// If the program name is not a full path and %G_SPAWN_SEARCH_PATH flag
278// is not used, then the program will be run from the current directory
279// (or @working_directory, if specified); this might be unexpected or even
280// dangerous in some cases when the current directory is world-writable.
281//
282// On Windows, note that all the string or string vector arguments to
283// this function and the other `g_spawn*()` functions are in UTF-8, the
284// GLib file name encoding. Unicode characters that are not part of
285// the system codepage passed in these arguments will be correctly
286// available in the spawned program only if it uses wide character API
287// to retrieve its command line. For C programs built with Microsoft's
288// tools it is enough to make the program have a `wmain()` instead of
289// `main()`. `wmain()` has a wide character argument vector as parameter.
290//
291// At least currently, mingw doesn't support `wmain()`, so if you use
292// mingw to develop the spawned program, it should call
293// g_win32_get_command_line() to get arguments in UTF-8.
294//
295// On Windows the low-level child process creation API `CreateProcess()`
296// doesn't use argument vectors, but a command line. The C runtime
297// library's `spawn*()` family of functions (which g_spawn_async_with_pipes()
298// eventually calls) paste the argument vector elements together into
299// a command line, and the C runtime startup code does a corresponding
300// reconstruction of an argument vector from the command line, to be
301// passed to `main()`. Complications arise when you have argument vector
302// elements that contain spaces or double quotes. The `spawn*()` functions
303// don't do any quoting or escaping, but on the other hand the startup
304// code does do unquoting and unescaping in order to enable receiving
305// arguments with embedded spaces or double quotes. To work around this
306// asymmetry, g_spawn_async_with_pipes() will do quoting and escaping on
307// argument vector elements that need it before calling the C runtime
308// `spawn()` function.
309//
310// The returned @child_pid on Windows is a handle to the child
311// process, not its identifier. Process handles and process
312// identifiers are different concepts on Windows.
313//
314// @envp is a %NULL-terminated array of strings, where each string
315// has the form `KEY=VALUE`. This will become the child's environment.
316// If @envp is %NULL, the child inherits its parent's environment.
317//
318// @flags should be the bitwise OR of any flags you want to affect the
319// function's behaviour. The %G_SPAWN_DO_NOT_REAP_CHILD means that the
320// child will not automatically be reaped; you must use a child watch
321// (g_child_watch_add()) to be notified about the death of the child process,
322// otherwise it will stay around as a zombie process until this process exits.
323// Eventually you must call g_spawn_close_pid() on the @child_pid, in order to
324// free resources which may be associated with the child process. (On Unix,
325// using a child watch is equivalent to calling waitpid() or handling
326// the `SIGCHLD` signal manually. On Windows, calling g_spawn_close_pid()
327// is equivalent to calling `CloseHandle()` on the process handle returned
328// in @child_pid). See g_child_watch_add().
329//
330// Open UNIX file descriptors marked as `FD_CLOEXEC` will be automatically
331// closed in the child process. %G_SPAWN_LEAVE_DESCRIPTORS_OPEN means that
332// other open file descriptors will be inherited by the child; otherwise all
333// descriptors except stdin/stdout/stderr will be closed before calling `exec()`
334// in the child. %G_SPAWN_SEARCH_PATH means that @argv[0] need not be an
335// absolute path, it will be looked for in the `PATH` environment
336// variable. %G_SPAWN_SEARCH_PATH_FROM_ENVP means need not be an
337// absolute path, it will be looked for in the `PATH` variable from
338// @envp. If both %G_SPAWN_SEARCH_PATH and %G_SPAWN_SEARCH_PATH_FROM_ENVP
339// are used, the value from @envp takes precedence over the environment.
340//
341// %G_SPAWN_CHILD_INHERITS_STDIN means that the child will inherit the parent's
342// standard input (by default, the child's standard input is attached to
343// `/dev/null`). %G_SPAWN_STDIN_FROM_DEV_NULL explicitly imposes the default
344// behavior. Both flags cannot be enabled at the same time and, in both cases,
345// the @stdin_pipe_out argument is ignored.
346//
347// %G_SPAWN_STDOUT_TO_DEV_NULL means that the child's standard output
348// will be discarded (by default, it goes to the same location as the parent's
349// standard output). %G_SPAWN_CHILD_INHERITS_STDOUT explicitly imposes the
350// default behavior. Both flags cannot be enabled at the same time and, in
351// both cases, the @stdout_pipe_out argument is ignored.
352//
353// %G_SPAWN_STDERR_TO_DEV_NULL means that the child's standard error
354// will be discarded (by default, it goes to the same location as the parent's
355// standard error). %G_SPAWN_CHILD_INHERITS_STDERR explicitly imposes the
356// default behavior. Both flags cannot be enabled at the same time and, in
357// both cases, the @stderr_pipe_out argument is ignored.
358//
359// It is valid to pass the same FD in multiple parameters (e.g. you can pass
360// a single FD for both @stdout_fd and @stderr_fd, and include it in
361// @source_fds too).
362//
363// @source_fds and @target_fds allow zero or more FDs from this process to be
364// remapped to different FDs in the spawned process. If @n_fds is greater than
365// zero, @source_fds and @target_fds must both be non-%NULL and the same length.
366// Each FD in @source_fds is remapped to the FD number at the same index in
367// @target_fds. The source and target FD may be equal to simply propagate an FD
368// to the spawned process. FD remappings are processed after standard FDs, so
369// any target FDs which equal @stdin_fd, @stdout_fd or @stderr_fd will overwrite
370// them in the spawned process.
371//
372// @source_fds is supported on Windows since 2.72.
373//
374// %G_SPAWN_FILE_AND_ARGV_ZERO means that the first element of @argv is
375// the file to execute, while the remaining elements are the actual
376// argument vector to pass to the file. Normally g_spawn_async_with_pipes()
377// uses @argv[0] as the file to execute, and passes all of @argv to the child.
378//
379// @child_setup and @user_data are a function and user data. On POSIX
380// platforms, the function is called in the child after GLib has
381// performed all the setup it plans to perform (including creating
382// pipes, closing file descriptors, etc.) but before calling `exec()`.
383// That is, @child_setup is called just before calling `exec()` in the
384// child. Obviously actions taken in this function will only affect
385// the child, not the parent.
386//
387// On Windows, there is no separate `fork()` and `exec()` functionality.
388// Child processes are created and run with a single API call,
389// `CreateProcess()`. There is no sensible thing @child_setup
390// could be used for on Windows so it is ignored and not called.
391//
392// If non-%NULL, @child_pid will on Unix be filled with the child's
393// process ID. You can use the process ID to send signals to the child,
394// or to use g_child_watch_add() (or `waitpid()`) if you specified the
395// %G_SPAWN_DO_NOT_REAP_CHILD flag. On Windows, @child_pid will be
396// filled with a handle to the child process only if you specified the
397// %G_SPAWN_DO_NOT_REAP_CHILD flag. You can then access the child
398// process using the Win32 API, for example wait for its termination
399// with the `WaitFor*()` functions, or examine its exit code with
400// `GetExitCodeProcess()`. You should close the handle with `CloseHandle()`
401// or g_spawn_close_pid() when you no longer need it.
402//
403// If non-%NULL, the @stdin_pipe_out, @stdout_pipe_out, @stderr_pipe_out
404// locations will be filled with file descriptors for writing to the child's
405// standard input or reading from its standard output or standard error.
406// The caller of g_spawn_async_with_pipes() must close these file descriptors
407// when they are no longer in use. If these parameters are %NULL, the
408// corresponding pipe won't be created.
409//
410// If @stdin_pipe_out is %NULL, the child's standard input is attached to
411// `/dev/null` unless %G_SPAWN_CHILD_INHERITS_STDIN is set.
412//
413// If @stderr_pipe_out is NULL, the child's standard error goes to the same
414// location as the parent's standard error unless %G_SPAWN_STDERR_TO_DEV_NULL
415// is set.
416//
417// If @stdout_pipe_out is NULL, the child's standard output goes to the same
418// location as the parent's standard output unless %G_SPAWN_STDOUT_TO_DEV_NULL
419// is set.
420//
421// @error can be %NULL to ignore errors, or non-%NULL to report errors.
422// If an error is set, the function returns %FALSE. Errors are reported
423// even if they occur in the child (for example if the executable in
424// `@argv[0]` is not found). Typically the `message` field of returned
425// errors should be displayed to users. Possible errors are those from
426// the %G_SPAWN_ERROR domain.
427//
428// If an error occurs, @child_pid, @stdin_pipe_out, @stdout_pipe_out,
429// and @stderr_pipe_out will not be filled with valid values.
430//
431// If @child_pid is not %NULL and an error does not occur then the returned
432// process reference must be closed using g_spawn_close_pid().
433//
434// On modern UNIX platforms, GLib can use an efficient process launching
435// codepath driven internally by `posix_spawn()`. This has the advantage of
436// avoiding the fork-time performance costs of cloning the parent process
437// address space, and avoiding associated memory overcommit checks that are
438// not relevant in the context of immediately executing a distinct process.
439// This optimized codepath will be used provided that the following conditions
440// are met:
441//
442// 1. %G_SPAWN_DO_NOT_REAP_CHILD is set
443// 2. %G_SPAWN_LEAVE_DESCRIPTORS_OPEN is set
444// 3. %G_SPAWN_SEARCH_PATH_FROM_ENVP is not set
445// 4. @working_directory is %NULL
446// 5. @child_setup is %NULL
447// 6. The program is of a recognised binary format, or has a shebang.
448// Otherwise, GLib will have to execute the program through the
449// shell, which is not done using the optimized codepath.
450//
451// If you are writing a GTK application, and the program you are spawning is a
452// graphical application too, then to ensure that the spawned program opens its
453// windows on the right screen, you may want to use #GdkAppLaunchContext,
454// #GAppLaunchContext, or set the `DISPLAY` environment variable.
455func SpawnAsyncWithPipesAndFds(WorkingDirectoryVar *string, ArgvVar []string, EnvpVar []string, FlagsVar SpawnFlags, ChildSetupVar *SpawnChildSetupFunc, UserDataVar uintptr, StdinFdVar int, StdoutFdVar int, StderrFdVar int, SourceFdsVar []int, TargetFdsVar []int, NFdsVar uint, ChildPidOutVar *Pid, StdinPipeOutVar *int, StdoutPipeOutVar *int, StderrPipeOutVar *int) (bool, error) {
456 var cerr *Error
457
458 var ChildSetupVarRef uintptr
459 if ChildSetupVar != nil {
460 ChildSetupVarPtr := uintptr(unsafe.Pointer(ChildSetupVar))
461 if cbRefPtr, ok := GetCallback(ChildSetupVarPtr); ok {
462 ChildSetupVarRef = cbRefPtr
463 } else {
464 fcb := func(arg0 uintptr) {
465 cbFn := *ChildSetupVar
466 cbFn(arg0)
467 }
468 ChildSetupVarRef = purego.NewCallback(fcb)
469 SaveCallbackWithClosure(ChildSetupVarPtr, ChildSetupVarRef, ChildSetupVar)
470 }
471 }
472
473 WorkingDirectoryVarPtr := core.GStrdupNullable(WorkingDirectoryVar)
474 defer core.GFreeNullable(WorkingDirectoryVarPtr)
475
476 cret := xSpawnAsyncWithPipesAndFds(WorkingDirectoryVarPtr, ArgvVar, EnvpVar, FlagsVar, ChildSetupVarRef, UserDataVar, StdinFdVar, StdoutFdVar, StderrFdVar, SourceFdsVar, TargetFdsVar, NFdsVar, ChildPidOutVar, StdinPipeOutVar, StdoutPipeOutVar, StderrPipeOutVar, &cerr)
477
478 if cerr == nil {
479 return cret, nil
480 }
481 return cret, cerr
482
483}
484
485var xSpawnCheckExitStatus func(int, **Error) bool
486
487// An old name for g_spawn_check_wait_status(), deprecated because its
488// name is misleading.
489//
490// Despite the name of the function, @wait_status must be the wait status
491// as returned by g_spawn_sync(), g_subprocess_get_status(), `waitpid()`,
492// etc. On Unix platforms, it is incorrect for it to be the exit status
493// as passed to `exit()` or returned by g_subprocess_get_exit_status() or
494// `WEXITSTATUS()`.
495func SpawnCheckExitStatus(WaitStatusVar int) (bool, error) {
496 var cerr *Error
497
498 cret := xSpawnCheckExitStatus(WaitStatusVar, &cerr)
499
500 if cerr == nil {
501 return cret, nil
502 }
503 return cret, cerr
504
505}
506
507var xSpawnCheckWaitStatus func(int, **Error) bool
508
509// Set @error if @wait_status indicates the child exited abnormally
510// (e.g. with a nonzero exit code, or via a fatal signal).
511//
512// The g_spawn_sync() and g_child_watch_add() family of APIs return the
513// status of subprocesses encoded in a platform-specific way.
514// On Unix, this is guaranteed to be in the same format waitpid() returns,
515// and on Windows it is guaranteed to be the result of GetExitCodeProcess().
516//
517// Prior to the introduction of this function in GLib 2.34, interpreting
518// @wait_status required use of platform-specific APIs, which is problematic
519// for software using GLib as a cross-platform layer.
520//
521// Additionally, many programs simply want to determine whether or not
522// the child exited successfully, and either propagate a #GError or
523// print a message to standard error. In that common case, this function
524// can be used. Note that the error message in @error will contain
525// human-readable information about the wait status.
526//
527// The @domain and @code of @error have special semantics in the case
528// where the process has an "exit code", as opposed to being killed by
529// a signal. On Unix, this happens if WIFEXITED() would be true of
530// @wait_status. On Windows, it is always the case.
531//
532// The special semantics are that the actual exit code will be the
533// code set in @error, and the domain will be %G_SPAWN_EXIT_ERROR.
534// This allows you to differentiate between different exit codes.
535//
536// If the process was terminated by some means other than an exit
537// status (for example if it was killed by a signal), the domain will be
538// %G_SPAWN_ERROR and the code will be %G_SPAWN_ERROR_FAILED.
539//
540// This function just offers convenience; you can of course also check
541// the available platform via a macro such as %G_OS_UNIX, and use
542// WIFEXITED() and WEXITSTATUS() on @wait_status directly. Do not attempt
543// to scan or parse the error message string; it may be translated and/or
544// change in future versions of GLib.
545//
546// Prior to version 2.70, g_spawn_check_exit_status() provides the same
547// functionality, although under a misleading name.
548func SpawnCheckWaitStatus(WaitStatusVar int) (bool, error) {
549 var cerr *Error
550
551 cret := xSpawnCheckWaitStatus(WaitStatusVar, &cerr)
552
553 if cerr == nil {
554 return cret, nil
555 }
556 return cret, cerr
557
558}
559
560var xSpawnClosePid func(Pid)
561
562// On some platforms, notably Windows, the #GPid type represents a resource
563// which must be closed to prevent resource leaking. g_spawn_close_pid()
564// is provided for this purpose. It should be used on all platforms, even
565// though it doesn't do anything under UNIX.
566func SpawnClosePid(PidVar Pid) {
567
568 xSpawnClosePid(PidVar)
569
570}
571
572var xSpawnCommandLineAsync func(string, **Error) bool
573
574// A simple version of g_spawn_async() that parses a command line with
575// g_shell_parse_argv() and passes it to g_spawn_async().
576//
577// Runs a command line in the background. Unlike g_spawn_async(), the
578// %G_SPAWN_SEARCH_PATH flag is enabled, other flags are not. Note
579// that %G_SPAWN_SEARCH_PATH can have security implications, so
580// consider using g_spawn_async() directly if appropriate. Possible
581// errors are those from g_shell_parse_argv() and g_spawn_async().
582//
583// The same concerns on Windows apply as for g_spawn_command_line_sync().
584func SpawnCommandLineAsync(CommandLineVar string) (bool, error) {
585 var cerr *Error
586
587 cret := xSpawnCommandLineAsync(CommandLineVar, &cerr)
588
589 if cerr == nil {
590 return cret, nil
591 }
592 return cret, cerr
593
594}
595
596var xSpawnCommandLineSync func(string, *[]byte, *[]byte, *int, **Error) bool
597
598// A simple version of g_spawn_sync() with little-used parameters
599// removed, taking a command line instead of an argument vector.
600//
601// See g_spawn_sync() for full details.
602//
603// The @command_line argument will be parsed by g_shell_parse_argv().
604//
605// Unlike g_spawn_sync(), the %G_SPAWN_SEARCH_PATH flag is enabled.
606// Note that %G_SPAWN_SEARCH_PATH can have security implications, so
607// consider using g_spawn_sync() directly if appropriate.
608//
609// Possible errors are those from g_spawn_sync() and those
610// from g_shell_parse_argv().
611//
612// If @wait_status is non-%NULL, the platform-specific status of
613// the child is stored there; see the documentation of
614// g_spawn_check_wait_status() for how to use and interpret this.
615// On Unix platforms, note that it is usually not equal
616// to the integer passed to `exit()` or returned from `main()`.
617//
618// On Windows, please note the implications of g_shell_parse_argv()
619// parsing @command_line. Parsing is done according to Unix shell rules, not
620// Windows command interpreter rules.
621// Space is a separator, and backslashes are
622// special. Thus you cannot simply pass a @command_line containing
623// canonical Windows paths, like "c:\\program files\\app\\app.exe", as
624// the backslashes will be eaten, and the space will act as a
625// separator. You need to enclose such paths with single quotes, like
626// "'c:\\program files\\app\\app.exe' 'e:\\folder\\argument.txt'".
627func SpawnCommandLineSync(CommandLineVar string, StandardOutputVar *[]byte, StandardErrorVar *[]byte, WaitStatusVar *int) (bool, error) {
628 var cerr *Error
629
630 cret := xSpawnCommandLineSync(CommandLineVar, StandardOutputVar, StandardErrorVar, WaitStatusVar, &cerr)
631
632 if cerr == nil {
633 return cret, nil
634 }
635 return cret, cerr
636
637}
638
639var xSpawnSync func(uintptr, []string, []string, SpawnFlags, uintptr, uintptr, *[]byte, *[]byte, *int, **Error) bool
640
641// Executes a child synchronously (waits for the child to exit before returning).
642//
643// All output from the child is stored in @standard_output and @standard_error,
644// if those parameters are non-%NULL. Note that you must set the
645// %G_SPAWN_STDOUT_TO_DEV_NULL and %G_SPAWN_STDERR_TO_DEV_NULL flags when
646// passing %NULL for @standard_output and @standard_error.
647//
648// If @wait_status is non-%NULL, the platform-specific status of
649// the child is stored there; see the documentation of
650// g_spawn_check_wait_status() for how to use and interpret this.
651// On Unix platforms, note that it is usually not equal
652// to the integer passed to `exit()` or returned from `main()`.
653//
654// Note that it is invalid to pass %G_SPAWN_DO_NOT_REAP_CHILD in
655// @flags, and on POSIX platforms, the same restrictions as for
656// g_child_watch_source_new() apply.
657//
658// If an error occurs, no data is returned in @standard_output,
659// @standard_error, or @wait_status.
660//
661// This function calls g_spawn_async_with_pipes() internally; see that
662// function for full details on the other parameters and details on
663// how these functions work on Windows.
664func SpawnSync(WorkingDirectoryVar *string, ArgvVar []string, EnvpVar []string, FlagsVar SpawnFlags, ChildSetupVar *SpawnChildSetupFunc, UserDataVar uintptr, StandardOutputVar *[]byte, StandardErrorVar *[]byte, WaitStatusVar *int) (bool, error) {
665 var cerr *Error
666
667 var ChildSetupVarRef uintptr
668 if ChildSetupVar != nil {
669 ChildSetupVarPtr := uintptr(unsafe.Pointer(ChildSetupVar))
670 if cbRefPtr, ok := GetCallback(ChildSetupVarPtr); ok {
671 ChildSetupVarRef = cbRefPtr
672 } else {
673 fcb := func(arg0 uintptr) {
674 cbFn := *ChildSetupVar
675 cbFn(arg0)
676 }
677 ChildSetupVarRef = purego.NewCallback(fcb)
678 SaveCallbackWithClosure(ChildSetupVarPtr, ChildSetupVarRef, ChildSetupVar)
679 }
680 }
681
682 WorkingDirectoryVarPtr := core.GStrdupNullable(WorkingDirectoryVar)
683 defer core.GFreeNullable(WorkingDirectoryVarPtr)
684
685 cret := xSpawnSync(WorkingDirectoryVarPtr, ArgvVar, EnvpVar, FlagsVar, ChildSetupVarRef, UserDataVar, StandardOutputVar, StandardErrorVar, WaitStatusVar, &cerr)
686
687 if cerr == nil {
688 return cret, nil
689 }
690 return cret, cerr
691
692}
693
694func init() {
695 core.SetPackageName("GLIB", "glib-2.0")
696 core.SetSharedLibraries("GLIB", []string{"libgobject-2.0.so.0", "libglib-2.0.so.0"})
697 var libs []uintptr
698 for _, libPath := range core.GetPaths("GLIB") {
699 lib, err := purego.Dlopen(libPath, purego.RTLD_NOW|purego.RTLD_GLOBAL)
700 if err != nil {
701 panic(err)
702 }
703 libs = append(libs, lib)
704 }
705
706 core.PuregoSafeRegister(&xSpawnAsync, libs, "g_spawn_async")
707 core.PuregoSafeRegister(&xSpawnAsyncWithFds, libs, "g_spawn_async_with_fds")
708 core.PuregoSafeRegister(&xSpawnAsyncWithPipes, libs, "g_spawn_async_with_pipes")
709 core.PuregoSafeRegister(&xSpawnAsyncWithPipesAndFds, libs, "g_spawn_async_with_pipes_and_fds")
710 core.PuregoSafeRegister(&xSpawnCheckExitStatus, libs, "g_spawn_check_exit_status")
711 core.PuregoSafeRegister(&xSpawnCheckWaitStatus, libs, "g_spawn_check_wait_status")
712 core.PuregoSafeRegister(&xSpawnClosePid, libs, "g_spawn_close_pid")
713 core.PuregoSafeRegister(&xSpawnCommandLineAsync, libs, "g_spawn_command_line_async")
714 core.PuregoSafeRegister(&xSpawnCommandLineSync, libs, "g_spawn_command_line_sync")
715 core.PuregoSafeRegister(&xSpawnSync, libs, "g_spawn_sync")
716
717}