On Mar 10 10:25, Corinna Vinschen wrote:
> execv (argv[1], args);

>  bash$ gcc -o exec exec.c
>  bash$ ./exec /bin/echo
>  abc
>  bash$ ./exec C:\\cygwin\\bin\\echo
>  abc
Thanks for trying a test case.  I am attaching a new test case that 
shows that the trouble was with execvp(), not exec().  Only execvp() 
calls find_exec() which fails to find a file in backslash notation,

  find_exec (path, buf, "PATH=", FE_NNF)

Another call to find_exec in spawnvpe() seems to succeed,

  find_exec (file, buf)

So, perhaps, another way to address the issue is to call find_exec()
without the 2 extra parameters.  I find it confusing that the 
function did not work despite its numerous options and its usage of 
isdrive() implying attempts to handle Windows native paths.

-- 
#include <process.h>    // for spawnvpe() (not specified by The Open Group)
#include <unistd.h>     // for execvp()
#include <stdio.h>      // for printf()
#include <errno.h>      // for errno
#include <string.h>     // for strdup(), strerror()
#include <stdlib.h>     // for getenv()

int
main (int argc, const char *argv[])
{
    const char const *args[3];
    char *mutable_args[3];
    // See http://c-faq.com/ansi/constmismatch.html explaining that a promise
    // of constness of values pointed to by pointer elements requires constness
    // of pointers as well.  In other words, a const char** parameter cannot
    // accept a char ** argument.
    const char *envp[2];
    const char *pathvalue = NULL;
    char *pathenv = NULL;
    int ec;

    if ( argc < 2 ) {
        return 2;
    }
 
    args[ 0 ] = argv[1];
    args[ 1 ] = "abc";
    args[ 2 ] = NULL;

    mutable_args[ 0 ] = strdup( args[ 0 ] );
    mutable_args[ 1 ] = strdup( args[ 1 ] );
    mutable_args[ 2 ] = NULL;

    pathvalue = getenv( "PATH" );
    if (pathvalue) {
        int pathlen = strlen( pathvalue );
        pathenv = malloc( 5 + pathlen + 1 );
        if ( pathenv ) {
            memcpy( pathenv, "PATH=", 5 );
            memcpy( pathenv + 5, pathvalue, pathlen + 1 );
        }
    }
    envp[ 0 ] = pathenv;
    envp[ 1 ] = NULL;

    setbuf( stdout, NULL );
    setbuf( stderr, NULL );

    printf( "Spawning %s with search in $PATH and a limited environment...\n", 
args[ 0 ] );
    ec = spawnvpe( _P_WAIT, args[ 0 ], args, envp );
    printf( "Exit code: %d\n\n", ec );

    printf( "Loading %s with search in $PATH and inherited environment...\n", 
args[ 0 ] );
    // The prototype in unistd.h differs from the one in process.h.  The former
    // does not promise to keep the pointers intact.
    execvp( args[ 0 ], mutable_args );
    ec = errno;
    printf( "Load error: %s (%d)\n", strerror( ec ), ec );
    return ec;
}

C:\WORK>.\exec.exe ..\echo.exe
Spawning ..\echo.exe with search in $PATH and a limited environment...
abc
Exit code: 0

Loading ..\echo.exe with search in $PATH and inherited environment...
Load error: No such file or directory (2)

C:\WORK>copy \cygwin\bin\cygwin1.dll.new \cygwin\bin\cygwin1.dll
Overwrite \cygwin\bin\cygwin1.dll? (Yes/No/All): y
        1 file(s) copied.

C:\WORK>.\exec.exe ..\echo.exe
Spawning ..\echo.exe with search in $PATH and a limited environment...
abc
Exit code: 0

Loading ..\echo.exe with search in $PATH and inherited environment...
abc

C:\WORK>

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Reply via email to