Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork105
🐜 single header process launching solution for C and C++
License
sheredom/subprocess.h
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
A simple one header solution to launching processes and interacting with themfor C/C++.
Just#include "subprocess.h" in your code!
The current supported platforms are Linux, macOS and Windows.
The current supported compilers are gcc, clang, MSVC's cl.exe, and clang-cl.exe.
Subprocess is a single header cross-platform library that allows users to launchsub-processes, interact with the stdin, stdout, and stderr of the process, andwait for them to complete.
To launch a process you callsubprocess_create like so:
constchar*command_line[]= {"echo","\"Hello, world!\"",NULL};structsubprocess_ssubprocess;intresult=subprocess_create(command_line,0,&subprocess);if (0!=result) {// an error occurred!}
You specify an array of string for the command line - terminating the array withaNULL element.
If the process is created successfully then 0 is returned fromsubprocess_create.
To write to the standard input of a child process you callsubprocess_stdin toget the FILE handle to write with, passing a previously created process, likeso:
FILE*p_stdin=subprocess_stdin(&process);fputs("Hello, world!",p_stdin);
Care must be taken to not write to the stdin after any call tosubprocess_joinorsubprocess_destroy.
To read from the standard output of a child process you callsubprocess_stdoutto get the FILE handle to read with, passing a previously created process, likeso:
FILE*p_stdout=subprocess_stdout(&process);charhello_world[32];fgets(hello_world,32,p_stdout);
Care must be taken to not read from the stdout after any call tosubprocess_destroy.
To read from the standard error of a child process you callsubprocess_stderrto get the FILE handle to read with, passing a previously created process, likeso:
FILE*p_stderr=subprocess_stderr(&process);charhello_world[32];fgets(hello_world,32,p_stderr);
Care must be taken to not read from the stderr after any call tosubprocess_destroy.
To wait for a previously created process to finish executing you callsubprocess_join like so:
intprocess_return;intresult=subprocess_join(&process,&process_return);if (0!=result) {// an error occurred!}
The return code of the child process is returned in the second argument (storedintoprocess_return in the example above). This parameter can beNULL if youdon't care about the process' return code.
If the child process encounters an unhandled exception, the return code will alwaysbe filled with anon zero value.
To destroy a previously created process you callsubprocess_destroy like so:
intresult=subprocess_destroy(&process);if (0!=result) {// an error occurred!}
Note that you can destroy a process before it has completed execution - thisallows you to spawn a process that wouldoutlive the execution of the parentprocess for instance.
To terminate a (possibly hung) previously created process you callsubprocess_terminate like so:
intresult=subprocess_terminate(&process);if (0!=result) {// an error occurred!}
Note that you still can callsubprocess_destroy, andsubprocess_join aftercallingsubprocess_terminate, and that the return code filled bysubprocess_join(&process, &process_return) is then guaranteed to benon zero.
If you want to be able to read from a processbefore callingsubprocess_joinon it, you cannot usesubprocess_stdout orsubprocess_stderr because thevarious operating systems that this library supports do not allow for this.
Instead you first have to callsubprocess_create and specify thesubprocess_option_enable_async option - which enables asynchronous reading.
Then you must use thesubprocess_read_stdout andsubprocess_read_stderrhelper functions to do any reading from either pipe. Note that these callsmayblock if there isn't any data ready to be read.
Thesubprocess_create_ex entry-point contains an additional argumentenvironment. This argument is an array ofFOO=BAR pairs terminating in aNULL entry:
constchar*command_line[]= {"echo","\"Hello, world!\"",NULL};constchar*environment[]= {"FOO=BAR","HAZ=BAZ",NULL};structsubprocess_ssubprocess;intresult=subprocess_create_ex(command_line,0,environment,&subprocess);if (0!=result) {// an error occurred!}
This lets you specify custom environments for spawned subprocesses.
Note though that youcannot specifysubprocess_option_inherit_environmentwith a custom environment. If you want to merge some custom environment with theparent process environment then it is up to you as the user to query the originalparent variables you want to pass to the child, and specify them in the spawnedprocess'environment.
If theoptions argument ofsubprocess_create containssubprocess_option_no_window then, if the platform supports it, the processwill be launched with no visible window.
constchar*command_line[]= {"echo","\"Hello, world!\"",NULL};structsubprocess_ssubprocess;intresult=subprocess_create(command_line,subprocess_option_no_window,&subprocess);if (0!=result) {// an error occurred!}
This option isonly required on Windows platforms at present if the behaviouris seeked for.
subprocess_create is subtly different from Windows'CreateProcessA in thatwhen theenvironment is set toNULL, it'll launch the process with anempty environment. Users should use thesubprocess_option_inherit_environmentoption to inherit the parent's environment. This is done to ensure that thesafest defaults are used for launching processes.
If you spawn a process that needs internet access then you will have to use thesubprocess_option_inherit_environment option during creation. The subprocesshas to inherit the environment of the parent because the environment implicitlycontains the privileges of the parent process (accessing the internet) that thechild requires.
The current list of todos:
- Add the ability toset environment variables of the child processas suggested by@graphitemaster.
- Add the ability to specify if a child process should die if the parent processis terminated.
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, ordistribute this software, either in source code form or as a compiledbinary, for any purpose, commercial or non-commercial, and by anymeans.
In jurisdictions that recognize copyright laws, the author or authorsof this software dedicate any and all copyright interest in thesoftware to the public domain. We make this dedication for the benefitof the public at large and to the detriment of our heirs andsuccessors. We intend this dedication to be an overt act ofrelinquishment in perpetuity of all present and future rights to thissoftware under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OFMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OROTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OROTHER DEALINGS IN THE SOFTWARE.
For more information, please refer tohttp://unlicense.org/
About
🐜 single header process launching solution for C and C++
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Contributors14
Uh oh!
There was an error while loading.Please reload this page.