Re: [Mingw-w64-public] [PATCH] crt: execv*/spawnv* const-correctness
On Saturday 04 May 2024 23:46:03 LIU Hao wrote: > 在 2024-05-04 20:18, Pali Rohár 写道: > > msvcrt's execve splits every member of arglist to more arguments by > > space. If you want to prevent this splitting then you need to quote > > argument as: > > Each Windows process receives its command-line arguments as a whole string > and has to parse it with `__getmainargs()`, unlike on Linux etc. where > arguments are passed directly as a `char**`. I know. The point is that msvcrt's _execve() is not compatible with msvcrt's __getmainargs(). There is a convention which applications follow to convert argv[] array into single string command-line and vice-versa. It matches getmainargs. But _exec* and _spawn* do not follow it, which makes these two functions hard to use... > > > So in my opinion, for compatibility with POSIX (when one of those macro > > is defined, like _POSIX_C_SOURCE) then mingw-w64 should provide also > > POSIX compatible execve() function wrapper. > > I think that nobody would ever prefer `_execve()` because it's a Unix relic. > It would not be very useful without `fork()`. execve() may be useful also without fork() - for wrapper purposes. When executable A wants to just to redirect control to executable B. But I agree that most common usage is fork()+exec*() > And we probably should not be reproducing Unix too much. Makes sense. Better is to let this execve() issue as is. On a side note, I think that implementing posix_spawn() can be useful. It can be implemented as a simple wrapper around msvcrt spawn() with argv[] handling compatible with msvcrt __getmainargs(). ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: execv*/spawnv* const-correctness
在 2024-05-04 20:18, Pali Rohár 写道: msvcrt's execve splits every member of arglist to more arguments by space. If you want to prevent this splitting then you need to quote argument as: Each Windows process receives its command-line arguments as a whole string and has to parse it with `__getmainargs()`, unlike on Linux etc. where arguments are passed directly as a `char**`. So in my opinion, for compatibility with POSIX (when one of those macro is defined, like _POSIX_C_SOURCE) then mingw-w64 should provide also POSIX compatible execve() function wrapper. I think that nobody would ever prefer `_execve()` because it's a Unix relic. It would not be very useful without `fork()`. And we probably should not be reproducing Unix too much. -- Best regards, LIU Hao OpenPGP_signature.asc Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: execv*/spawnv* const-correctness
On Saturday 20 April 2024 12:24:53 Pali Rohár wrote: > > > > So we gain conformance with MSVC, but lose conformance with POSIX. > > > > (OTOH, > > > > our functions are named with leading underscores, which can motivate > > > > them > > > > differing.) > > > > > > AFAIK types (not even type-constness) are **not** a part of C ABI on any > > > known platform to me. > > > > I didn't say it is an ABI break - it's not. It's an API break though. > > Hello, in my opinion, when compiling in POSIX compatible mode, there > should be POSIX compatible declarations. When not compiling for POSIX > then there can be MSVC compatible declarations. Names with leading > underscore are not in POSIX, so they can always have MSVC compatible > declarations. > > So what about something like this? > > > _CRTIMP intptr_t __cdecl _execve(const char *_Filename,const char *const > *_ArgList,const char *const *_Env); > #if defined(_POSIX) || \ > defined(_POSIX_SOURCE) || \ > defined(_POSIX_C_SOURCE) || \ > defined(_XOPEN_SOURCE) || \ > defined(_XOPEN_SOURCE_EXTENDED) || \ > defined(_BSD_SOURCE) || \ > defined(_SVID_SOURCE) || \ > defined(_GNU_SOURCE) > _CRTIMP int __cdecl execve(const char *_Filename,char *const _ArgList[],char > *const _Env[]); > #else > _CRTIMP intptr_t __cdecl execve(const char *_Filename,const char *const > *_ArgList,const char *const *_Env); > #endif I was looking at behavior of msvcrt execve and it is not compatible with POSIX at all. For example if you call: char filename[] = "C:\\test.exe"; char argv1[] = "first arg"; char argv2[] = "second_arg"; char *argv[] = { filename, argv1, argv2, NULL }; execve(filename, argv, env); Then msvcrt will spawn a new process in which main() receive: argc = 4; argv[0] = "C:\\test.exe" argv[1] = "first" argv[2] = "arg" argv[3] = "second_arg" argv[4] = NULL msvcrt's execve splits every member of arglist to more arguments by space. If you want to prevent this splitting then you need to quote argument as: char argv1[] = "\"first arg\""; And if you want to pass quote character into arglist then you have to escape it via "\\". This is behavior is not compatible with POSIX, which execve() function passes arglist as-is into the process main()'s argv[]. So in my opinion, for compatibility with POSIX (when one of those macro is defined, like _POSIX_C_SOURCE) then mingw-w64 should provide also POSIX compatible execve() function wrapper. Also there is another problem with msvcrt execve() implementation. As Windows NT kernel does not have execve syscall, msvcrt.dll execve implementation spawns a new child process and then exit the current process. Which means that if the grand parent process (parent of the one which called msvcrt.dll execve) is waiting for its child to finish, it would not notice that its child called execve and will receive exit status 0 (returned by msvcrt.dll execve()) instead of the exit status of the process which was execve-ed. Also execve() disassociate stdin and stdout. Based on these facts, exeve() in msvcrt.dll is broken and if UNIX / POSIX based applications are going to be compiled against msvcrt.dll then they have to be modified and fixed for this behavior. So for this reason I would prefer to let execve() declarations in mingw-w64 header file as is, so it would trigger an compile warnings / errors. As this is a valid problem in application if it want to target mingw-w64 with msvcrt.dll. I guess that this issue was not even fixed in UCRT. If somebody wants better execve() then it basically should do something like this: - construct cmdline from arglist by correctly quoting and escaping every item - spawn a new process with correct cmdline and correctly inherits all handles - check for errors if spawn was successful - kill other threads of the current process except the current one - wait until the child process finish execution - exit current process with status of the (now finished) child process Also the other threads maybe should be suspended before the spawn and then resumed if spawn failed. ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: execv*/spawnv* const-correctness
> > > So we gain conformance with MSVC, but lose conformance with POSIX. (OTOH, > > > our functions are named with leading underscores, which can motivate them > > > differing.) > > > > AFAIK types (not even type-constness) are **not** a part of C ABI on any > > known platform to me. > > I didn't say it is an ABI break - it's not. It's an API break though. Hello, in my opinion, when compiling in POSIX compatible mode, there should be POSIX compatible declarations. When not compiling for POSIX then there can be MSVC compatible declarations. Names with leading underscore are not in POSIX, so they can always have MSVC compatible declarations. So what about something like this? _CRTIMP intptr_t __cdecl _execve(const char *_Filename,const char *const *_ArgList,const char *const *_Env); #if defined(_POSIX) || \ defined(_POSIX_SOURCE) || \ defined(_POSIX_C_SOURCE) || \ defined(_XOPEN_SOURCE) || \ defined(_XOPEN_SOURCE_EXTENDED) || \ defined(_BSD_SOURCE) || \ defined(_SVID_SOURCE) || \ defined(_GNU_SOURCE) _CRTIMP int __cdecl execve(const char *_Filename,char *const _ArgList[],char *const _Env[]); #else _CRTIMP intptr_t __cdecl execve(const char *_Filename,const char *const *_ArgList,const char *const *_Env); #endif ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: execv*/spawnv* const-correctness
On Fri, 19 Apr 2024, Nikita Kniazev wrote: A "char**" pointer can't be implicitly converted to a "const char**" pointer - see https://c-faq.com/ansi/constmismatch.html for the full explanation for this issue. The function arguments are not "const char**", they are "const char* const*" so there is no issue. That doesn't make any difference. The point is that non-const can be implicitly converted to const, only applies on the outermost pointer layer. int execve_before(const char *_Filename,char *const _ArgList[],char *const _Env[]); int execve_after(const char *_Filename,const char *const _ArgList[],const char *const _Env[]); void foo(char** args, char** env) { execve_before("x", args, env); execve_after("x", args, env); } https://godbolt.org/z/4Tx5j9KM9 Note how you run this example in C++ mode. As Liu Hao mentioned, the rules for these conversions differ between C and C++. If you convert your example to C, it gives loud warnings with Clang and is a hard error with GCC. https://godbolt.org/z/d7EsnK61x So we gain conformance with MSVC, but lose conformance with POSIX. (OTOH, our functions are named with leading underscores, which can motivate them differing.) AFAIK types (not even type-constness) are **not** a part of C ABI on any known platform to me. I didn't say it is an ABI break - it's not. It's an API break though. // Martin ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: execv*/spawnv* const-correctness
> A "char**" pointer can't be implicitly converted to a "const char**" > pointer - see https://c-faq.com/ansi/constmismatch.html for the full > explanation for this issue. The function arguments are not "const char**", they are "const char* const*" so there is no issue. int execve_before(const char *_Filename,char *const _ArgList[],char *const _Env[]); int execve_after(const char *_Filename,const char *const _ArgList[],const char *const _Env[]); void foo(char** args, char** env) { execve_before("x", args, env); execve_after("x", args, env); } https://godbolt.org/z/4Tx5j9KM9 > So we gain conformance with MSVC, but lose conformance with POSIX. (OTOH, > our functions are named with leading underscores, which can motivate them > differing.) AFAIK types (not even type-constness) are **not** a part of C ABI on any known platform to me. > In any case, while correct, this change can (and probably will) definitely > break building some user code that has so far worked So I don't think it is a breaking change. On Fri, Apr 19, 2024 at 10:38 AM Martin Storsjö wrote: > On Thu, 18 Apr 2024, Nikita Kniazev wrote: > > > From 0d9fb95b2c50a15a90276f67e7ec44c67cb1093b Mon Sep 17 00:00:00 2001 > > From: Nikita Kniazev > > Date: Thu, 18 Apr 2024 03:37:48 + > > Subject: [PATCH] crt: execv*/spawnv* const-correctness > > > > Signed-off-by: Nikita Kniazev > > --- > > mingw-w64-headers/crt/process.h | 26 +- > > 1 file changed, 13 insertions(+), 13 deletions(-) > > > > diff --git a/mingw-w64-headers/crt/process.h > > b/mingw-w64-headers/crt/process.h > > index 1ac39a064..8c35372a3 100644 > > --- a/mingw-w64-headers/crt/process.h > > +++ b/mingw-w64-headers/crt/process.h > > @@ -183,20 +183,20 @@ extern "C" { > > stupid warnings, define them in POSIX way. This is save, because > > those > > methods do not return in success case, so that the return value is > not > > really dependent to its scalar width. */ > > - _CRTIMP int __cdecl execv(const char *_Filename,char *const > _ArgList[]) > > __MINGW_ATTRIB_DEPRECATED_MSVC2005; > > - _CRTIMP int __cdecl execve(const char *_Filename,char *const > > _ArgList[],char *const _Env[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; > > - _CRTIMP int __cdecl execvp(const char *_Filename,char *const > _ArgList[]) > > __MINGW_ATTRIB_DEPRECATED_MSVC2005; > > - _CRTIMP int __cdecl execvpe(const char *_Filename,char *const > > _ArgList[],char *const _Env[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; > > + _CRTIMP int __cdecl execv(const char *_Filename,const char *const > > _ArgList[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; > > Thanks, I think this patch is correct, so I think we should apply it. > > However, this is a quite subtle area, and this can actually cause breakage > in user code. > > A "char**" pointer can't be implicitly converted to a "const char**" > pointer - see https://c-faq.com/ansi/constmismatch.html for the full > explanation for this issue. > > That said, MSVC's header seem to have const applied on these pointers like > you suggest, already in ancient versions like MSVC 6, up to the latest > versions using UCRT. So therefore, the change certainly is motivated, and > reduces the amount of unnecessary differences to MSVC. > > However, on the other side, the POSIX spec for the exec* family of > functions, declare them without const here: > https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html > > So we gain conformance with MSVC, but lose conformance with POSIX. (OTOH, > our functions are named with leading underscores, which can motivate them > differing.) > > In any case, while correct, this change can (and probably will) definitely > break building some user code that has so far worked, depending on > language mode and warning strictness etc. (Code that is built with both > MSVC and mingw might not have such issues though as there already was a > divergence.) > > // Martin > > > > ___ > Mingw-w64-public mailing list > Mingw-w64-public@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/mingw-w64-public > ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: execv*/spawnv* const-correctness
在 2024-04-19 16:00, LIU Hao 写道: The conversion from `char**` to `const char* const*` is only implicit in C++, and not in C. The POSIX prototypes have only one `const` [1]. The Microsoft variants do have double `const` [2], so I think the proposed patch may be acceptable, as long as users have been aware of that. My second thought is that GCC 14 (not branched yet, but available from https://gcc.godbolt.org/z/E9EnYTG39) starts to reject such conversions. Given that these names are POSIX, I'd prefer we follow POSIX and leave them alone. BTW, I would like to hear about the issues that they are causing. -- Best regards, LIU Hao OpenPGP_signature.asc Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: execv*/spawnv* const-correctness
在 2024-04-19 15:37, Martin Storsjö 写道: - _CRTIMP int __cdecl execvpe(const char *_Filename,char *const _ArgList[],char *const _Env[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; + _CRTIMP int __cdecl execv(const char *_Filename,const char *const _ArgList[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; Thanks, I think this patch is correct, so I think we should apply it. However, this is a quite subtle area, and this can actually cause breakage in user code. The conversion from `char**` to `const char* const*` is only implicit in C++, and not in C. The POSIX prototypes have only one `const` [1]. The Microsoft variants do have double `const` [2], so I think the proposed patch may be acceptable, as long as users have been aware of that. [1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html [2] https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/execve-wexecve?view=msvc-170 $ cat test.c void use(const char* const* pp); void pass(char** pp) { use(pp); } $ gcc -fsyntax-only -W{all,extra,pedantic} test.c test.c: In function ‘pass’: test.c:2:28: warning: passing argument 1 of ‘use’ from incompatible pointer type [-Wincompatible-pointer-types] 2 | void pass(char** pp) { use(pp); } |^~ || |char ** test.c:1:29: note: expected ‘const char * const*’ but argument is of type ‘char **’ 1 | void use(const char* const* pp); | ~~~^~ -- Best regards, LIU Hao OpenPGP_signature.asc Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] [PATCH] crt: execv*/spawnv* const-correctness
On Thu, 18 Apr 2024, Nikita Kniazev wrote: From 0d9fb95b2c50a15a90276f67e7ec44c67cb1093b Mon Sep 17 00:00:00 2001 From: Nikita Kniazev Date: Thu, 18 Apr 2024 03:37:48 + Subject: [PATCH] crt: execv*/spawnv* const-correctness Signed-off-by: Nikita Kniazev --- mingw-w64-headers/crt/process.h | 26 +- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/mingw-w64-headers/crt/process.h b/mingw-w64-headers/crt/process.h index 1ac39a064..8c35372a3 100644 --- a/mingw-w64-headers/crt/process.h +++ b/mingw-w64-headers/crt/process.h @@ -183,20 +183,20 @@ extern "C" { stupid warnings, define them in POSIX way. This is save, because those methods do not return in success case, so that the return value is not really dependent to its scalar width. */ - _CRTIMP int __cdecl execv(const char *_Filename,char *const _ArgList[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; - _CRTIMP int __cdecl execve(const char *_Filename,char *const _ArgList[],char *const _Env[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; - _CRTIMP int __cdecl execvp(const char *_Filename,char *const _ArgList[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; - _CRTIMP int __cdecl execvpe(const char *_Filename,char *const _ArgList[],char *const _Env[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; + _CRTIMP int __cdecl execv(const char *_Filename,const char *const _ArgList[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; Thanks, I think this patch is correct, so I think we should apply it. However, this is a quite subtle area, and this can actually cause breakage in user code. A "char**" pointer can't be implicitly converted to a "const char**" pointer - see https://c-faq.com/ansi/constmismatch.html for the full explanation for this issue. That said, MSVC's header seem to have const applied on these pointers like you suggest, already in ancient versions like MSVC 6, up to the latest versions using UCRT. So therefore, the change certainly is motivated, and reduces the amount of unnecessary differences to MSVC. However, on the other side, the POSIX spec for the exec* family of functions, declare them without const here: https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html So we gain conformance with MSVC, but lose conformance with POSIX. (OTOH, our functions are named with leading underscores, which can motivate them differing.) In any case, while correct, this change can (and probably will) definitely break building some user code that has so far worked, depending on language mode and warning strictness etc. (Code that is built with both MSVC and mingw might not have such issues though as there already was a divergence.) // Martin ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
[Mingw-w64-public] [PATCH] crt: execv*/spawnv* const-correctness
>From 0d9fb95b2c50a15a90276f67e7ec44c67cb1093b Mon Sep 17 00:00:00 2001 From: Nikita Kniazev Date: Thu, 18 Apr 2024 03:37:48 + Subject: [PATCH] crt: execv*/spawnv* const-correctness Signed-off-by: Nikita Kniazev --- mingw-w64-headers/crt/process.h | 26 +- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/mingw-w64-headers/crt/process.h b/mingw-w64-headers/crt/process.h index 1ac39a064..8c35372a3 100644 --- a/mingw-w64-headers/crt/process.h +++ b/mingw-w64-headers/crt/process.h @@ -183,20 +183,20 @@ extern "C" { stupid warnings, define them in POSIX way. This is save, because those methods do not return in success case, so that the return value is not really dependent to its scalar width. */ - _CRTIMP int __cdecl execv(const char *_Filename,char *const _ArgList[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; - _CRTIMP int __cdecl execve(const char *_Filename,char *const _ArgList[],char *const _Env[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; - _CRTIMP int __cdecl execvp(const char *_Filename,char *const _ArgList[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; - _CRTIMP int __cdecl execvpe(const char *_Filename,char *const _ArgList[],char *const _Env[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; + _CRTIMP int __cdecl execv(const char *_Filename,const char *const _ArgList[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; + _CRTIMP int __cdecl execve(const char *_Filename,const char *const _ArgList[],const char *const _Env[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; + _CRTIMP int __cdecl execvp(const char *_Filename,const char *const _ArgList[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; + _CRTIMP int __cdecl execvpe(const char *_Filename,const char *const _ArgList[],const char *const _Env[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; #else - _CRTIMP intptr_t __cdecl execv(const char *_Filename,char *const _ArgList[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; - _CRTIMP intptr_t __cdecl execve(const char *_Filename,char *const _ArgList[],char *const _Env[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; - _CRTIMP intptr_t __cdecl execvp(const char *_Filename,char *const _ArgList[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; - _CRTIMP intptr_t __cdecl execvpe(const char *_Filename,char *const _ArgList[],char *const _Env[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; + _CRTIMP intptr_t __cdecl execv(const char *_Filename,const char *const _ArgList[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; + _CRTIMP intptr_t __cdecl execve(const char *_Filename,const char *const _ArgList[],const char *const _Env[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; + _CRTIMP intptr_t __cdecl execvp(const char *_Filename,const char *const _ArgList[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; + _CRTIMP intptr_t __cdecl execvpe(const char *_Filename,const char *const _ArgList[],const char *const _Env[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; #endif - _CRTIMP intptr_t __cdecl spawnv(int,const char *_Filename,char *const _ArgList[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; - _CRTIMP intptr_t __cdecl spawnve(int,const char *_Filename,char *const _ArgList[],char *const _Env[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; - _CRTIMP intptr_t __cdecl spawnvp(int,const char *_Filename,char *const _ArgList[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; - _CRTIMP intptr_t __cdecl spawnvpe(int,const char *_Filename,char *const _ArgList[],char *const _Env[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; + _CRTIMP intptr_t __cdecl spawnv(int,const char *_Filename,const char *const _ArgList[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; + _CRTIMP intptr_t __cdecl spawnve(int,const char *_Filename,const char *const _ArgList[],const char *const _Env[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; + _CRTIMP intptr_t __cdecl spawnvp(int,const char *_Filename,const char *const _ArgList[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; + _CRTIMP intptr_t __cdecl spawnvpe(int,const char *_Filename,const char *const _ArgList[],const char *const _Env[]) __MINGW_ATTRIB_DEPRECATED_MSVC2005; #endif #endif /* _CRT_USE_WINAPI_FAMILY_DESKTOP_APP */ ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
[Mingw-w64-public] [PATCH] crt: execv*/spawnv* const-correctness
Hello. Found these doing binutils build check, where should I submit the patch? ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public