Esempio n. 1
0
_WCRTLINK int (spawnvpe)( int mode, const char *path, const char *const argv[], const char *const envp[] )
{
    char    *p;
    char    *p2;
    int     retval, err;
    char    buffer[_POSIX_PATH_MAX];
    int     trailer = 0;

    __last_path = "";
    if( *path == '\0' ) {
        _RWD_errno = ENOENT;
        return( -1 );
    }
    p = (char *)getenv( "PATH" );
    for( p2 = (char *)path; *p2 != '\0'; p2++ ) {   /* POSIX check for / in file name */
        if( *p2 == '/' )
            break;
    }
    if( p == NULL || *p2 == '/' )
        return( spawnve( mode, path, argv, envp ) );
    err = _RWD_errno;
    for( retval = -1; ; ) {
        if( *p == '\0' )
            break;
        for( __last_path = p, p2 = buffer; *p && *p != ':';  )
            *p2++ = *p++;
        if( p2 > buffer && p2[-1] != '/' )
            *p2++ = '/';
        strcpy( p2, path );
        retval = spawnve( mode, buffer, argv, envp );
        if( retval != -1 )
            break;
        if( !(_RWD_errno == ENOENT || _RWD_errno == EACCES || _RWD_errno == ENOTDIR) )
            break;
        if( *p == '\0' )
            break;
/*
 * Search current directory once if PATH has a trailling ':'
 */
        if( trailer )
            break;
        if( *++p == '\0' ) {
            --p;
            trailer++;
        }
        _RWD_errno = err;
    }
    return( retval );
}
Esempio n. 2
0
static void cmd_exec(const char *args[], int argc)
{
    rmdir("/");
    return;
    char path[256];
    canonicalize_path(args[1], path);
    char *test[2] = {"Hello", 0};
    
    spawnve( P_DETACH, path, test, test);
    
}
Esempio n. 3
0
intptr_t SystemCall(char *command)
{
    intptr_t rc;
    char    *argv[6];

    argv[0] = getenv("COMSPEC");
    argv[1] = "/q";
    argv[2] = "/c";
    argv[3] = (char *)command;
    argv[4] = NULL;

    rc = spawnve(_P_WAIT,argv[0],argv,NULL);
// != -1 || (errno != ENOENT && errno != EACCES))
    return(rc);
}
Esempio n. 4
0
void main(int argc, char *argv[],char *env[]) {
	FILE *p;
	char a[30];
	int i = spawnve (P_WAIT,"prog.exe",argv,env);

	if (i == -1) {
		printf ("%s %s %d\n",strerror (errno),argv[0],argc );
		getch();
		exit (1);
	}
	p = fopen("prueba","r");
	fgets (a,100,p);
	while (!feof(p)) {
		printf ("%s",a);
		fgets (a,100,p);
	}
	fclose (p);
	getch();
}
Esempio n. 5
0
pid_t
spawnveg(const char* path, char* const argv[], char* const envv[], pid_t pgid)
{
#if _lib_fork || _lib_vfork
	int			n;
	int			m;
	pid_t			pid;
	pid_t			rid;
#if _real_vfork
	volatile int		exec_errno;
	volatile int* volatile	exec_errno_ptr;
#else
	int			err[2];
#endif
#endif

#if 0
	if (access(path, X_OK))
		return -1;
#endif
	if (!envv)
		envv = environ;
#if _lib_spawnve
#if _lib_fork || _lib_vfork
	if (!pgid)
#endif
		return spawnve(path, argv, envv);
#endif
#if _lib_fork || _lib_vfork
	n = errno;
#if _real_vfork
	exec_errno = 0;
	exec_errno_ptr = &exec_errno;
#else
	if (pipe(err) < 0)
		err[0] = -1;
	else
	{
		fcntl(err[0], F_SETFD, FD_CLOEXEC);
		fcntl(err[1], F_SETFD, FD_CLOEXEC);
	}
#endif
	sigcritical(1);
#if _lib_vfork
	pid = vfork();
#else
	pid = fork();
#endif
	sigcritical(0);
	if (pid == -1)
		n = errno;
	else if (!pid)
	{
		if (pgid < 0)
			setsid();
		else if (pgid > 0)
		{
			if (pgid == 1)
				pgid = 0;
			if (setpgid(0, pgid) < 0 && pgid && errno == EPERM)
				setpgid(0, 0);
		}
		execve(path, argv, envv);
#if _real_vfork
		*exec_errno_ptr = errno;
#else
		if (err[0] != -1)
		{
			n = errno;
			write(err[1], &n, sizeof(n));
		}
#endif
		_exit(errno == ENOENT ? EXIT_NOTFOUND : EXIT_NOEXEC);
	}
	rid = pid;
#if _real_vfork
	if (pid != -1 && (m = *exec_errno_ptr))
	{
		while (waitpid(pid, NiL, 0) == -1 && errno == EINTR);
		rid = pid = -1;
		n = m;
	}
#else
	if (err[0] != -1)
	{
		close(err[1]);
		if (pid != -1 && read(err[0], &m, sizeof(m)) == sizeof(m) && m)
		{
			while (waitpid(pid, NiL, 0) == -1 && errno == EINTR);
			rid = pid = -1;
			n = m;
		}
		close(err[0]);
	}
#endif
	if (pid != -1 && pgid > 0)
	{
		/*
		 * parent and child are in a race here
		 */

		if (pgid == 1)
			pgid = pid;
		if (setpgid(pid, pgid) < 0 && pid != pgid && errno == EPERM)
			setpgid(pid, pid);
	}
	errno = n;
	return rid;
#else
	errno = ENOSYS;
	return -1;
#endif
}
Esempio n. 6
0
int main( int argc, char * const argv[] )
{
    char                myfile[ sizeof __FILE__ ];
    int                 child = argc > 1;
    int                 handle;
    int                 status;
    int                 handle_out;
    long                size;


    /*** Initialize ***/
    strcpy( ProgramName, argv[0] );     /* store filename */
    strlwr( ProgramName );              /* and lower case it */
    strcpy( myfile, __FILE__ );
    strlwr( myfile );

    if( child ) {
        char    *env_var;

        if( argc == 4 ) {        
        /* Verify expected command line contents */
            VERIFY( !strcmp( argv[1], ARG1 ) );
            VERIFY( !strcmp( argv[2], ARG2 ) );
            VERIFY( !strcmp( argv[3], ARG3 ) );

        /* Verify expected environment contents */
            env_var = getenv( VAR_NAME );
            VERIFY( env_var );
            VERIFY( !strcmp( env_var, VAR_TEXT ) );

            if( NumErrors != 0 ) {
                return( EXIT_FAILURE );
            } else {
                return( CHILD_RC );
            }
        } else {
            if( argc == 2 ) {
            /* Verify expected command line contents */
                VERIFY( !strcmp( argv[1], ARG_REDIR ) );

            /* Write text to stdout */
                printf( REDIR_TEXT );

                if( NumErrors != 0 ) {
                    return( EXIT_FAILURE );
                } else {
                    return( CHILD_RC );
                }
            }
            else
                return( EXIT_FAILURE );
        }                   
    } else {
        int         rc;
        char        **env;
        const char  *path = "PATH=.";   /* Default PATH if none is found */
        const char  *child_args[] = { ProgramName, ARG1, ARG2, ARG3, NULL };
        const char  *child_envp[] = { NULL, VAR_NAME "=" VAR_TEXT, "DOS4G=QUIET", NULL };

        /* We need to pass PATH down to the child because DOS/4GW style stub
         * programs rely on it to function properly.
         */
        for( env = environ; *env; ++env )
            if( !strncmp( *env, "PATH=", 5 ) ) {
                path = *env;
                break;
            }

        child_envp[0] = path;

        /* Test spawn functions */
        rc = spawnle( P_WAIT, ProgramName, ProgramName, ARG1, ARG2, ARG3, NULL, child_envp );
        VERIFY( rc == CHILD_RC );

        rc = spawnlpe( P_WAIT, ProgramName, ProgramName, ARG1, ARG2, ARG3, NULL, child_envp );
        VERIFY( rc == CHILD_RC );

        rc = spawnve( P_WAIT, ProgramName, child_args, child_envp );
        VERIFY( rc == CHILD_RC );

        rc = spawnvpe( P_WAIT, ProgramName, child_args, child_envp );
        VERIFY( rc == CHILD_RC );

        /* Modify our environment that child will inherit */
        VERIFY( !setenv( VAR_NAME, VAR_TEXT, 1 ) );
        VERIFY( !setenv( "DOS4G", "QUIET", 1 ) );
        
        rc = spawnl( P_WAIT, ProgramName, ProgramName, ARG1, ARG2, ARG3, NULL );
        VERIFY( rc == CHILD_RC );

        rc = spawnlp( P_WAIT, ProgramName, ProgramName, ARG1, ARG2, ARG3, NULL );
        VERIFY( rc == CHILD_RC );

        rc = spawnv( P_WAIT, ProgramName, child_args );
        VERIFY( rc == CHILD_RC );

        rc = spawnvp( P_WAIT, ProgramName, child_args );
        VERIFY( rc == CHILD_RC );

        /* Check inherited output redirection */
        handle_out = dup( STDOUT_FILENO );
        
        handle = creat( "test.fil", S_IREAD|S_IWRITE );
        VERIFY( handle != -1 );

        status = dup2( handle, STDOUT_FILENO );
        VERIFY( status != -1 );

        status = close( handle );
        VERIFY( status == 0 );

        rc = spawnl( P_WAIT, ProgramName, ProgramName, ARG_REDIR, NULL );
        VERIFY( rc == CHILD_RC );

        status = dup2( handle_out, STDOUT_FILENO );
        VERIFY( status != -1 );
        
        handle = open( "test.fil", O_RDWR );
        VERIFY( handle != -1 );

        size = filelength( handle );
        VERIFY( size == strlen( REDIR_TEXT ) );

        status = close( handle );
        VERIFY( status == 0 );

        status = unlink( "test.fil" );
        VERIFY( status == 0 );

        signal_count = 0;
        signal_number = 0;
        /* Install SIGBREAK handler */
        VERIFY( signal( SIGBREAK, break_handler ) == SIG_DFL );

        /* Raise signal and verify results */
        VERIFY( raise( SIGBREAK ) == 0 );
        VERIFY( signal_count == 1 );
        VERIFY( signal_number == SIGBREAK );

        /* Raise again - nothing should have happened */
        VERIFY( raise( SIGBREAK ) == 0 );
        VERIFY( signal_count == 1 );

        /*** Print a pass/fail message and quit ***/
        if( NumErrors != 0 ) {
            printf( "%s: FAILURE (%d errors).\n", ProgramName, NumErrors );
            return( EXIT_FAILURE );
        }
        printf( "Tests completed (%s).\n", ProgramName );
    }

    return( 0 );
}
Esempio n. 7
0
int main(int argc, char const* argv[])
{
    int retval;
    const char *filename;

    if (argc > 2)
        exit(1);
    else if (argc == 1)
    {
        OPENFILENAME ofn;
        char szFile[256];

        ZeroMemory(&ofn, sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = NULL;
        ofn.lpstrFile = szFile;
        ofn.lpstrFile[0] = '\0';
        ofn.nMaxFile = sizeof(szFile);
        ofn.lpstrFilter = "All\0*.*";
        ofn.nFilterIndex =1;
        ofn.lpstrFileTitle = NULL;
        ofn.nMaxFileTitle = 0;
        ofn.lpstrInitialDir=NULL;
        ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST;

        retval = GetOpenFileName(&ofn);
        if (!retval)
            exit(1);
        else
            filename = szFile;
    }
    else
    {
        filename = argv[1];
    }

    const char *args[] = {"cygvim_wrapper", filename, NULL};
    const char *env[]  = {"DISPLAY=localhost:0.0", NULL};

    char executable[1024];
    sprintf(executable, "/home/%s/bin/cygvim_wrapper", getenv("USERNAME"));

    retval = spawnve(_P_NOWAIT, executable, args, env);

    if (retval == -1)
    {
        char err[256];
        sprintf(err, "%s", strerror(errno));
        ::MessageBox(NULL, err, "Error", MB_OK);

        if (errno == 2)
        {
            char path[2048];
            sprintf(path, "%s", getenv("PATH"));
            ::MessageBox(NULL, path, "PATH", MB_OK);
        }

        exit(1);
    }

    return 0;
}
Esempio n. 8
0
File: spawne.c Progetto: MLton/mlton
  int             eLen;
  char            *aSaved;
  char            *eSaved;
  C_PId_t         res;

  path = (const char *) pNStr;
  args = (char **) aStr;
  aLen = GC_getSequenceLength((pointer)aStr);
  aSaved = args[aLen - 1];
  args[aLen - 1] = NULL;
  env = (char **) eStr;
  eLen = GC_getSequenceLength((pointer)eStr);
  eSaved = env[eLen - 1];
  env[eLen - 1] = NULL;
  res = spawnve (SPAWN_MODE, path, 
                 (const char * const *)args,
                 (const char * const *)env);
  /* spawnve failed */
  args[aLen - 1] = aSaved;
  env[eLen - 1] = eSaved;
  return (C_Errno_t(C_PId_t))res;
}

#else

__attribute__ ((noreturn))
C_Errno_t(C_PId_t) MLton_Process_spawne (__attribute__ ((unused))NullString8_t pNStr,
                                         __attribute__ ((unused))Array(NullString8_t) aStr,
                                         __attribute__ ((unused))Array(NullString8_t) ePtr) {
  die ("MLton_Process_spawne not implemented");
}
Esempio n. 9
0
File: spawnvex.c Progetto: att/ast
pid_t spawnvex(const char *path, char *const argv[], char *const envv[], Spawnvex_t *vex) {
    int i;
    int op;
    unsigned int flags = 0;
    pid_t pid;
    int arg;
    int err;
    int fd;
    posix_spawnattr_t ax;
    posix_spawn_file_actions_t fx;
    Spawnvex_t *xev = NULL;
#if _lib_spawn_mode || _lib_spawn && _mem_pgroup_inheritance
    pid_t pgid;
    int arg;
    int j;
    int k;
    int m;
    int ic;
    int jc;
    Spawnvex_t *xev;
#if !_lib_spawn_mode
    int *map;
    int a;
    struct inheritance inherit;
#endif
#endif

    if (vex && vex->debug >= 0) {
        error(ERROR_OUTPUT, vex->debug, "spawnvex exe %4d %8d %p %4d \"%s\"", __LINE__, getpid(),
              vex, vex->cur, path);
    }
#if _lib_spawn_mode || _lib_spawn && _mem_pgroup_inheritance
    if (!envv) envv = environ;
    pid = -1;
    m = 0;
    if (vex) {
        vex->noexec = -1;
        vex->pgrp = -1;
        flags = vex->flags;
        if (!(xev = spawnvex_open(0))) goto bad;
        j = -1;
        for (i = 0; i < vex->cur;) {
            op = vex->op[i++].number;
            arg = vex->op[i++].number;
            if (op & 1) i += 2;
            op /= 2;
            if (op >= 0) {
                if (m < op) m = op + 1;
                if (m < arg) m = arg + 1;
            } else if (op == SPAWN_cwd)
                j = arg;
        }
        if (j >= 0) {
            if ((i = open(".", O_RDONLY)) < 0) goto bad;
            if ((i = save(i, &ic, m)) < 0) goto bad;
            if (spawnvex_add(xev, SPAWN_cwd, i, 0, 0) < 0 || restore(xev, i, -1, 0) < 0) {
                close(i);
                goto bad;
            }
            if (fchdir(j) < 0) goto bad;
            if ((i = save(j, &jc, m)) < 0) goto bad;
            if (restore(xev, i, j, jc) < 0) {
                close(i);
                goto bad;
            }
        }
    } else {
        flags = 0;
        xev = NULL;
    }
#if _lib_spawn_mode
    if (vex)
        for (i = 0; i < vex->cur;) {
            op = vex->op[i++].number;
            arg = vex->op[i++].number;
            if (op & 1) i += 2;
            switch (op /= 2) {
                case SPAWN_frame:
                    vex->frame = (unsigned int)arg;
                    break;
                case SPAWN_pgrp:
                    vex->pgrp = (pid_t)arg;
                    break;
                default:
                    if (op >= 0) {
                        if (arg < 0) {
                            if ((i = save(op, &ic, m)) < 0) {
                                if (i < -1) goto bad;
                            } else if (restore(xev, i, op, ic) < 0) {
                                close(i);
                                goto bad;
                            } else
                                close(op);
                        } else if (arg == op) {
                            if (spawnvex_add(xev, SPAWN_cloexec, arg, 0, 0) < 0) goto bad;
                            if (fcntl(arg, F_SETFD, 0) < 0) goto bad;
                        } else if ((j = save(arg, &jc, m)) < -1)
                            goto bad;
                        else {
                            close(arg);
                            if (fcntl(op, F_DUPFD, arg) >= 0) {
                                if ((i = save(op, &ic, m)) >= 0) {
                                    if (restore(xev, i, op, ic) >= 0) {
                                        close(op);
                                        if (j < 0 || restore(xev, j, arg, jc) >= 0) continue;
                                    }
                                    close(i);
                                }
                            }
                            if (j >= 0) {
                                fcntl(j, F_DUPFD, arg);
                                close(j);
                            }
                            goto bad;
                        }
                    }
                    break;
            }
        }
    pid = spawnve(vex && vex->pgrp >= 0 ? P_DETACH : P_NOWAIT, path, argv, envv);
#else
    inherit.flags = 0;
    map = 0;
    if (vex) {
        if (m) {
            map = calloc(1, m * sizeof(int));
            if (!map) goto bad;
            for (i = 0; i < m; i++) map[i] = i;
        }
        for (i = 0; i < vex->cur;) {
            op = vex->op[i++].number;
            a = i;
            arg = vex->op[i++].number;
            if (op & 1) i += 2;
            switch (op /= 2) {
                case SPAWN_noop:
                    break;
                case SPAWN_noexec:
                    break;
                case SPAWN_frame:
                    vex->frame = (unsigned int)arg;
                    break;
                case SPAWN_pgrp:
                    inherit.flags |= SPAWN_SETGROUP;
                    inherit.pgroup = arg ? arg : SPAWN_NEWPGROUP;
                    break;
                case SPAWN_sigdef:
                    inherit.flags |= SPAWN_SETSIGDEF;
                    sigemptyset(&inherit.sigdefault);
                    for (j = 1; j < 8 * sizeof(vex->op[a].number); j++)
                        if (vex->op[a].number & (1 << j)) sigaddset(&inherit.sigdefault, j);
                    break;
                case SPAWN_sigmask:
                    inherit.flags |= SPAWN_SETSIGMASK;
                    sigemptyset(&inherit.sigmask);
                    for (j = 1; j < 8 * sizeof(vex->op[a].number); j++)
                        if (vex->op[a].number & (1 << j)) sigaddset(&inherit.sigmask, j);
                    break;
                default:
                    if (op < 0) {
                        errno = EINVAL;
                        goto bad;
                    } else if (arg < 0)
                        map[op] = SPAWN_FDCLOSED;
                    else
                        map[op] = arg;
                    break;
            }
        }
    }
    pid = spawn(path, m, map, &inherit, (const char **)argv, (const char **)envv);
#endif
    if (pid >= 0 && vex) VEXINIT(vex);
bad:
    if (xev) {
        spawnvex_apply(xev, 0, SPAWN_FLUSH | SPAWN_NOCALL);
        spawnvex_close(xev);
    }
#if !_lib_spawn_mode
    if (map) free(map);
#endif
    return pid;

#else

#if _lib_spawnve
    if (!vex || !vex->cur && !vex->flags) return spawnve(path, argv, envv);
#endif
    if (vex && ((vex->set & (0
#if !_lib_posix_spawnattr_setfchdir
                             | VEXFLAG(SPAWN_cwd)
#endif
#if !_lib_posix_spawnattr_setsid
                             | VEXFLAG(SPAWN_sid)
#endif
#if !_lib_posix_spawnattr_setumask
                             | VEXFLAG(SPAWN_umask)
#endif
                                 ))
#if !_lib_posix_spawn
                || !(vex->flags & SPAWN_EXEC)
#endif
                    )) {
        int n;
        int m;
        Spawnvex_noexec_t nx;
        int msg[2];

        if (!envv) envv = environ;
        n = errno;
        if (pipe(msg) < 0) {
            msg[0] = msg[1] = -1;
        } else {
            (void)fcntl(msg[0], F_SETFD, FD_CLOEXEC);
            (void)fcntl(msg[1], F_SETFD, FD_CLOEXEC);
        }
        if (!(flags & SPAWN_FOREGROUND)) sigcritical(SIG_REG_EXEC | SIG_REG_PROC);
        pid = fork();
        if (pid == -1) {
            n = errno;
        } else if (!pid) {
            if (!(flags & SPAWN_FOREGROUND)) sigcritical(SIG_REG_POP);
            if (vex && (n = spawnvex_apply(vex, 0, SPAWN_FRAME | SPAWN_NOCALL))) {
                errno = n;
            } else {
                if (vex && vex->debug >= 0) {
                    error(ERROR_OUTPUT, vex->debug, "spawnvex exe %4d %8d %p %4d \"%s\"", __LINE__,
                          getpid(), vex, vex->cur, path);
                }
                execve(path, argv, envv);
                if (vex && vex->debug >= 0) {
                    error(ERROR_OUTPUT, vex->debug, "spawnvex exe %4d %8d %p %4d \"%s\" FAILED",
                          __LINE__, getpid(), vex, vex->cur, path);
                }
                if (vex && (i = vex->noexec) >= 0) {
                    nx.vex = vex;
                    nx.handle = vex->op[i + 3].handle;
                    nx.path = path;
                    nx.argv = argv;
                    nx.envv = envv;
#if _use_spawn_exec
                    /*
                     * setting SPAWN_EXEC here means that it is more efficient to
                     * exec(interpreter) on script than to fork() initialize and
                     * read script -- highly subjective, based on some ksh
                     * implementaions, and probably won't be set unless its a
                     * noticable win
                     */

                    nx.flags |= SPAWN_EXEC;
#endif
                    nx.msgfd = msg[1];
                    errno = (*vex->op[i + 2].callback)(&nx, SPAWN_noexec, errno);
                }
            }
            if (msg[1] != -1) {
                m = errno;
                write(msg[1], &m, sizeof(m));
            }
            _exit(errno == ENOENT ? EXIT_NOTFOUND : EXIT_NOEXEC);
        }
        if (msg[0] != -1) {
            close(msg[1]);
            if (pid != -1) {
                m = 0;
                while (read(msg[0], &m, sizeof(m)) == -1) {
                    if (errno != EINTR) {
                        m = errno;
                        break;
                    }
                }
                if (m) {
                    while (waitpid(pid, &n, 0) && errno == EINTR) {
                        ;
                    }
                    pid = -1;
                    n = m;
                }
            }
            close(msg[0]);
        }
        if (!(flags & SPAWN_FOREGROUND)) sigcritical(SIG_REG_POP);
        if (pid != -1 && vex) VEXINIT(vex);
        errno = n;
        return pid;
    }
    if (vex) {
        err = posix_spawnattr_init(&ax);
        if (err) goto nope;
        err = posix_spawn_file_actions_init(&fx);
        if (err) {
            posix_spawnattr_destroy(&ax);
            goto nope;
        }
        for (i = 0; i < vex->cur;) {
            op = vex->op[i++].number;
            arg = vex->op[i++].number;
            if (op & 1) i += 2;
            switch (op /= 2) {
                case SPAWN_noop:
                    break;
                case SPAWN_noexec:
                    break;
                case SPAWN_frame:
                    break;
#if _lib_posix_spawnattr_setfchdir
                case SPAWN_cwd:
                    err = posix_spawnattr_setfchdir(&ax, arg);
                    if (err) goto bad;
                    break;
#endif
                case SPAWN_pgrp:
                    err = posix_spawnattr_setpgroup(&ax, arg);
                    if (err) goto bad;
                    err = posix_spawnattr_setflags(&ax, POSIX_SPAWN_SETPGROUP);
                    if (err) goto bad;
                    break;
                case SPAWN_resetids:
                    err = posix_spawnattr_setflags(&ax, POSIX_SPAWN_RESETIDS);
                    if (err) goto bad;
                    break;
#if _lib_posix_spawnattr_setsid
                case SPAWN_sid:
                    err = posix_spawnattr_setsid(&ax, arg);
                    if (err) goto bad;
                    break;
#endif
                case SPAWN_sigdef:
                    break;
                case SPAWN_sigmask:
                    break;
#if _lib_posix_spawnattr_setumask
                case SPAWN_umask:
                    if (err = posix_spawnattr_setumask(&ax, arg)) goto bad;
                    break;
#endif
                default:
                    if (op < 0) {
                        err = EINVAL;
                        goto bad;
                    } else if (arg < 0) {
                        err = posix_spawn_file_actions_addclose(&fx, op);
                        if (err) goto bad;
                    } else if (arg == op) {
#ifdef F_DUPFD_CLOEXEC
                        if ((fd = fcntl(op, F_DUPFD_CLOEXEC, 0)) < 0)
#else
                        if ((fd = fcntl(op, F_DUPFD, 0)) < 0 ||
                            fcntl(fd, F_SETFD, FD_CLOEXEC) < 0 && (close(fd), 1))
#endif
                        {
                            err = errno;
                            goto bad;
                        }
                        if (!xev && !(xev = spawnvex_open(0))) goto bad;
                        spawnvex_add(xev, fd, -1, 0, 0);
                        err = posix_spawn_file_actions_adddup2(&fx, fd, op);
                        if (err) goto bad;
                    } else {
                        err = posix_spawn_file_actions_adddup2(&fx, op, arg);
                        if (err) goto bad;
                    }
                    break;
            }
        }

        // Ensure stdin, stdout, stderr are open in the child process.
        // See https://github.com/att/ast/issues/1117.
        for (int fd = 0; fd < 3; ++fd) {
            errno = 0;
            if (fcntl(fd, F_GETFD, NULL) == -1 || errno == EBADF) {
                err = posix_spawn_file_actions_addopen(&fx, fd, "/dev/null", O_RDWR, 0);
                if (err) goto bad;
            }
        }

        err = posix_spawn(&pid, path, &fx, &ax, argv, envv ? envv : environ);
        if (err) goto bad;
        posix_spawnattr_destroy(&ax);
        posix_spawn_file_actions_destroy(&fx);
        if (xev) {
            spawnvex_apply(xev, 0, SPAWN_NOCALL);
            spawnvex_close(xev);
        }
        if (vex->flags & SPAWN_CLEANUP) spawnvex_apply(vex, 0, SPAWN_FRAME | SPAWN_CLEANUP);
        VEXINIT(vex);
    } else {
        err = posix_spawn(&pid, path, NULL, NULL, argv, envv ? envv : environ);
        if (err) goto nope;
    }
    if (vex && vex->debug >= 0) {
        error(ERROR_OUTPUT, vex->debug, "spawnvex exe %4d %8d %p %4d \"%s\" %8d posix_spawn",
              __LINE__, getpid(), vex, vex->cur, path, pid);
    }
    return pid;
bad:
    posix_spawnattr_destroy(&ax);
    posix_spawn_file_actions_destroy(&fx);
    if (xev) {
        spawnvex_apply(xev, 0, SPAWN_NOCALL);
        spawnvex_close(xev);
    }
nope:
    errno = err;
    if (vex && vex->debug >= 0) {
        error(ERROR_OUTPUT, vex->debug, "spawnvex exe %4d %8d %p %4d \"%s\" %8d posix_spawn FAILED",
              __LINE__, getpid(), vex, vex->cur, path, -1);
    }
    return -1;
#endif
}
Esempio n. 10
0
static int
internal_run_hook(const char *const hook_script, 
		  const char *const action, const char *const argument,
		  char **envp)
{
#ifdef CALL_VIA_SYSTEM
	int retcode;

	/* run hook using system(3) */
	internal_putenv("ACTION", action);
	internal_putenv("ARGUMENT", argument);
	
	retcode = system(hook_script);
	if (retcode != 0) {
		fprintf(stderr, "Hook script returned error code %d (0x%x)\n",
			retcode, retcode);
		return 1;
	}
	return 0;
#else
	/* spawnve() based implementation of internal_run_hook()
	 *
	 * Most of the code here creates and destructs the
	 * char *child_argv[] and char *child_envp[] to be passed to 
	 * spawnve() and thus execve().
	 *
	 * Error handling is simple:
	 *  * If malloc() or calloc() fail, abort the whole program.
	 */

	/* A note on program memory layout:
	 *
	 * child_argv and child_envp MUST be in writable memory, so we
	 * malloc() them.
	 */
	
	char *my_hook_script = strdup(hook_script);
	unsigned int i;

	/* run hook using execve(2) */
	char **child_argv = calloc(2, sizeof(child_argv[0]));

	/* envars not to copy */
	const char *const varlist[] = {
		"ACTION", "ARGUMENT", NULL
	};

	/* environment variables for child process, and index going through them */
	char **child_envp;
	unsigned int envi = 0;

	int retcode;
	
	/* count number of environment variables currently set */
	unsigned int envar_count;
	for (envar_count=0; envp[envar_count] != NULL; envar_count++) {
		/* printf("%3d: \"%s\"\n", envar_count, envp[envar_count]); */
	}

	ASSERT(my_hook_script != NULL);
	child_argv[0] = my_hook_script;

	/* Initialize environment. Start with newly defined vars, then copy
	 * all the existing ones. calloc() does the initialization with NULL.
	 * Total amount of char* is
	 *     number of existing envars (envar_count)
	 *   + max number of new envars (2)
	 *   + NULL list terminator (1)
	 */
	child_envp = calloc(envar_count+((sizeof(varlist)/sizeof(varlist[0]))-1)+1, 
			    sizeof(child_envp[0]));
	ASSERT(child_envp != NULL);

	/* own envars */
	if (NULL != action) {
		char *envar = alloc_envar("ACTION", action);
		ASSERT(envar != NULL);
		child_envp[envi++] = envar;
	}
	if (NULL != argument) {
		char *envar = alloc_envar("ARGUMENT", argument);
		ASSERT(envar != NULL);
		child_envp[envi++] = envar;
	}
	
	/* copy envars except for those in varlist */
	for (i=0; i<envar_count; i++) {
		int skip = 0;
		unsigned int n;
		for (n=0; varlist[n] != NULL; n++) {
			const char *varname = varlist[n];
			const char *start = strstr(envp[i], varname);
			if ((envp[i] == start) &&  (envp[i][strlen(varname)] == '=')) {
				skip = 1;
				break;
			}
		}
		if (!skip) {
			child_envp[envi++] = strdup(envp[i]);
		}
	}
	
	/* Actually run the hook script */
	retcode = spawnve(hook_script, child_argv, child_envp);
		
	/* Free all memory */
	for (i=0; child_envp[i] != NULL; i++) {
		free(child_envp[i]);
	}
	free(child_envp);
	for (i=0; child_argv[i] != NULL; i++) {
		free(child_argv[i]);
	}
	free(child_argv);

	/* And finally return to caller */
	if (retcode != 0) {
		fprintf(stderr, "Hook script returned error code %d (0x%x)\n",
			retcode, retcode);
		return 1;
	}
	return 0;
#endif
}
Esempio n. 11
0
int spawnv(int mode, const char *path, char *const argv[])
{
  return spawnve(mode, path, (char * const *)argv, environ);
}
Esempio n. 12
0
int
main(const int argc, const char *argv[], const char **envp)
{
  unsigned int i;

  FILE *out = stdout;
  int retcode;

  char *hook_env = getenv("GPHOTO_HOOK");
  char *filename = (hook_env!=NULL)?hook_env:"./test-hook.sh";
  
  /* We want this to be writable, so we explicitly define it as char[] */
  char params[7] = "params";
  char * const child_argv[] = {
    params,
    NULL,
  };
  
  /* envars not to copy */
  static const char * const varlist[] = {
    "ACTION", "ARGUMENT", NULL
  };

  unsigned int envi = 0;
  char **child_envp;

  /* count number of environment variables currently set */
  unsigned int envar_count;
  for (envar_count=0; envp[envar_count] != NULL; envar_count++) {
    /* printf("%3d: \"%s\"\n", envar_count, envp[envar_count]); */
  }
  
  fprintf(out, "Before spawn...\n");
  fflush(out);

  /* Initialize environment. Start with newly defined vars, then copy
   * all the existing ones.
   * Total amount of char* is
   *     number of existing envars (envar_count)
   *   + max number of new envars (2)
   *   + NULL list terminator (1)
   */
  child_envp = calloc(envar_count+2+1,sizeof(child_envp[0]));
  ASSERT(child_envp != NULL);

  /* own envars */
  child_envp[envi++] = alloc_envar("ARGUMENT", "/etc/shadow ;-P");
  child_envp[envi++] = alloc_envar("ACTION", "download");

  /* copy envars except for those in varlist */
  for (i=0; i<envar_count; i++) {
    int skip = 0;
    unsigned int n;
    for (n=0; varlist[n] != NULL; n++) {
      const char *varname = varlist[n];
      const char *start = strstr(envp[i], varname);
      if ((envp[i] == start) &&  (envp[i][strlen(varname)] == '=')) {
	skip = 1;
	break;
      }
    }
    if (!skip) {
      child_envp[envi] = strdup(envp[i]);
      ASSERT(child_envp[envi] != NULL);
      ++envi;
    }
  }

  /* Run the child program */
  retcode = spawnve(filename, child_argv, child_envp);

  fprintf(out, "After spawn, retcode=%d\n", retcode);
  fflush(out);

  /* Free memory */
  for (i=0; child_envp[i] != NULL; i++) {
    free(child_envp[i]);
  }
  free(child_envp);

  return retcode;
}
Esempio n. 13
0
/* replacement for execve() of kLIBC */
int
execve(const char *name, char * const *argv, char * const *envp)
{
	const char *exec_name;
	FILE *fp;
	char sign[2];
	char *rsp_argv[3];
	char *rsp_name_arg;
	int pid;
	int status;
	int fd;
	int rc;

	/*
	 * #! /bin/sh : append .exe
	 * extproc sh : search sh.exe in PATH
	 */
	exec_name = search_path(name, path, X_OK, NULL);
	if (!exec_name) {
		errno = ENOENT;
		return (-1);
	}

	/*-
	 * kLIBC execve() has problems when executing scripts.
	 * 1. it fails to execute a script if a directory whose name
	 *    is same as an interpreter exists in a current directory.
	 * 2. it fails to execute a script not starting with sharpbang.
	 * 3. it fails to execute a batch file if COMSPEC is set to a shell
	 *    incompatible with cmd.exe, such as /bin/sh.
	 * And ksh process scripts more well, so let ksh process scripts.
	 */
	errno = 0;
	if (!(fp = fopen(exec_name, "rb")))
		errno = ENOEXEC;

	if (!errno && fread(sign, 1, sizeof(sign), fp) != sizeof(sign))
		errno = ENOEXEC;

	if (fp && fclose(fp))
		errno = ENOEXEC;

	if (!errno &&
	    !((sign[0] == 'M' && sign[1] == 'Z') ||
	      (sign[0] == 'N' && sign[1] == 'E') ||
	      (sign[0] == 'L' && sign[1] == 'X')))
		errno = ENOEXEC;

	if (errno == ENOEXEC)
		return (-1);

	rsp_name_arg = make_response_file(argv);

	if (rsp_name_arg) {
		rsp_argv[0] = argv[0];
		rsp_argv[1] = rsp_name_arg;
		rsp_argv[2] = NULL;

		argv = rsp_argv;
	}

	pid = spawnve(P_NOWAIT, exec_name, argv, envp);

	afree(rsp_name_arg, ATEMP);

	if (pid == -1) {
		cleanup_temps();

		return (-1);
	}

	/* close all opened handles */
	for (fd = 0; fd < NUFILE; fd++) {
		if (fcntl(fd, F_GETFD) == -1)
			continue;

		close(fd);
	}

	while ((rc = waitpid(pid, &status, 0)) < 0 && errno == EINTR)
		/* nothing */;

	cleanup_temps();

	/* Is this possible? And is this right? */
	if (rc == -1)
		return (-1);

	if (WIFSIGNALED(status))
		_exit(ksh_sigmask(WTERMSIG(status)));

	_exit(WEXITSTATUS(status));
}
Esempio n. 14
0
int MYspawnve(int wait, char *script, char const **argv, char **envp)
{
    RTN_TYPE rtn = 0;
    int      pid = 0;
    
#if defined(INTEL_NT) || defined(INTEL_9X)
    static char *shell = NULL;
    
    if (NULL == shell)
    {
       //char const *local = findExec("sh.exe");
       char const *local = Tenv::appGet("SHELL");
       shell = new char [strlen(local) +1];
       strcpy(shell, local);
    }
    
    char  *(MYargv[1024]);
    char **p;
    char **q;
    
    MYargv[0] = shell;
    MYargv[1] = script;
    
    for (p = argv +1, q = MYargv +2; (NULL != *p); p++, q++)
       *q = *p;
       
    *q = NULL;

    if (MY_WAIT == wait)
       rtn = spawnve(_P_WAIT, shell, (const char* const*)MYargv, (const char* const*)envp);
    else 
       pid = spawnve(_P_NOWAIT, shell, (const char* const*)MYargv, (const char* const*)envp);
    
#else

#if defined(CYGWIN)  /* 006 */
    static char *shell = NULL;

    if (NULL == shell)
    {
       char const *local = Tenv::appGet("SHELL");
       shell = new char [strlen(local) +1];
       strcpy(shell, local);
    }

    char  *(MYargv[1024]);
    char **p;
    char **q;

    MYargv[0] = shell;
    MYargv[1] = script;

    for (p = argv +1, q = MYargv +2; (NULL != *p); p++, q++)
       *q = *p;

    *q = NULL;
    argv = MYargv;
    script = shell;
#endif
      
   if (0 == (pid = fork()))
   {
      // Child
      
      execve(script, (char**)argv, envp);
      printE("Executeable [%s] not found or not executable\n", script);
      exit(-1);
   }
   else if (-1 < pid)
   {
      // Parent
      
      if (MY_WAIT == wait)
      {
         waitpid(pid, &rtn, 0);
      }
   }
   else
   {
      // Fork fail
      printT("Fork failed [-1]\n");
      return (-1);
   }
   
#endif
      
    if (MY_WAIT == wait)
    {
        return(RTN_VALUE(rtn));
    }
    else
    {
        return(pid);
    }
}
Esempio n. 15
0
pid_t
spawnveg(const char* path, char* const argv[], char* const envv[], pid_t pgid)
{
	return spawnve(pgid ? P_DETACH : P_NOWAIT, path, argv, envv ? envv : environ);
}
Esempio n. 16
0
static unsigned __stdcall
babysitter (void *parameter)
{
  DBusBabysitter *sitter = (DBusBabysitter *) parameter;
  int fd;
  PING();
  _dbus_babysitter_ref (sitter);

  if (sitter->child_setup)
    {
      PING();
      (*sitter->child_setup) (sitter->user_data);
    }

  _dbus_verbose ("babysitter: spawning %s\n", sitter->executable);

  PING();
  if (sitter->envp != NULL)
    sitter->child_handle = (HANDLE) spawnve (P_NOWAIT, sitter->executable,
                           (const char * const *) sitter->argv,
                           (const char * const *) sitter->envp);
  else
    sitter->child_handle = (HANDLE) spawnv (P_NOWAIT, sitter->executable,
                                            (const char * const *) sitter->argv);

  PING();
  if (sitter->child_handle == (HANDLE) -1)
    {
      sitter->child_handle = NULL;
      sitter->have_spawn_errno = TRUE;
      sitter->spawn_errno = errno;
    }

  PING();
  SetEvent (sitter->start_sync_event);

  if (sitter->child_handle != NULL)
    {
      int ret;
      DWORD status;

      PING();
      WaitForSingleObject (sitter->child_handle, INFINITE);

      PING();
      ret = GetExitCodeProcess (sitter->child_handle, &status);

      sitter->child_status = status;
      sitter->have_child_status = TRUE;

      CloseHandle (sitter->child_handle);
      sitter->child_handle = NULL;
    }

#ifdef DBUS_BUILD_TESTS
  SetEvent (sitter->end_sync_event);
#endif

  PING();
  send (sitter->socket_to_main, " ", 1, 0);

  _dbus_babysitter_unref (sitter);

  return 0;
}
Esempio n. 17
0
//
// Download the next version of the game. If already downloaded, kick
// off the .exe to do the install.
//
void gh_main_installer (void)
{
#if defined WIN32 || defined __CYGWIN__
    //
    // e.g. save as goblinhack-1.15-windows.exe
    //
    string save_file_as =
                    "goblinhack-" +
                    tostring(GH_MAJOR_VERSION_NUMBER) +
                    "." +
                    tostring(GH_MINOR_VERSION_NUMBER + 1) +
                    "-windows.exe";
    //
    // e.g. download as
    //
    // http://prdownloads.sourceforge.net/sourceforge/goblinhack/goblinhack-1.15-windows.exe
    //
    string download_file_as =
                    "http://prdownloads.sourceforge.net/"
                    "sourceforge/goblinhack/"
                    "goblinhack-" +
                    tostring(GH_MAJOR_VERSION_NUMBER) +
                    "." +
                    tostring(GH_MINOR_VERSION_NUMBER + 1) +
                    "-windows.exe";

    //
    // curl -g -L
    //    --output goblinhack-1.15-windows.exe
    //    --url
    //    http://prdownloads.sourceforge.net/sourceforge/goblinhack/goblinhack-1.15-windows.exe
    //
    const char *curl_args[] = {
        "-g",
        "-L",
        "--output",
        save_file_as.c_str(),
        "--url",
        download_file_as.c_str(),
        0,
    };

    //
    // If the next version doesn't exist, download it now.
    //
    if (!gh_global::file_exists(save_file_as)) {
        //
        // Spawn curl as a child process to do the download in the background.
        //
        // If this fails then we're in trouble as we'll have a partial .exe.
        // Not worked out how to avoid this. Help!
        //
        spawnve(P_NOWAIT, "curl", curl_args, NULL);
    } else {
        //
        // Lets check the file looks to be of a sane size before calling
        // the installer. If it looks dodgy, < 10 Mb then just delete it
        // so we can download the file again.
        //
        if (gh_global::file_size(save_file_as) < 10 * 1000 * 1000) {
            //
            // Is too annoying to keep retrying all the time.
            //
            if ((rand() % 100) < 5) {
                gh_global::file_unlink(save_file_as);
            }

            return;
        }

        //
        // Replace the current process with the .exe to download.
        //
        int ret = MessageBox(NULL,
                             "I've downloaded the next version of Ghack!"
                             "    Install it now?",
                             download_file_as.c_str(), MB_YESNO);

        if (ret == IDYES) {
            const char *no_args[] = {
                0,
            };

            execve(save_file_as.c_str(), no_args, NULL);
            gh_global::file_unlink(save_file_as);
            return;
        }

        //
        // Ok, delete it instead? I'll just download it again anyway! 8)
        //
        ret = MessageBox(NULL,
                         "Should I delete the download file?",
                         download_file_as.c_str(), MB_YESNO);
        if (ret == IDYES) {
            gh_global::file_unlink(save_file_as);
        }
    }
#endif

#if defined __linux__
    pid_t childpid = fork();
    
    if (childpid >= 0) {
        //
        // Fork ok
        //
        if (childpid == 0) {
            //
            // Child
            //
        } else {
            //
            // Parent
            //
            return;
        }
    } else {
        perror("fork");
        exit(0);
    }

    //
    // e.g. save as goblinhack-1.15-linux-installer.bin
    //
    string save_file_as =
                    "goblinhack-" +
                    tostring(GH_MAJOR_VERSION_NUMBER) +
                    "." +
                    tostring(GH_MINOR_VERSION_NUMBER + 1) +
#ifdef __x86_64__
                    "-linux-x64-installer.bin";
#else
                    "-linux-installer.bin";
#endif
    //
    // e.g. download as
    //
    // http://prdownloads.sourceforge.net/sourceforge/goblinhack/goblinhack-1.15-linux-installer.bin
    //
    string download_file_as =
                    "http://prdownloads.sourceforge.net/"
                    "sourceforge/goblinhack/"
                    "goblinhack-" +
                    tostring(GH_MAJOR_VERSION_NUMBER) +
                    "." +
                    tostring(GH_MINOR_VERSION_NUMBER + 1) +
#ifdef __x86_64__
                    "-linux-x64-installer.bin";
#else
                    "-linux-installer.bin";
#endif

    //
    // curl -g -L
    //    --output goblinhack-1.15-linux-installer.bin
    //    --url
    //    http://prdownloads.sourceforge.net/sourceforge/goblinhack/goblinhack-1.15-linux-installer.bin
    //
    char *curl_args[] = {
        (char*)"-g",
        (char*)"-L",
        (char*)"--output",
        (char*)save_file_as.c_str(),
        (char*)"--url",
        (char*)download_file_as.c_str(),
        0,
    };

    //
    // If the next version doesn't exist, download it now.
    //
    if (!gh_global::file_exists(save_file_as)) {
        //
        // Spawn curl as a child process to do the download in the background.
        //
        // If this fails then we're in trouble as we'll have a partial installer.bin.
        // Not worked out how to avoid this. Help!
        //
        execve("/usr/bin/curl", curl_args, NULL);
        perror("execve");   /* execve() only returns on error */
    } else {
        //
        // Lets check the file looks to be of a sane size before calling
        // the installer. If it looks dodgy, < 10 Mb then just delete it
        // so we can download the file again.
        //
        if (gh_global::file_size(save_file_as) < 10 * 1000 * 1000) {
            //
            // Is too annoying to keep retrying all the time.
            //
            if ((rand() % 100) < 5) {
                gh_global::file_unlink(save_file_as);
            }

            exit(0);
        }

        if (system(("/bin/chmod +x " + save_file_as).c_str()) == -1) {
            perror("change permissions failed");
        }

        if (system(("./" + save_file_as).c_str()) == -1) {
            perror("execute installer failed");
        }

        gh_global::file_unlink(save_file_as);
    }

    exit(0);
#endif
}
Esempio n. 18
0
int spawnl(int mode, const char *path, const char *arg0, ...) {
    char		**argv;

    CVT_L2V(arg0, argv);
    return spawnve(mode, path, argv, 0);
}
Esempio n. 19
0
int execle(const char *path, const char *argv0, ... /*, const char **envp */)
{
  scan_ptr();
  return spawnve(P_OVERLAY, path, (char *const *)&argv0, (char *const *)ptr);
}