[PATCH 0/1] MR10926: ntdll,msv1_0: Add fallback paths for systems without posix_spawn().
This adds fallback implementations for posix_spawn() usage in ntdll and msv1_0. Older Android versions do not provide posix_spawn() or posix_spawnp(). The affected code paths only need simple helper process startup and only distinguish success from failure, so this keeps the existing posix_spawn() implementation where available and uses vfork() with execv()/execvp() otherwise. The ntdll loader path preserves the existing execv-style behavior for a fully built path. The msv1_0 ntlm_auth path preserves the posix_spawnp-style PATH lookup by using execvp() in the fallback. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10926
From: Twaik Yont <9674930+twaik@users.noreply.github.com> Some platforms do not provide posix_spawn() and posix_spawnp(). Use vfork() with execv()/execvp() as a local fallback for the helper process startup paths that only need to distinguish a successful exec from a failed launch. Keep using posix_spawn() where available. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- configure | 6 +++++ configure.ac | 1 + dlls/msv1_0/unixlib.c | 51 ++++++++++++++++++++++++++++++++++++---- dlls/ntdll/unix/loader.c | 23 ++++++++++++++++-- include/config.h.in | 3 +++ 5 files changed, 77 insertions(+), 7 deletions(-) diff --git a/configure b/configure index fda5e60e415..118009ca227 100755 --- a/configure +++ b/configure @@ -21980,6 +21980,12 @@ if test "x$ac_cv_func_posix_fallocate" = xyes then : printf "%s\n" "#define HAVE_POSIX_FALLOCATE 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "posix_spawn" "ac_cv_func_posix_spawn" +if test "x$ac_cv_func_posix_spawn" = xyes +then : + printf "%s\n" "#define HAVE_POSIX_SPAWN 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "prctl" "ac_cv_func_prctl" if test "x$ac_cv_func_prctl" = xyes diff --git a/configure.ac b/configure.ac index 485a1370b06..3cfb61a1adb 100644 --- a/configure.ac +++ b/configure.ac @@ -2119,6 +2119,7 @@ AC_CHECK_FUNCS(\ port_create \ posix_fadvise \ posix_fallocate \ + posix_spawn \ prctl \ process_vm_readv \ process_vm_writev \ diff --git a/dlls/msv1_0/unixlib.c b/dlls/msv1_0/unixlib.c index e9c2088da9e..880a4aeb8bd 100644 --- a/dlls/msv1_0/unixlib.c +++ b/dlls/msv1_0/unixlib.c @@ -28,7 +28,6 @@ #include <unistd.h> #include <fcntl.h> #include <errno.h> -#include <spawn.h> #include <sys/wait.h> #include "ntstatus.h" #include "windef.h" @@ -36,6 +35,10 @@ #include "winbase.h" #include "sspi.h" +#ifdef HAVE_POSIX_SPAWN +#include <spawn.h> +#endif + #include "wine/debug.h" #include "unixlib.h" @@ -161,9 +164,12 @@ static NTSTATUS ntlm_fork( void *args ) { const struct fork_params *params = args; struct ntlm_ctx *ctx = params->ctx; - posix_spawn_file_actions_t file_actions; - int pipe_in[2], pipe_out[2], err; + int pipe_in[2], pipe_out[2]; NTSTATUS status = STATUS_SUCCESS; +#ifdef HAVE_POSIX_SPAWN + int err; + posix_spawn_file_actions_t file_actions; +#endif #ifdef HAVE_PIPE2 if (pipe2( pipe_in, O_CLOEXEC ) < 0) @@ -187,6 +193,7 @@ static NTSTATUS ntlm_fork( void *args ) fcntl( pipe_out[1], F_SETFD, FD_CLOEXEC ); } +#ifdef HAVE_POSIX_SPAWN posix_spawn_file_actions_init( &file_actions ); posix_spawn_file_actions_adddup2( &file_actions, pipe_out[0], 0 ); @@ -207,13 +214,47 @@ static NTSTATUS ntlm_fork( void *args ) status = STATUS_UNSUCCESSFUL; } + posix_spawn_file_actions_destroy( &file_actions ); +#else + { + volatile int failed = 0; + pid_t child = vfork(); + + if (!child) + { + if (dup2( pipe_out[0], 0 ) == -1 || dup2( pipe_in[1], 1 ) == -1) + { + failed = 1; + _exit(127); + } + + close( pipe_out[0] ); + close( pipe_out[1] ); + close( pipe_in[0] ); + close( pipe_in[1] ); + + execvp( params->argv[0], params->argv ); + failed = 1; + _exit(127); + } + + if (child == -1 || failed) + { + ctx->pid = -1; + write( pipe_in[1], "BH\n", 3 ); + ERR_(winediag)( "Can't start ntlm_auth. " + "Usually you can find it in the winbind package of your distribution.\n" ); + status = STATUS_UNSUCCESSFUL; + } + else ctx->pid = child; + } +#endif + ctx->pipe_in = pipe_in[0]; close( pipe_in[1] ); ctx->pipe_out = pipe_out[1]; close( pipe_out[0] ); - posix_spawn_file_actions_destroy( &file_actions ); - return status; } diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index c1e6b588dcb..491cdfce586 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -30,7 +30,6 @@ #include <stdarg.h> #include <stdio.h> #include <signal.h> -#include <spawn.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> @@ -39,6 +38,9 @@ #include <sys/wait.h> #include <unistd.h> #include <dlfcn.h> +#ifdef HAVE_POSIX_SPAWN +#include <spawn.h> +#endif #ifdef HAVE_PWD_H # include <pwd.h> #endif @@ -249,10 +251,27 @@ static char *build_relative_path( const char *base, const char *from, const char /* build a path to a binary and exec it */ static int build_path_and_exec( pid_t *pid, const char *dir, const char *name, char **argv ) { - int ret; + int ret = 0; argv[0] = build_path( dir, name ); +#ifdef HAVE_POSIX_SPAWN ret = posix_spawn( pid, argv[0], NULL, NULL, argv, environ ); +#else + { + volatile int failed = 0; + pid_t child = vfork(); + + if (!child) + { + execv( argv[0], argv ); + failed = 1; + _exit(127); + } + + ret = child == -1 || failed ? 127 : 0; + if (!ret) *pid = child; + } +#endif free( argv[0] ); return ret; } diff --git a/include/config.h.in b/include/config.h.in index 551771eaa6a..82d08d53b5f 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -336,6 +336,9 @@ /* Define to 1 if you have the 'posix_fallocate' function. */ #undef HAVE_POSIX_FALLOCATE +/* Define to 1 if you have the 'posix_spawn' function. */ +#undef HAVE_POSIX_SPAWN + /* Define to 1 if you have the 'prctl' function. */ #undef HAVE_PRCTL -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10926
ntlm_auth is unlikely to be available on Android and NTLM is used sporadically so I'm inclined to disable it and see if any demand turns up. You should split the commits: one per dll. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10926#note_140269
participants (3)
-
Hans Leidekker (@hans) -
Twaik Yont -
Twaik Yont (@twaik)