diff options
author | NIIBE Yutaka <[email protected]> | 2024-05-29 06:14:44 +0000 |
---|---|---|
committer | NIIBE Yutaka <[email protected]> | 2024-05-29 06:16:56 +0000 |
commit | 6c05b35977c9d15da45b4fe6c0c870dbbf51657c (patch) | |
tree | eeff919dfe06900b6f8f62b3cf45153ed2d6ab88 /src/spawn-w32.c | |
parent | Import spawn functions from GnuPG master. (diff) | |
download | libgpg-error-6c05b35977c9d15da45b4fe6c0c870dbbf51657c.tar.gz libgpg-error-6c05b35977c9d15da45b4fe6c0c870dbbf51657c.zip |
Cleaner semantics for _gpgrt_process_spawn without a callback.
* src/gpg-error.h.in (@define:struct_spawn_cb_arg@): Remove.
(gpgrt_spawn_actions_t): New.
(@define:spawn_actions_functions@): New.
* src/gpgrt-int.h (_gpgrt_spawn_actions_new)
(_gpgrt_spawn_actions_release, _gpgrt_spawn_actions_set_envvars)
(_gpgrt_spawn_actions_set_redirect): New.
[HAVE_W32_SYSTEM] (_gpgrt_spawn_actions_set_inherit_handles): New.
[!HAVE_W32_SYSTEM] (_gpgrt_spawn_actions_set_inherit_fds)
(_gpgrt_spawn_actions_set_atfork): New.
(_gpgrt_process_spawn): Use gpgrt_spawn_actions_t.
(_gpgrt_spawn_helper): Remove.
* src/mkheader.c: Emit gpgrt_spawn_actions_* definition.
* src/spawn-posix.c(_gpgrt_spawn_actions_new)
(_gpgrt_spawn_actions_release, _gpgrt_spawn_actions_set_envvars)
(_gpgrt_spawn_actions_set_redirect)
(_gpgrt_spawn_actions_set_inherit_fds)
(_gpgrt_spawn_actions_set_atfork): New.
(spawn_detached, _gpgrt_process_spawn): Use gpgrt_spawn_actions_t.
(_gpgrt_spawn_helper): Remove.
* src/spawn-w32.c: Ditto, with
_gpgrt_spawn_actions_set_inherit_handles, but no
_gpgrt_spawn_actions_set_atfork.
--
GnuPG-bug-id: 6249
Signed-off-by: NIIBE Yutaka <[email protected]>
Diffstat (limited to 'src/spawn-w32.c')
-rw-r--r-- | src/spawn-w32.c | 144 |
1 files changed, 98 insertions, 46 deletions
diff --git a/src/spawn-w32.c b/src/spawn-w32.c index b2eb760..72d5552 100644 --- a/src/spawn-w32.c +++ b/src/spawn-w32.c @@ -301,6 +301,11 @@ _gpgrt_make_pipe (int filedes[2], estream_t *r_fp, int direction, int nonblock) return do_create_pipe_and_estream (filedes, NULL, 0, 0); } +struct gpgrt_spawn_actions { + void *hd[3]; + void **inherit_hds; + char **env; +}; struct gpgrt_process { const char *pgmname; @@ -338,8 +343,7 @@ check_windows_version (void) static gpg_err_code_t -spawn_detached (const char *pgmname, char *cmdline, - void (*spawn_cb) (struct spawn_cb_arg *), void *spawn_cb_arg) +spawn_detached (const char *pgmname, char *cmdline, gpgrt_spawn_actions_t act) { SECURITY_ATTRIBUTES sec_attr; PROCESS_INFORMATION pi = { NULL, 0, 0, 0 }; @@ -349,8 +353,8 @@ spawn_detached (const char *pgmname, char *cmdline, wchar_t *wpgmname = NULL; gpg_err_code_t ec; int ret; - struct spawn_cb_arg sca; BOOL ask_inherit = FALSE; + int i; ec = _gpgrt_access (pgmname, X_OK); if (ec) @@ -361,22 +365,27 @@ spawn_detached (const char *pgmname, char *cmdline, memset (&si, 0, sizeof si); - sca.allow_foreground_window = FALSE; - sca.hd[0] = INVALID_HANDLE_VALUE; - sca.hd[1] = INVALID_HANDLE_VALUE; - sca.hd[2] = INVALID_HANDLE_VALUE; - sca.inherit_hds = NULL; - sca.arg = spawn_cb_arg; - if (spawn_cb) - (*spawn_cb) (&sca); + i = 0; + if (act->hd[0] != INVALID_HANDLE_VALUE) + i++; + if (act->hd[1] != INVALID_HANDLE_VALUE) + i++; + if (act->hd[2] != INVALID_HANDLE_VALUE) + i++; - if (sca.inherit_hds) + if (i != 0 || act->inherit_hds) { SIZE_T attr_list_size = 0; HANDLE hd[16]; - HANDLE *hd_p = sca.inherit_hds; + HANDLE *hd_p = act->inherit_hds; int j = 0; + if (act->hd[0] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[0]; + if (act->hd[1] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[1]; + if (act->hd[1] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[2]; if (hd_p) { while (*hd_p != INVALID_HANDLE_VALUE) @@ -406,7 +415,6 @@ spawn_detached (const char *pgmname, char *cmdline, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, hd, sizeof (HANDLE) * j, NULL, NULL); } - ask_inherit = TRUE; } } @@ -418,8 +426,12 @@ spawn_detached (const char *pgmname, char *cmdline, /* Start the process. */ si.StartupInfo.cb = sizeof (si); - si.StartupInfo.dwFlags = STARTF_USESHOWWINDOW; + si.StartupInfo.dwFlags = ((i > 0 ? STARTF_USESTDHANDLES : 0) + | STARTF_USESHOWWINDOW); si.StartupInfo.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE; + si.StartupInfo.hStdInput = act->hd[0]; + si.StartupInfo.hStdOutput = act->hd[1]; + si.StartupInfo.hStdError = act->hd[2]; cr_flags = (CREATE_DEFAULT_ERROR_MODE | GetPriorityClass (GetCurrentProcess ()) @@ -476,18 +488,60 @@ spawn_detached (const char *pgmname, char *cmdline, } +gpg_err_code_t +_gpgrt_spawn_actions_new (gpgrt_spawn_actions_t *r_act) +{ + gpgrt_spawn_actions_t act; + int i; + + *r_act = NULL; + + act = xtrycalloc (1, sizeof (struct gpgrt_spawn_actions)); + if (act == NULL) + return _gpg_err_code_from_syserror (); + + for (i = 0; i <= 2; i++) + act->hd[i] = INVALID_HANDLE_VALUE; + + *r_act = act; + return 0; +} + +void +_gpgrt_spawn_actions_release (gpgrt_spawn_actions_t act) +{ + if (!act) + return; + + xfree (act); +} + +void +_gpgrt_spawn_actions_set_envvars (gpgrt_spawn_actions_t act, char **env) +{ + act->env = env; +} + +void +_gpgrt_spawn_actions_set_redirect (gpgrt_spawn_actions_t act, + void *in, void *out, void *err) +{ + act->hd[0] = in; + act->hd[1] = out; + act->hd[2] = err; +} + void -_gpgrt_spawn_helper (struct spawn_cb_arg *sca) +_gpgrt_spawn_actions_set_inherit_handles (gpgrt_spawn_actions_t act, + void **handles) { - HANDLE *user_except = sca->arg; - sca->inherit_hds = user_except; + act->inherit_hds = handles; } + gpg_err_code_t _gpgrt_process_spawn (const char *pgmname, const char *argv[], - unsigned int flags, - void (*spawn_cb) (struct spawn_cb_arg *), - void *spawn_cb_arg, + unsigned int flags, gpgrt_spawn_actions_t act, gpgrt_process_t *r_process) { gpg_err_code_t ec; @@ -503,9 +557,9 @@ _gpgrt_process_spawn (const char *pgmname, const char *argv[], HANDLE hd_in[2]; HANDLE hd_out[2]; HANDLE hd_err[2]; - struct spawn_cb_arg sca; int i; BOOL ask_inherit = FALSE; + BOOL allow_foreground_window = FALSE; /* Build the command line. */ ec = build_w32_commandline (pgmname, argv, &cmdline); @@ -527,7 +581,7 @@ _gpgrt_process_spawn (const char *pgmname, const char *argv[], return GPG_ERR_INV_ARG; } - return spawn_detached (pgmname, cmdline, spawn_cb, spawn_cb_arg); + return spawn_detached (pgmname, cmdline, act); } if (r_process) @@ -627,36 +681,34 @@ _gpgrt_process_spawn (const char *pgmname, const char *argv[], memset (&si, 0, sizeof si); - sca.allow_foreground_window = FALSE; - sca.hd[0] = hd_in[0]; - sca.hd[1] = hd_out[1]; - sca.hd[2] = hd_err[1]; - sca.inherit_hds = NULL; - sca.arg = spawn_cb_arg; - if (spawn_cb) - (*spawn_cb) (&sca); + if (act->hd[0] == INVALID_HANDLE_VALUE) + act->hd[0] = hd_in[0]; + if (act->hd[1] == INVALID_HANDLE_VALUE) + act->hd[1] = hd_out[1]; + if (act->hd[2] == INVALID_HANDLE_VALUE) + act->hd[2] = hd_err[1]; i = 0; - if (sca.hd[0] != INVALID_HANDLE_VALUE) + if (act->hd[0] != INVALID_HANDLE_VALUE) i++; - if (sca.hd[1] != INVALID_HANDLE_VALUE) + if (act->hd[1] != INVALID_HANDLE_VALUE) i++; - if (sca.hd[2] != INVALID_HANDLE_VALUE) + if (act->hd[2] != INVALID_HANDLE_VALUE) i++; - if (i != 0 || sca.inherit_hds) + if (i != 0 || act->inherit_hds) { SIZE_T attr_list_size = 0; HANDLE hd[16]; - HANDLE *hd_p = sca.inherit_hds; + HANDLE *hd_p = act->inherit_hds; int j = 0; - if (sca.hd[0] != INVALID_HANDLE_VALUE) - hd[j++] = sca.hd[0]; - if (sca.hd[1] != INVALID_HANDLE_VALUE) - hd[j++] = sca.hd[1]; - if (sca.hd[1] != INVALID_HANDLE_VALUE) - hd[j++] = sca.hd[2]; + if (act->hd[0] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[0]; + if (act->hd[1] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[1]; + if (act->hd[1] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[2]; if (hd_p) { while (*hd_p != INVALID_HANDLE_VALUE) @@ -715,9 +767,9 @@ _gpgrt_process_spawn (const char *pgmname, const char *argv[], si.StartupInfo.cb = sizeof (si); si.StartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.StartupInfo.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_HIDE; - si.StartupInfo.hStdInput = sca.hd[0]; - si.StartupInfo.hStdOutput = sca.hd[1]; - si.StartupInfo.hStdError = sca.hd[2]; + si.StartupInfo.hStdInput = act->hd[0]; + si.StartupInfo.hStdOutput = act->hd[1]; + si.StartupInfo.hStdError = act->hd[2]; /* log_debug ("CreateProcess, path='%s' cmdline='%s'\n", pgmname, cmdline); */ cr_flags = (CREATE_DEFAULT_ERROR_MODE @@ -790,7 +842,7 @@ _gpgrt_process_spawn (const char *pgmname, const char *argv[], /* pi.hProcess, pi.hThread, */ /* (int) pi.dwProcessId, (int) pi.dwThreadId); */ - if (sca.allow_foreground_window) + if (allow_foreground_window) { /* Fixme: For unknown reasons AllowSetForegroundWindow returns * an invalid argument error if we pass it the correct |