source: appstream-generator/build/girepo/glib/Spawn.d @ 4841

Last change on this file since 4841 was 4841, checked in by Juanma, 2 years ago

Initial release

File size: 16.1 KB
Line 
1/*
2 * Licensed under the GNU Lesser General Public License Version 3
3 *
4 * This library is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation, either version 3 of the license, or
7 * (at your option) any later version.
8 *
9 * This software is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18// generated automatically - do not change
19
20
21module glib.Spawn;
22
23private import core.stdc.stdio;
24private import core.stdc.string;
25private import core.thread;
26private import gi.glib;
27public  import gi.glibtypes;
28private import glib.ErrorG;
29private import glib.GException;
30private import glib.Str;
31private import std.string;
32
33
34/** */
35public class Spawn
36{
37        //we need fdopen.
38        version(Posix)
39        {
40                private import core.sys.posix.stdio;
41        }
42        //fdopen for Windows is defined in gi.glibtypes.
43       
44        string workingDirectory = ".";
45        string[] argv;
46        string[] envp;
47        GSpawnFlags flags = SpawnFlags.SEARCH_PATH;
48        GSpawnChildSetupFunc childSetup;
49        void* userData;
50        GPid childPid;
51        FILE* standardInput;
52        FILE* standardOutput;
53        FILE* standardError;
54        GError* error;
55        int stdIn;
56        int stdOut;
57        int stdErr;
58       
59        // for commandLineSync
60        int exitStatus;
61        char* strOutput;
62        char* strError;
63       
64        alias bool delegate(Spawn) ChildWatch;
65        ChildWatch externalWatch;
66       
67        /**
68         * Creates a Spawn for execution.
69         */
70        public this(string program, string[] envp=null)
71        {
72                argv ~= program;
73                this.envp = envp;
74        }
75       
76        /**
77         * Creates a Spawn for execution.
78         */
79        public this(string[] program, string[] envp=null)
80        {
81                argv = program;
82                this.envp = envp;
83        }
84       
85        /**
86         * Adds a delegate to be notified on the end of the child process.
87         * Params:
88         *      dlg =
89         */
90        public void addChildWatch(ChildWatch dlg)
91        {
92                externalWatch = dlg;
93        }
94       
95        /**
96         * Closes all open streams and child process.
97         */
98        public void close()
99        {
100                if (stdIn != 0 )
101                {
102                        fclose(standardInput);
103                        stdIn = 0;
104                }
105                if (stdOut != 0 )
106                {
107                        fclose(standardOutput);
108                        stdOut = 0;
109                }
110                if (stdErr != 0 )
111                {
112                        fclose(standardError);
113                        stdErr = 0;
114                }
115                if ( childPid != 0 )
116                {
117                        closePid(childPid);
118                        childPid = 0;
119                }
120        }
121       
122        /**
123         * Adds a parameter to the execution program
124         */
125        public void addParm(string parm)
126        {
127                argv ~= parm;
128        }
129       
130        /**
131         * Gets the last error message
132         */
133        public string getLastError()
134        {
135                if ( error != null )
136                {
137                        return Str.toString(error.message);
138                }
139                return "";
140        }
141       
142        /**
143         * Executes the prepared process
144         */
145        public int execAsyncWithPipes(
146                ChildWatch externalWatch = null,
147                bool delegate(string) readOutput = null,
148        bool delegate(string) readError = null )
149        {
150                int result = g_spawn_async_with_pipes(
151                        Str.toStringz(workingDirectory),
152                        Str.toStringzArray(argv),
153                        Str.toStringzArray(envp),
154                        flags,
155                        childSetup,
156                        userData,
157                        &childPid,
158                        &stdIn,
159                        &stdOut,
160                        &stdErr,
161                        &error
162                );
163               
164                if ( result != 0 )
165                {
166                        this.externalWatch = externalWatch;
167                        g_child_watch_add(childPid, cast(GChildWatchFunc)(&childWatchCallback), cast(void*)this);
168                        standardInput = fdopen(stdIn, Str.toStringz("w"));
169                        standardOutput = fdopen(stdOut, Str.toStringz("r"));
170                        standardError = fdopen(stdErr, Str.toStringz("r"));
171                       
172                        if ( readOutput !is null )
173                        {
174                                (new ReadFile(standardOutput, readOutput)).start();
175                        }
176                        if ( readError !is null )
177                        {
178                                (new ReadFile(standardError, readError)).start();
179                        }
180                }
181               
182                return result;
183        }
184       
185        class ReadFile : Thread
186        {
187                bool delegate(string) read;
188                FILE* file;
189               
190                int lineCount;
191               
192                this(FILE* file, bool delegate (string) read )
193                {
194                        this.file = file;
195                        this.read = read;
196                       
197                        super(&run);
198                }
199               
200                public void run()
201                {
202                        string line = readLine(file);
203                        while( line !is null )
204                        {
205                                ++lineCount;
206                                if ( read !is null )
207                                {
208                                        read(line);
209                                }
210                                line = readLine(file);
211                        }
212                }
213        }
214       
215        private string readLine(FILE* stream, int max=4096)
216        {
217                if ( feof(stream) )
218                {
219                        if ( externalWatch !is null )
220                        {
221                                externalWatch(this);
222                        }
223                        return null;
224                }
225                string line;
226                line.length = max+1;
227                char* lineP = fgets(Str.toStringz(line), max, stream);
228                if ( lineP is null )
229                {
230                        return "";
231                }
232                size_t l = strlen(line.ptr);
233                if ( l > 0 ) --l;
234               
235                return line[0..l];
236        }
237       
238        extern(C) static void childWatchCallback(int pid, int status, Spawn spawn)
239        {
240                //writefln("Spawn.childWatchCallback %s %s", pid, status);
241                spawn.exitStatus = status;
242                if ( spawn.externalWatch !is null )
243                {
244                        spawn.externalWatch(spawn);
245                }
246                spawn.close();
247        }
248       
249       
250        public bool endOfOutput()
251        {
252                if ( standardOutput is null ) return true;
253                return feof(standardOutput) != 0;
254        }
255       
256        public bool endOfError()
257        {
258                if ( standardError is null ) return true;
259                return feof(standardError) != 0;
260        }
261       
262        string getOutputString()
263        {
264                return Str.toString(strOutput);
265        }
266       
267        string getErrorString()
268        {
269                return Str.toString(strError);
270        }
271       
272        int getExitStatus()
273        {
274                return exitStatus;
275        }
276       
277        /**
278         * Executes a command synchronasly and
279         * optionally calls delegates for sysout, syserr and end of job
280         *
281         */
282        public int commandLineSync(
283                ChildWatch externalWatch = null,
284                bool delegate(string) readOutput = null,
285        bool delegate(string) readError = null )
286        {
287                string commandLine;
288                foreach ( int count, string arg; argv)
289                {
290                        if ( count > 0 )
291                        {
292                                commandLine ~= ' ';
293                        }
294                        commandLine ~= arg;
295                }
296                int status = g_spawn_command_line_sync(
297                        Str.toStringz(commandLine),
298                        &strOutput,
299                        &strError,
300                        &exitStatus,
301                        &error);
302                if ( readOutput != null )
303                {
304                        foreach ( string line ; splitLines(Str.toString(strOutput)) )
305                        {
306                                readOutput(line);
307                        }
308                }
309                if ( readError != null )
310                {
311                        foreach ( string line ; splitLines(Str.toString(strError)) )
312                        {
313                                readError(line);
314                        }
315                }
316                if ( externalWatch != null )
317                {
318                        externalWatch(this);
319                }
320                return status;
321        }
322
323        /**
324         */
325
326        /**
327         * See g_spawn_async_with_pipes() for a full description; this function
328         * simply calls the g_spawn_async_with_pipes() without any pipes.
329         *
330         * You should call g_spawn_close_pid() on the returned child process
331         * reference when you don't need it any more.
332         *
333         * If you are writing a GTK+ application, and the program you are
334         * spawning is a graphical application, too, then you may want to
335         * use gdk_spawn_on_screen() instead to ensure that the spawned program
336         * opens its windows on the right screen.
337         *
338         * Note that the returned @child_pid on Windows is a handle to the child
339         * process and not its identifier. Process handles and process identifiers
340         * are different concepts on Windows.
341         *
342         * Params:
343         *     workingDirectory = child's current working directory, or %NULL to inherit parent's
344         *     argv = child's argument vector
345         *     envp = child's environment, or %NULL to inherit parent's
346         *     flags = flags from #GSpawnFlags
347         *     childSetup = function to run in the child just before exec()
348         *     userData = user data for @child_setup
349         *     childPid = return location for child process reference, or %NULL
350         *
351         * Returns: %TRUE on success, %FALSE if error is set
352         *
353         * Throws: GException on failure.
354         */
355        public static bool async(string workingDirectory, string[] argv, string[] envp, GSpawnFlags flags, GSpawnChildSetupFunc childSetup, void* userData, out GPid childPid)
356        {
357                GError* err = null;
358               
359                auto p = g_spawn_async(Str.toStringz(workingDirectory), Str.toStringzArray(argv), Str.toStringzArray(envp), flags, childSetup, userData, &childPid, &err) != 0;
360               
361                if (err !is null)
362                {
363                        throw new GException( new ErrorG(err) );
364                }
365               
366                return p;
367        }
368
369        /**
370         * Set @error if @exit_status indicates the child exited abnormally
371         * (e.g. with a nonzero exit code, or via a fatal signal).
372         *
373         * The g_spawn_sync() and g_child_watch_add() family of APIs return an
374         * exit status for subprocesses encoded in a platform-specific way.
375         * On Unix, this is guaranteed to be in the same format waitpid() returns,
376         * and on Windows it is guaranteed to be the result of GetExitCodeProcess().
377         *
378         * Prior to the introduction of this function in GLib 2.34, interpreting
379         * @exit_status required use of platform-specific APIs, which is problematic
380         * for software using GLib as a cross-platform layer.
381         *
382         * Additionally, many programs simply want to determine whether or not
383         * the child exited successfully, and either propagate a #GError or
384         * print a message to standard error. In that common case, this function
385         * can be used. Note that the error message in @error will contain
386         * human-readable information about the exit status.
387         *
388         * The @domain and @code of @error have special semantics in the case
389         * where the process has an "exit code", as opposed to being killed by
390         * a signal. On Unix, this happens if WIFEXITED() would be true of
391         * @exit_status. On Windows, it is always the case.
392         *
393         * The special semantics are that the actual exit code will be the
394         * code set in @error, and the domain will be %G_SPAWN_EXIT_ERROR.
395         * This allows you to differentiate between different exit codes.
396         *
397         * If the process was terminated by some means other than an exit
398         * status, the domain will be %G_SPAWN_ERROR, and the code will be
399         * %G_SPAWN_ERROR_FAILED.
400         *
401         * This function just offers convenience; you can of course also check
402         * the available platform via a macro such as %G_OS_UNIX, and use
403         * WIFEXITED() and WEXITSTATUS() on @exit_status directly. Do not attempt
404         * to scan or parse the error message string; it may be translated and/or
405         * change in future versions of GLib.
406         *
407         * Params:
408         *     exitStatus = An exit code as returned from g_spawn_sync()
409         *
410         * Returns: %TRUE if child exited successfully, %FALSE otherwise (and
411         *     @error will be set)
412         *
413         * Since: 2.34
414         *
415         * Throws: GException on failure.
416         */
417        public static bool checkExitStatus(int exitStatus)
418        {
419                GError* err = null;
420               
421                auto p = g_spawn_check_exit_status(exitStatus, &err) != 0;
422               
423                if (err !is null)
424                {
425                        throw new GException( new ErrorG(err) );
426                }
427               
428                return p;
429        }
430
431        /**
432         * On some platforms, notably Windows, the #GPid type represents a resource
433         * which must be closed to prevent resource leaking. g_spawn_close_pid()
434         * is provided for this purpose. It should be used on all platforms, even
435         * though it doesn't do anything under UNIX.
436         *
437         * Params:
438         *     pid = The process reference to close
439         */
440        public static void closePid(GPid pid)
441        {
442                g_spawn_close_pid(pid);
443        }
444
445        /**
446         * A simple version of g_spawn_async() that parses a command line with
447         * g_shell_parse_argv() and passes it to g_spawn_async(). Runs a
448         * command line in the background. Unlike g_spawn_async(), the
449         * %G_SPAWN_SEARCH_PATH flag is enabled, other flags are not. Note
450         * that %G_SPAWN_SEARCH_PATH can have security implications, so
451         * consider using g_spawn_async() directly if appropriate. Possible
452         * errors are those from g_shell_parse_argv() and g_spawn_async().
453         *
454         * The same concerns on Windows apply as for g_spawn_command_line_sync().
455         *
456         * Params:
457         *     commandLine = a command line
458         *
459         * Returns: %TRUE on success, %FALSE if error is set
460         *
461         * Throws: GException on failure.
462         */
463        public static bool commandLineAsync(string commandLine)
464        {
465                GError* err = null;
466               
467                auto p = g_spawn_command_line_async(Str.toStringz(commandLine), &err) != 0;
468               
469                if (err !is null)
470                {
471                        throw new GException( new ErrorG(err) );
472                }
473               
474                return p;
475        }
476
477        /**
478         * A simple version of g_spawn_sync() with little-used parameters
479         * removed, taking a command line instead of an argument vector.  See
480         * g_spawn_sync() for full details. @command_line will be parsed by
481         * g_shell_parse_argv(). Unlike g_spawn_sync(), the %G_SPAWN_SEARCH_PATH flag
482         * is enabled. Note that %G_SPAWN_SEARCH_PATH can have security
483         * implications, so consider using g_spawn_sync() directly if
484         * appropriate. Possible errors are those from g_spawn_sync() and those
485         * from g_shell_parse_argv().
486         *
487         * If @exit_status is non-%NULL, the platform-specific exit status of
488         * the child is stored there; see the documentation of
489         * g_spawn_check_exit_status() for how to use and interpret this.
490         *
491         * On Windows, please note the implications of g_shell_parse_argv()
492         * parsing @command_line. Parsing is done according to Unix shell rules, not
493         * Windows command interpreter rules.
494         * Space is a separator, and backslashes are
495         * special. Thus you cannot simply pass a @command_line containing
496         * canonical Windows paths, like "c:\\program files\\app\\app.exe", as
497         * the backslashes will be eaten, and the space will act as a
498         * separator. You need to enclose such paths with single quotes, like
499         * "'c:\\program files\\app\\app.exe' 'e:\\folder\\argument.txt'".
500         *
501         * Params:
502         *     commandLine = a command line
503         *     standardOutput = return location for child output
504         *     standardError = return location for child errors
505         *     exitStatus = return location for child exit status, as returned by waitpid()
506         *
507         * Returns: %TRUE on success, %FALSE if an error was set
508         *
509         * Throws: GException on failure.
510         */
511        public static bool commandLineSync(string commandLine, out string standardOutput, out string standardError, out int exitStatus)
512        {
513                char* outstandardOutput = null;
514                char* outstandardError = null;
515                GError* err = null;
516               
517                auto p = g_spawn_command_line_sync(Str.toStringz(commandLine), &outstandardOutput, &outstandardError, &exitStatus, &err) != 0;
518               
519                if (err !is null)
520                {
521                        throw new GException( new ErrorG(err) );
522                }
523               
524                standardOutput = Str.toString(outstandardOutput);
525                standardError = Str.toString(outstandardError);
526               
527                return p;
528        }
529
530        /** */
531        public static GQuark errorQuark()
532        {
533                return g_spawn_error_quark();
534        }
535
536        /** */
537        public static GQuark exitErrorQuark()
538        {
539                return g_spawn_exit_error_quark();
540        }
541
542        /**
543         * Executes a child synchronously (waits for the child to exit before returning).
544         * All output from the child is stored in @standard_output and @standard_error,
545         * if those parameters are non-%NULL. Note that you must set the
546         * %G_SPAWN_STDOUT_TO_DEV_NULL and %G_SPAWN_STDERR_TO_DEV_NULL flags when
547         * passing %NULL for @standard_output and @standard_error.
548         *
549         * If @exit_status is non-%NULL, the platform-specific exit status of
550         * the child is stored there; see the documentation of
551         * g_spawn_check_exit_status() for how to use and interpret this.
552         * Note that it is invalid to pass %G_SPAWN_DO_NOT_REAP_CHILD in
553         * @flags.
554         *
555         * If an error occurs, no data is returned in @standard_output,
556         * @standard_error, or @exit_status.
557         *
558         * This function calls g_spawn_async_with_pipes() internally; see that
559         * function for full details on the other parameters and details on
560         * how these functions work on Windows.
561         *
562         * Params:
563         *     workingDirectory = child's current working directory, or %NULL to inherit parent's
564         *     argv = child's argument vector
565         *     envp = child's environment, or %NULL to inherit parent's
566         *     flags = flags from #GSpawnFlags
567         *     childSetup = function to run in the child just before exec()
568         *     userData = user data for @child_setup
569         *     standardOutput = return location for child output, or %NULL
570         *     standardError = return location for child error messages, or %NULL
571         *     exitStatus = return location for child exit status, as returned by waitpid(), or %NULL
572         *
573         * Returns: %TRUE on success, %FALSE if an error was set
574         *
575         * Throws: GException on failure.
576         */
577        public static bool sync(string workingDirectory, string[] argv, string[] envp, GSpawnFlags flags, GSpawnChildSetupFunc childSetup, void* userData, out string standardOutput, out string standardError, out int exitStatus)
578        {
579                char* outstandardOutput = null;
580                char* outstandardError = null;
581                GError* err = null;
582               
583                auto p = g_spawn_sync(Str.toStringz(workingDirectory), Str.toStringzArray(argv), Str.toStringzArray(envp), flags, childSetup, userData, &outstandardOutput, &outstandardError, &exitStatus, &err) != 0;
584               
585                if (err !is null)
586                {
587                        throw new GException( new ErrorG(err) );
588                }
589               
590                standardOutput = Str.toString(outstandardOutput);
591                standardError = Str.toString(outstandardError);
592               
593                return p;
594        }
595}
Note: See TracBrowser for help on using the repository browser.