Menu

#1265 POSIXness of exec* functions

WSL
open
None
none
Feature_in_WSL_4.1
2013-01-21
2009-03-06
Eric Blake
No

POSIX requires that the exec* family of functions take 'char *const argv[]' for argv and environ, but the mingw header process.h declares them with 'const char* const*'. The difference between 'char' and 'const char' means that compilers must issue a warning when passing correctly typed arguments to execv, which in turn breaks compilation with -Werror.

Discussion

  • Earnie Boyd

    Earnie Boyd - 2009-03-07

    This is another of those OLDNAMES issues. Microsoft no longer supplies the exec* family of functions. It supplies _exec* family of functions. Those are defined correctly by the mingw runtime. For instance Microsoft documentation states that execve is a deprecated POSIX name and redirects you to _execve instead. The question becomes how do we wish to fix this? I'm nearly in favor of setting _NO_OLDNAMES on by default but we could also make this one of those extensible items. I want to hear from others.

     
  • Earnie Boyd

    Earnie Boyd - 2009-03-07
    • labels: 456608 --> mingw runtime (deprecated use WSL)
    • milestone: --> Behaves_as_Documented
    • summary: wrong prototype for exec functions --> POSIXness of exec functions
     
  • Keith Marshall

    Keith Marshall - 2009-03-13

    IMO, it goes deeper than just an OLDNAMES issue. (FTR, I am *not* in favour of having _NO_OLDNAMES on by default).

    POSIX also requires the any of the exec functions shall *replace* the current process image with a new image. Microsoft's implementations have *never* fulfilled that requirement. They create a *new* *child* process, then cause the parent to immediately terminate; this breaks the parent..child relationship, which POSIX would expect to continue to exist, between the *parent* of the process *calling* exec, and the process created by the call. In POSIX semantics, their implementation is effectively equivalent to:

    if( (child_pid = fork()) == 0 )
    execv( child_image, argv );

    else if( child > 0 )
    exit( 0 );

    The effects are such that I very strongly recommend *never* using Microsoft's exec functions; use _spawn instead, and follow a successful outcome with a _cwait on the child_pid, (or do that with a _P_WAIT attribute in the _spawn mode flags), terminating only after the child returns. It may seem inefficient, in terms of process memory usage, but it does at least preserve a more logical relationship between the parent and child, (albeit as a grandparent..child relationship, in reality).

    That caveat aside, I guess we could define the execv functions, with POSIX syntax prototypes, as inlined wrappers around their _execv counterparts, with appropriate casting of the incompatibly typed arguments, (or even simply just supply the POSIX compatible prototypes for the execv functions, regardless of the difference with the Microsoft syntax in the _execv prototypes -- ld will not care, when it comes to resolve the references, and users wanting the Microsoft syntax should be using the _execv names anyway, since Microsoft have deprecated the POSIX names as of VS-2005).

    Just to complete the discussion, note that this particular inconsistency afflicts only the execv forms of the functions; the execl forms have consistent argument types, with their _execl counterparts. However, there is one further inconsistency, which afflicts *all* forms -- Microsoft now declare the function return type as intptr_t, for all forms, where POSIX specifies `int'. We should address that, in similar manner.

     
  • Earnie Boyd

    Earnie Boyd - 2013-01-21
    • labels: mingw runtime (deprecated use WSL) -->
    • assigned_to: Earnie Boyd
    • resolution: --> none
    • category: --> Feature_in_WSL_4.1
    • milestone: Behaves_as_Documented --> WSL