SDL_process.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. /*
  2. Simple DirectMedia Layer
  3. Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any damages
  6. arising from the use of this software.
  7. Permission is granted to anyone to use this software for any purpose,
  8. including commercial applications, and to alter it and redistribute it
  9. freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you must not
  11. claim that you wrote the original software. If you use this software
  12. in a product, an acknowledgment in the product documentation would be
  13. appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and must not be
  15. misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. /**
  19. * # CategoryProcess
  20. *
  21. * Process control support.
  22. *
  23. * These functions provide a cross-platform way to spawn and manage OS-level
  24. * processes.
  25. *
  26. * You can create a new subprocess with SDL_CreateProcess() and optionally
  27. * read and write to it using SDL_ReadProcess() or SDL_GetProcessInput() and
  28. * SDL_GetProcessOutput(). If more advanced functionality like chaining input
  29. * between processes is necessary, you can use
  30. * SDL_CreateProcessWithProperties().
  31. *
  32. * You can get the status of a created process with SDL_WaitProcess(), or
  33. * terminate the process with SDL_KillProcess().
  34. *
  35. * Don't forget to call SDL_DestroyProcess() to clean up, whether the process
  36. * process was killed, terminated on its own, or is still running!
  37. */
  38. #ifndef SDL_process_h_
  39. #define SDL_process_h_
  40. #include <SDL3/SDL_stdinc.h>
  41. #include <SDL3/SDL_error.h>
  42. #include <SDL3/SDL_iostream.h>
  43. #include <SDL3/SDL_properties.h>
  44. #include <SDL3/SDL_begin_code.h>
  45. /* Set up for C function definitions, even when using C++ */
  46. #ifdef __cplusplus
  47. extern "C" {
  48. #endif
  49. /**
  50. * An opaque handle representing a system process.
  51. *
  52. * \since This datatype is available since SDL 3.2.0.
  53. *
  54. * \sa SDL_CreateProcess
  55. */
  56. typedef struct SDL_Process SDL_Process;
  57. /**
  58. * Create a new process.
  59. *
  60. * The path to the executable is supplied in args[0]. args[1..N] are
  61. * additional arguments passed on the command line of the new process, and the
  62. * argument list should be terminated with a NULL, e.g.:
  63. *
  64. * ```c
  65. * const char *args[] = { "myprogram", "argument", NULL };
  66. * ```
  67. *
  68. * Setting pipe_stdio to true is equivalent to setting
  69. * `SDL_PROP_PROCESS_CREATE_STDIN_NUMBER` and
  70. * `SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER` to `SDL_PROCESS_STDIO_APP`, and
  71. * will allow the use of SDL_ReadProcess() or SDL_GetProcessInput() and
  72. * SDL_GetProcessOutput().
  73. *
  74. * See SDL_CreateProcessWithProperties() for more details.
  75. *
  76. * \param args the path and arguments for the new process.
  77. * \param pipe_stdio true to create pipes to the process's standard input and
  78. * from the process's standard output, false for the process
  79. * to have no input and inherit the application's standard
  80. * output.
  81. * \returns the newly created and running process, or NULL if the process
  82. * couldn't be created.
  83. *
  84. * \threadsafety It is safe to call this function from any thread.
  85. *
  86. * \since This function is available since SDL 3.2.0.
  87. *
  88. * \sa SDL_CreateProcessWithProperties
  89. * \sa SDL_GetProcessProperties
  90. * \sa SDL_ReadProcess
  91. * \sa SDL_GetProcessInput
  92. * \sa SDL_GetProcessOutput
  93. * \sa SDL_KillProcess
  94. * \sa SDL_WaitProcess
  95. * \sa SDL_DestroyProcess
  96. */
  97. extern SDL_DECLSPEC SDL_Process * SDLCALL SDL_CreateProcess(const char * const *args, bool pipe_stdio);
  98. /**
  99. * Description of where standard I/O should be directed when creating a
  100. * process.
  101. *
  102. * If a standard I/O stream is set to SDL_PROCESS_STDIO_INHERITED, it will go
  103. * to the same place as the application's I/O stream. This is the default for
  104. * standard output and standard error.
  105. *
  106. * If a standard I/O stream is set to SDL_PROCESS_STDIO_NULL, it is connected
  107. * to `NUL:` on Windows and `/dev/null` on POSIX systems. This is the default
  108. * for standard input.
  109. *
  110. * If a standard I/O stream is set to SDL_PROCESS_STDIO_APP, it is connected
  111. * to a new SDL_IOStream that is available to the application. Standard input
  112. * will be available as `SDL_PROP_PROCESS_STDIN_POINTER` and allows
  113. * SDL_GetProcessInput(), standard output will be available as
  114. * `SDL_PROP_PROCESS_STDOUT_POINTER` and allows SDL_ReadProcess() and
  115. * SDL_GetProcessOutput(), and standard error will be available as
  116. * `SDL_PROP_PROCESS_STDERR_POINTER` in the properties for the created
  117. * process.
  118. *
  119. * If a standard I/O stream is set to SDL_PROCESS_STDIO_REDIRECT, it is
  120. * connected to an existing SDL_IOStream provided by the application. Standard
  121. * input is provided using `SDL_PROP_PROCESS_CREATE_STDIN_POINTER`, standard
  122. * output is provided using `SDL_PROP_PROCESS_CREATE_STDOUT_POINTER`, and
  123. * standard error is provided using `SDL_PROP_PROCESS_CREATE_STDERR_POINTER`
  124. * in the creation properties. These existing streams should be closed by the
  125. * application once the new process is created.
  126. *
  127. * In order to use an SDL_IOStream with SDL_PROCESS_STDIO_REDIRECT, it must
  128. * have `SDL_PROP_IOSTREAM_WINDOWS_HANDLE_POINTER` or
  129. * `SDL_PROP_IOSTREAM_FILE_DESCRIPTOR_NUMBER` set. This is true for streams
  130. * representing files and process I/O.
  131. *
  132. * \since This enum is available since SDL 3.2.0.
  133. *
  134. * \sa SDL_CreateProcessWithProperties
  135. * \sa SDL_GetProcessProperties
  136. * \sa SDL_ReadProcess
  137. * \sa SDL_GetProcessInput
  138. * \sa SDL_GetProcessOutput
  139. */
  140. typedef enum SDL_ProcessIO
  141. {
  142. SDL_PROCESS_STDIO_INHERITED, /**< The I/O stream is inherited from the application. */
  143. SDL_PROCESS_STDIO_NULL, /**< The I/O stream is ignored. */
  144. SDL_PROCESS_STDIO_APP, /**< The I/O stream is connected to a new SDL_IOStream that the application can read or write */
  145. SDL_PROCESS_STDIO_REDIRECT /**< The I/O stream is redirected to an existing SDL_IOStream. */
  146. } SDL_ProcessIO;
  147. /**
  148. * Create a new process with the specified properties.
  149. *
  150. * These are the supported properties:
  151. *
  152. * - `SDL_PROP_PROCESS_CREATE_ARGS_POINTER`: an array of strings containing
  153. * the program to run, any arguments, and a NULL pointer, e.g. const char
  154. * *args[] = { "myprogram", "argument", NULL }. This is a required property.
  155. * - `SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER`: an SDL_Environment
  156. * pointer. If this property is set, it will be the entire environment for
  157. * the process, otherwise the current environment is used.
  158. * - `SDL_PROP_PROCESS_CREATE_WORKING_DIRECTORY_STRING`: a UTF-8 encoded
  159. * string representing the working directory for the process, defaults to
  160. * the current working directory.
  161. * - `SDL_PROP_PROCESS_CREATE_STDIN_NUMBER`: an SDL_ProcessIO value describing
  162. * where standard input for the process comes from, defaults to
  163. * `SDL_PROCESS_STDIO_NULL`.
  164. * - `SDL_PROP_PROCESS_CREATE_STDIN_POINTER`: an SDL_IOStream pointer used for
  165. * standard input when `SDL_PROP_PROCESS_CREATE_STDIN_NUMBER` is set to
  166. * `SDL_PROCESS_STDIO_REDIRECT`.
  167. * - `SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER`: an SDL_ProcessIO value
  168. * describing where standard output for the process goes to, defaults to
  169. * `SDL_PROCESS_STDIO_INHERITED`.
  170. * - `SDL_PROP_PROCESS_CREATE_STDOUT_POINTER`: an SDL_IOStream pointer used
  171. * for standard output when `SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER` is set
  172. * to `SDL_PROCESS_STDIO_REDIRECT`.
  173. * - `SDL_PROP_PROCESS_CREATE_STDERR_NUMBER`: an SDL_ProcessIO value
  174. * describing where standard error for the process goes to, defaults to
  175. * `SDL_PROCESS_STDIO_INHERITED`.
  176. * - `SDL_PROP_PROCESS_CREATE_STDERR_POINTER`: an SDL_IOStream pointer used
  177. * for standard error when `SDL_PROP_PROCESS_CREATE_STDERR_NUMBER` is set to
  178. * `SDL_PROCESS_STDIO_REDIRECT`.
  179. * - `SDL_PROP_PROCESS_CREATE_STDERR_TO_STDOUT_BOOLEAN`: true if the error
  180. * output of the process should be redirected into the standard output of
  181. * the process. This property has no effect if
  182. * `SDL_PROP_PROCESS_CREATE_STDERR_NUMBER` is set.
  183. * - `SDL_PROP_PROCESS_CREATE_BACKGROUND_BOOLEAN`: true if the process should
  184. * run in the background. In this case the default input and output is
  185. * `SDL_PROCESS_STDIO_NULL` and the exitcode of the process is not
  186. * available, and will always be 0. This is not required to launch a program
  187. * asynchronously, this is for detaching a child process from its parent
  188. * completely (a so-called "double fork" on Unix). Created processes run
  189. * asynchronously by default, regardless of this property.
  190. * - `SDL_PROP_PROCESS_CREATE_CMDLINE_STRING`: a string containing the program
  191. * to run and any parameters. This string is passed directly to
  192. * `CreateProcess` on Windows, and does nothing on other platforms. This
  193. * property is only important if you want to start programs that does
  194. * non-standard command-line processing, and in most cases using
  195. * `SDL_PROP_PROCESS_CREATE_ARGS_POINTER` is sufficient.
  196. *
  197. * On POSIX platforms, wait() and waitpid(-1, ...) should not be called, and
  198. * SIGCHLD should not be ignored or handled because those would prevent SDL
  199. * from properly tracking the lifetime of the underlying process. You should
  200. * use SDL_WaitProcess() instead.
  201. *
  202. * \param props the properties to use.
  203. * \returns the newly created and running process, or NULL if the process
  204. * couldn't be created.
  205. *
  206. * \threadsafety It is safe to call this function from any thread.
  207. *
  208. * \since This function is available since SDL 3.2.0.
  209. *
  210. * \sa SDL_CreateProcess
  211. * \sa SDL_GetProcessProperties
  212. * \sa SDL_ReadProcess
  213. * \sa SDL_GetProcessInput
  214. * \sa SDL_GetProcessOutput
  215. * \sa SDL_KillProcess
  216. * \sa SDL_WaitProcess
  217. * \sa SDL_DestroyProcess
  218. */
  219. extern SDL_DECLSPEC SDL_Process * SDLCALL SDL_CreateProcessWithProperties(SDL_PropertiesID props);
  220. #define SDL_PROP_PROCESS_CREATE_ARGS_POINTER "SDL.process.create.args"
  221. #define SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER "SDL.process.create.environment"
  222. #define SDL_PROP_PROCESS_CREATE_WORKING_DIRECTORY_STRING "SDL.process.create.working_directory"
  223. #define SDL_PROP_PROCESS_CREATE_STDIN_NUMBER "SDL.process.create.stdin_option"
  224. #define SDL_PROP_PROCESS_CREATE_STDIN_POINTER "SDL.process.create.stdin_source"
  225. #define SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER "SDL.process.create.stdout_option"
  226. #define SDL_PROP_PROCESS_CREATE_STDOUT_POINTER "SDL.process.create.stdout_source"
  227. #define SDL_PROP_PROCESS_CREATE_STDERR_NUMBER "SDL.process.create.stderr_option"
  228. #define SDL_PROP_PROCESS_CREATE_STDERR_POINTER "SDL.process.create.stderr_source"
  229. #define SDL_PROP_PROCESS_CREATE_STDERR_TO_STDOUT_BOOLEAN "SDL.process.create.stderr_to_stdout"
  230. #define SDL_PROP_PROCESS_CREATE_BACKGROUND_BOOLEAN "SDL.process.create.background"
  231. #define SDL_PROP_PROCESS_CREATE_CMDLINE_STRING "SDL.process.create.cmdline"
  232. /**
  233. * Get the properties associated with a process.
  234. *
  235. * The following read-only properties are provided by SDL:
  236. *
  237. * - `SDL_PROP_PROCESS_PID_NUMBER`: the process ID of the process.
  238. * - `SDL_PROP_PROCESS_STDIN_POINTER`: an SDL_IOStream that can be used to
  239. * write input to the process, if it was created with
  240. * `SDL_PROP_PROCESS_CREATE_STDIN_NUMBER` set to `SDL_PROCESS_STDIO_APP`.
  241. * - `SDL_PROP_PROCESS_STDOUT_POINTER`: a non-blocking SDL_IOStream that can
  242. * be used to read output from the process, if it was created with
  243. * `SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER` set to `SDL_PROCESS_STDIO_APP`.
  244. * - `SDL_PROP_PROCESS_STDERR_POINTER`: a non-blocking SDL_IOStream that can
  245. * be used to read error output from the process, if it was created with
  246. * `SDL_PROP_PROCESS_CREATE_STDERR_NUMBER` set to `SDL_PROCESS_STDIO_APP`.
  247. * - `SDL_PROP_PROCESS_BACKGROUND_BOOLEAN`: true if the process is running in
  248. * the background.
  249. *
  250. * \param process the process to query.
  251. * \returns a valid property ID on success or 0 on failure; call
  252. * SDL_GetError() for more information.
  253. *
  254. * \threadsafety It is safe to call this function from any thread.
  255. *
  256. * \since This function is available since SDL 3.2.0.
  257. *
  258. * \sa SDL_CreateProcess
  259. * \sa SDL_CreateProcessWithProperties
  260. */
  261. extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetProcessProperties(SDL_Process *process);
  262. #define SDL_PROP_PROCESS_PID_NUMBER "SDL.process.pid"
  263. #define SDL_PROP_PROCESS_STDIN_POINTER "SDL.process.stdin"
  264. #define SDL_PROP_PROCESS_STDOUT_POINTER "SDL.process.stdout"
  265. #define SDL_PROP_PROCESS_STDERR_POINTER "SDL.process.stderr"
  266. #define SDL_PROP_PROCESS_BACKGROUND_BOOLEAN "SDL.process.background"
  267. /**
  268. * Read all the output from a process.
  269. *
  270. * If a process was created with I/O enabled, you can use this function to
  271. * read the output. This function blocks until the process is complete,
  272. * capturing all output, and providing the process exit code.
  273. *
  274. * The data is allocated with a zero byte at the end (null terminated) for
  275. * convenience. This extra byte is not included in the value reported via
  276. * `datasize`.
  277. *
  278. * The data should be freed with SDL_free().
  279. *
  280. * \param process The process to read.
  281. * \param datasize a pointer filled in with the number of bytes read, may be
  282. * NULL.
  283. * \param exitcode a pointer filled in with the process exit code if the
  284. * process has exited, may be NULL.
  285. * \returns the data or NULL on failure; call SDL_GetError() for more
  286. * information.
  287. *
  288. * \threadsafety This function is not thread safe.
  289. *
  290. * \since This function is available since SDL 3.2.0.
  291. *
  292. * \sa SDL_CreateProcess
  293. * \sa SDL_CreateProcessWithProperties
  294. * \sa SDL_DestroyProcess
  295. */
  296. extern SDL_DECLSPEC void * SDLCALL SDL_ReadProcess(SDL_Process *process, size_t *datasize, int *exitcode);
  297. /**
  298. * Get the SDL_IOStream associated with process standard input.
  299. *
  300. * The process must have been created with SDL_CreateProcess() and pipe_stdio
  301. * set to true, or with SDL_CreateProcessWithProperties() and
  302. * `SDL_PROP_PROCESS_CREATE_STDIN_NUMBER` set to `SDL_PROCESS_STDIO_APP`.
  303. *
  304. * Writing to this stream can return less data than expected if the process
  305. * hasn't read its input. It may be blocked waiting for its output to be read,
  306. * if so you may need to call SDL_GetProcessOutput() and read the output in
  307. * parallel with writing input.
  308. *
  309. * \param process The process to get the input stream for.
  310. * \returns the input stream or NULL on failure; call SDL_GetError() for more
  311. * information.
  312. *
  313. * \threadsafety It is safe to call this function from any thread.
  314. *
  315. * \since This function is available since SDL 3.2.0.
  316. *
  317. * \sa SDL_CreateProcess
  318. * \sa SDL_CreateProcessWithProperties
  319. * \sa SDL_GetProcessOutput
  320. */
  321. extern SDL_DECLSPEC SDL_IOStream * SDLCALL SDL_GetProcessInput(SDL_Process *process);
  322. /**
  323. * Get the SDL_IOStream associated with process standard output.
  324. *
  325. * The process must have been created with SDL_CreateProcess() and pipe_stdio
  326. * set to true, or with SDL_CreateProcessWithProperties() and
  327. * `SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER` set to `SDL_PROCESS_STDIO_APP`.
  328. *
  329. * Reading from this stream can return 0 with SDL_GetIOStatus() returning
  330. * SDL_IO_STATUS_NOT_READY if no output is available yet.
  331. *
  332. * \param process The process to get the output stream for.
  333. * \returns the output stream or NULL on failure; call SDL_GetError() for more
  334. * information.
  335. *
  336. * \threadsafety It is safe to call this function from any thread.
  337. *
  338. * \since This function is available since SDL 3.2.0.
  339. *
  340. * \sa SDL_CreateProcess
  341. * \sa SDL_CreateProcessWithProperties
  342. * \sa SDL_GetProcessInput
  343. */
  344. extern SDL_DECLSPEC SDL_IOStream * SDLCALL SDL_GetProcessOutput(SDL_Process *process);
  345. /**
  346. * Stop a process.
  347. *
  348. * \param process The process to stop.
  349. * \param force true to terminate the process immediately, false to try to
  350. * stop the process gracefully. In general you should try to stop
  351. * the process gracefully first as terminating a process may
  352. * leave it with half-written data or in some other unstable
  353. * state.
  354. * \returns true on success or false on failure; call SDL_GetError() for more
  355. * information.
  356. *
  357. * \threadsafety This function is not thread safe.
  358. *
  359. * \since This function is available since SDL 3.2.0.
  360. *
  361. * \sa SDL_CreateProcess
  362. * \sa SDL_CreateProcessWithProperties
  363. * \sa SDL_WaitProcess
  364. * \sa SDL_DestroyProcess
  365. */
  366. extern SDL_DECLSPEC bool SDLCALL SDL_KillProcess(SDL_Process *process, bool force);
  367. /**
  368. * Wait for a process to finish.
  369. *
  370. * This can be called multiple times to get the status of a process.
  371. *
  372. * The exit code will be the exit code of the process if it terminates
  373. * normally, a negative signal if it terminated due to a signal, or -255
  374. * otherwise. It will not be changed if the process is still running.
  375. *
  376. * If you create a process with standard output piped to the application
  377. * (`pipe_stdio` being true) then you should read all of the process output
  378. * before calling SDL_WaitProcess(). If you don't do this the process might be
  379. * blocked indefinitely waiting for output to be read and SDL_WaitProcess()
  380. * will never return true;
  381. *
  382. * \param process The process to wait for.
  383. * \param block If true, block until the process finishes; otherwise, report
  384. * on the process' status.
  385. * \param exitcode a pointer filled in with the process exit code if the
  386. * process has exited, may be NULL.
  387. * \returns true if the process exited, false otherwise.
  388. *
  389. * \threadsafety This function is not thread safe.
  390. *
  391. * \since This function is available since SDL 3.2.0.
  392. *
  393. * \sa SDL_CreateProcess
  394. * \sa SDL_CreateProcessWithProperties
  395. * \sa SDL_KillProcess
  396. * \sa SDL_DestroyProcess
  397. */
  398. extern SDL_DECLSPEC bool SDLCALL SDL_WaitProcess(SDL_Process *process, bool block, int *exitcode);
  399. /**
  400. * Destroy a previously created process object.
  401. *
  402. * Note that this does not stop the process, just destroys the SDL object used
  403. * to track it. If you want to stop the process you should use
  404. * SDL_KillProcess().
  405. *
  406. * \param process The process object to destroy.
  407. *
  408. * \threadsafety This function is not thread safe.
  409. *
  410. * \since This function is available since SDL 3.2.0.
  411. *
  412. * \sa SDL_CreateProcess
  413. * \sa SDL_CreateProcessWithProperties
  414. * \sa SDL_KillProcess
  415. */
  416. extern SDL_DECLSPEC void SDLCALL SDL_DestroyProcess(SDL_Process *process);
  417. /* Ends C function definitions when using C++ */
  418. #ifdef __cplusplus
  419. }
  420. #endif
  421. #include <SDL3/SDL_close_code.h>
  422. #endif /* SDL_process_h_ */