diff options
author | Ludovic Courtès <ludo@gnu.org> | 2023-01-18 18:25:25 +0100 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2023-01-18 22:50:18 +0100 |
commit | aeb22f486139f457ae7fc44c2d931312aaae52d8 (patch) | |
tree | 0fbfe6d421e637553f9bca39f08577c0ddb990e8 /lib/windows-spawn.c | |
parent | 4404b553a5a135aee5a606dedea9b6fa25363be4 (diff) | |
download | guile-aeb22f486139f457ae7fc44c2d931312aaae52d8.tar.gz |
Update Gnulib to v0.1-5703-g356a414e8c and add 'posix_spawn' module.
This is a followup to edfca3b7e5931b5b5a83112e2a9813b068be99c2, which
added the 'posix_spawnp' module but not 'posix_spawn'.
* m4/gnulib-cache.m4: Add 'posix_spawn' module.
* gnulib-local/m4/clock_time.m4.diff: Adjust.
* configure.ac: Move 'gl_EARLY' use right after 'AC_PROG_CC'.
Diffstat (limited to 'lib/windows-spawn.c')
-rw-r--r-- | lib/windows-spawn.c | 108 |
1 files changed, 60 insertions, 48 deletions
diff --git a/lib/windows-spawn.c b/lib/windows-spawn.c index a9212d485..f864db131 100644 --- a/lib/windows-spawn.c +++ b/lib/windows-spawn.c @@ -1,5 +1,5 @@ /* Auxiliary functions for the creation of subprocesses. Native Windows API. - Copyright (C) 2001, 2003-2022 Free Software Foundation, Inc. + Copyright (C) 2001, 2003-2023 Free Software Foundation, Inc. Written by Bruno Haible <bruno@clisp.org>, 2003. This file is free software: you can redistribute it and/or modify @@ -24,7 +24,6 @@ #define WIN32_LEAN_AND_MEAN #include <windows.h> -#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -324,14 +323,21 @@ init_inheritable_handles (struct inheritable_handles *inh_handles, HANDLE handle = (HANDLE) _get_osfhandle (fd); if (handle != INVALID_HANDLE_VALUE) { - DWORD hflags; - /* GetHandleInformation - <https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-gethandleinformation> */ - if (GetHandleInformation (handle, &hflags)) + if (duplicate) + /* We will add fd to the array, regardless of whether it is + inheritable or not. */ + break; + else { - if ((hflags & HANDLE_FLAG_INHERIT) != 0) - /* fd denotes an inheritable descriptor. */ - break; + DWORD hflags; + /* GetHandleInformation + <https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-gethandleinformation> */ + if (GetHandleInformation (handle, &hflags)) + { + if ((hflags & HANDLE_FLAG_INHERIT) != 0) + /* fd denotes an inheritable descriptor. */ + break; + } } } } @@ -339,31 +345,23 @@ init_inheritable_handles (struct inheritable_handles *inh_handles, } /* Note: handles_count >= 3. */ - /* Allocate the arrays. */ + /* Allocate the array. */ size_t handles_allocated = handles_count; - HANDLE *handles_array = - (HANDLE *) malloc (handles_allocated * sizeof (HANDLE)); - if (handles_array == NULL) - { - errno = ENOMEM; - return -1; - } - unsigned char *flags_array = - (unsigned char *) malloc (handles_allocated * sizeof (unsigned char)); - if (flags_array == NULL) + struct IHANDLE *ih = + (struct IHANDLE *) malloc (handles_allocated * sizeof (struct IHANDLE)); + if (ih == NULL) { - free (handles_array); errno = ENOMEM; return -1; } - /* Fill in the two arrays. */ + /* Fill in the array. */ { HANDLE curr_process = (duplicate ? GetCurrentProcess () : INVALID_HANDLE_VALUE); unsigned int fd; for (fd = 0; fd < handles_count; fd++) { - handles_array[fd] = INVALID_HANDLE_VALUE; + ih[fd].handle = INVALID_HANDLE_VALUE; /* _get_osfhandle <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle> */ HANDLE handle = (HANDLE) _get_osfhandle (fd); @@ -374,29 +372,42 @@ init_inheritable_handles (struct inheritable_handles *inh_handles, <https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-gethandleinformation> */ if (GetHandleInformation (handle, &hflags)) { - if ((hflags & HANDLE_FLAG_INHERIT) != 0) + if (duplicate) { - /* fd denotes an inheritable descriptor. */ - if (duplicate) + /* Add fd to the array, regardless of whether it is + inheritable or not. */ + if ((hflags & HANDLE_FLAG_INHERIT) != 0) + { + /* Instead of duplicating it, just mark it as shared. */ + ih[fd].handle = handle; + ih[fd].flags = KEEP_OPEN_IN_PARENT | KEEP_OPEN_IN_CHILD; + } + else { if (!DuplicateHandle (curr_process, handle, - curr_process, &handles_array[fd], + curr_process, &ih[fd].handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) { unsigned int i; for (i = 0; i < fd; i++) - if (handles_array[i] != INVALID_HANDLE_VALUE) - CloseHandle (handles_array[i]); - free (flags_array); - free (handles_array); + if (ih[i].handle != INVALID_HANDLE_VALUE + && !(ih[i].flags & KEEP_OPEN_IN_PARENT)) + CloseHandle (ih[i].handle); + free (ih); errno = EBADF; /* arbitrary */ return -1; } + ih[fd].flags = 0; + } + } + else + { + if ((hflags & HANDLE_FLAG_INHERIT) != 0) + { + /* fd denotes an inheritable descriptor. */ + ih[fd].handle = handle; + ih[fd].flags = KEEP_OPEN_IN_CHILD; } - else - handles_array[fd] = handle; - - flags_array[fd] = 0; } } } @@ -406,8 +417,7 @@ init_inheritable_handles (struct inheritable_handles *inh_handles, /* Return the result. */ inh_handles->count = handles_count; inh_handles->allocated = handles_allocated; - inh_handles->handles = handles_array; - inh_handles->flags = flags_array; + inh_handles->ih = ih; return 0; } @@ -418,9 +428,9 @@ compose_handles_block (const struct inheritable_handles *inh_handles, /* STARTUPINFO <https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa> */ sinfo->dwFlags = STARTF_USESTDHANDLES; - sinfo->hStdInput = inh_handles->handles[0]; - sinfo->hStdOutput = inh_handles->handles[1]; - sinfo->hStdError = inh_handles->handles[2]; + sinfo->hStdInput = inh_handles->ih[0].handle; + sinfo->hStdOutput = inh_handles->ih[1].handle; + sinfo->hStdError = inh_handles->ih[2].handle; /* On newer versions of Windows, more file descriptors / handles than the first three can be passed. @@ -471,11 +481,11 @@ compose_handles_block (const struct inheritable_handles *inh_handles, handles_aligned[fd] = INVALID_HANDLE_VALUE; flags[fd] = 0; - HANDLE handle = inh_handles->handles[fd]; + HANDLE handle = inh_handles->ih[fd].handle; if (handle != INVALID_HANDLE_VALUE /* The first three are possibly already passed above. But they need to passed here as well, if they have some flags. */ - && (fd >= 3 || inh_handles->flags[fd] != 0)) + && (fd >= 3 || (unsigned char) inh_handles->ih[fd].flags != 0)) { DWORD hflags; /* GetHandleInformation @@ -490,7 +500,7 @@ compose_handles_block (const struct inheritable_handles *inh_handles, flags[fd] = 1. But on ReactOS or Wine, adding the bit that indicates the handle type may be necessary. So, just do it everywhere. */ - flags[fd] = 1 | inh_handles->flags[fd]; + flags[fd] = 1 | (unsigned char) inh_handles->ih[fd].flags; switch (GetFileType (handle)) { case FILE_TYPE_CHAR: @@ -522,8 +532,7 @@ compose_handles_block (const struct inheritable_handles *inh_handles, void free_inheritable_handles (struct inheritable_handles *inh_handles) { - free (inh_handles->flags); - free (inh_handles->handles); + free (inh_handles->ih); } int @@ -619,9 +628,12 @@ spawnpvech (int mode, errno = saved_errno; return -1; } - inh_handles.handles[0] = stdin_handle; inh_handles.flags[0] = 0; - inh_handles.handles[1] = stdout_handle; inh_handles.flags[1] = 0; - inh_handles.handles[2] = stderr_handle; inh_handles.flags[2] = 0; + inh_handles.ih[0].handle = stdin_handle; + inh_handles.ih[0].flags = KEEP_OPEN_IN_CHILD; + inh_handles.ih[1].handle = stdout_handle; + inh_handles.ih[1].flags = KEEP_OPEN_IN_CHILD; + inh_handles.ih[2].handle = stderr_handle; + inh_handles.ih[2].flags = KEEP_OPEN_IN_CHILD; /* CreateProcess <https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa> */ |