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

Reply via email to