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