diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2016-10-26 21:13:00 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2016-10-26 21:13:00 (GMT) |
commit | da2e3d212171bbe64c1af39114fd067308656990 (patch) | |
tree | 9601f7ed15fa1394762124630c12a792bc073ec2 /funtools/util/xlaunch.c | |
parent | 76b109ad6d97d19ab835596dc70149ef379f3733 (diff) | |
download | blt-da2e3d212171bbe64c1af39114fd067308656990.zip blt-da2e3d212171bbe64c1af39114fd067308656990.tar.gz blt-da2e3d212171bbe64c1af39114fd067308656990.tar.bz2 |
rm funtools for update
Diffstat (limited to 'funtools/util/xlaunch.c')
-rw-r--r-- | funtools/util/xlaunch.c | 657 |
1 files changed, 0 insertions, 657 deletions
diff --git a/funtools/util/xlaunch.c b/funtools/util/xlaunch.c deleted file mode 100644 index 9f064d1..0000000 --- a/funtools/util/xlaunch.c +++ /dev/null @@ -1,657 +0,0 @@ -/* - * Copyright (c) 1999-2007 Smithsonian Astrophysical Observatory - */ - -#include <xlaunch.h> - -/* - *---------------------------------------------------------------------------- - * - * - * Private Routines and Data - * - * - *---------------------------------------------------------------------------- - */ - -static pid_t pid=0; - -#if HAVE_MINGW32==0 - -/* wait for child process to start, using waitpid() */ -#ifdef ANSI_FUNC -static int launch_pipes(int *pipes, int flag) -#else -static int launch_pipes(pipes, flag) - int *pipes; - int flag; -#endif -{ - int i; - char tbuf[SZ_LINE]; - if( pipes ){ - for(i=0; i<4; i++){ - pipes[i] = -1; - } - if( (pipe(&pipes[0]) < 0) || (pipe(&pipes[2]) < 0) ) return -1; - if( flag ){ -#if HAVE_SETENV - snprintf(tbuf, SZ_LINE-1, "%d,%d,%d,%d", - pipes[0], pipes[1], pipes[2], pipes[3]); - setenv("LAUNCH_PIPES", tbuf, 1); -#else - snprintf(tbuf, SZ_LINE-1, "LAUNCH_PIPES=%d,%d,%d,%d", - pipes[0], pipes[1], pipes[2], pipes[3]); - putenv(xstrdup(tbuf)); -#endif - } - } - return 0; -} - -#ifdef ANSI_FUNC -static int cleanup_pipes(int *pipes) -#else -static int cleanup_pipes(pipes) - int *pipes; -#endif -{ - if( pipes ){ - /* close child pipes */ - close(pipes[1]); - close(pipes[2]); - /* move parent write into slot 1 */ - pipes[1] = pipes[3]; - /* set unused pipes to impossible value */ - pipes[2] = -1; - pipes[3] = -1; - } - return 0; -} - -#if LAUNCH_USE_WAITPID -/* wait for child process to start, using waitpid() */ -#ifdef ANSI_FUNC -static int launch_waitstart(pid_t pid) -#else -static int launch_waitstart(pid) - pid_t pid; -#endif -{ - int i, got; - int status=0; - struct timeval tv; - /* wait up to LAUNCH_WAIT_TRIES millisec to make sure the child started, - but if we get an error, we can exit immediately */ - for(i=0; i<LAUNCH_WAIT_TRIES; i++){ - errno = 0; - got=waitpid(pid, &status, WNOHANG); - /* look for error termination */ - if( (got < 0) || ((got == 0) && xerrno) ){ - got = -1; - /* make sure status shows error */ - if( status == 0 ) - status = -1; - break; - } - /* look for normal termination */ - else if( got > 0 ){ - break; - } - /* no termination, sleep and wait some more */ - else{ - tv.tv_sec = 0; - tv.tv_usec = LAUNCH_WAIT_MSEC; - xselect(1, NULL, NULL, NULL, &tv); - } - } - /* no termination means the child is still running */ - if( got == 0 ) status = 0; - /* return the news */ - return status; -} -#endif - -/* - * standard unix version of launch: - * adapted from the system() code in: - * W. Richard Stevens - * "Advanced Programming in the Unix Environment" - * Addison-Wesley Publishing Co, 1992 - * p. 314 - */ -#ifdef ANSI_FUNC -static int launch_fork_exec(char *cmdstring, int attach, - char **stdfiles, int *pipes) -#else - static int launch_fork_exec(cmdstring, attach, stdfiles, pipes) - char *cmdstring; - int attach; - char **stdfiles; - int *pipes; -#endif -{ - int status; - int tpipes[4]; - struct sigaction ignore, saveintr, savequit; - sigset_t chldmask, savemask; -#if LAUNCH_USE_PIPE - int fd[2]; -#endif - - /* return false if no command is specified */ - if( !cmdstring || !*cmdstring ) return -1; - - ignore.sa_handler = SIG_IGN; /* ignore SIGINT and SIGQUIT */ - sigemptyset(&ignore.sa_mask); - ignore.sa_flags = 0; - if (sigaction(SIGINT, &ignore, &saveintr) < 0) - return -1; - if (sigaction(SIGQUIT, &ignore, &savequit) < 0) - return -1; - - sigemptyset(&chldmask); /* now block SIGCHLD */ - sigaddset(&chldmask, SIGCHLD); - if (sigprocmask(SIG_BLOCK, &chldmask, &savemask) < 0) - return -1; - -#if LAUNCH_USE_PIPE - /* open a pipe so parent can hear if the child fails to exec */ - if( !attach ){ - if( pipe(fd) < 0 ) - return -1; - xfcntl(fd[0], F_SETFD, FD_CLOEXEC); - xfcntl(fd[1], F_SETFD, FD_CLOEXEC); - } -#endif - - /* create temp ipc pipes if necessary */ - if( pipes ){ - if( launch_pipes(tpipes, 0) < 0 ) return -1; - } - - /* start new process */ - if( (pid = fork()) < 0 ){ -#if LAUNCH_USE_PIPE - if( !attach ){ - close(fd[0]); - close(fd[1]); - } -#endif - if( pipes ){ - close(tpipes[0]); - close(tpipes[1]); - close(tpipes[2]); - close(tpipes[3]); - } - status = -1; /* ERROR: probably out of processes */ - } else if( pid == 0 ){ /* child */ - int i, j, len; - char *argv[LAUNCH_ARGS+1]; - char *path=NULL; - char *s=NULL, *t=NULL; - - /* reset pipes, if necessary */ - if( pipes ){ - /* close parent's read/write pipes */ - close(tpipes[0]); - close(tpipes[3]); - /* change child's stdin/stdout to use the passed pipes to parent */ - dup2(tpipes[2], 0); close(tpipes[2]); - dup2(tpipes[1], 1); close(tpipes[1]); - } - - /* close and reopen stdio files, if necessary */ - if( stdfiles ){ - for(i=0; i<3; i++){ - if( stdfiles[i] ){ - close(i); - switch(i){ - case 0: - if( open(stdfiles[i], O_RDONLY) < 0){ - _exit(-1); - } - break; - case 1: - if( open(stdfiles[i], O_CREAT|O_WRONLY|O_TRUNC, 0600) < 0){ - _exit(-1); - } - break; - case 2: - /* if stderr is the same as stdout, just dup */ - if( stdfiles[1] && !strcmp(stdfiles[1], stdfiles[i]) ){ - dup(1); - } - else{ - if( open(stdfiles[i], O_CREAT|O_WRONLY|O_TRUNC, 0600) < 0){ - _exit(-1); - } - } - break; - } - } - } - } - - /* restore previous signal actions & reset signal mask, but only if - parent is waiting for completion (i.e., we are "attached") */ - if( attach ){ - sigaction(SIGINT, &saveintr, NULL); - sigaction(SIGQUIT, &savequit, NULL); - sigprocmask(SIG_SETMASK, &savemask, NULL); - } -#if LAUNCH_USE_PIPE - /* child closes reader -- only writes status */ - else{ - close(fd[0]); - } -#endif - - /* package up the arguments for new process */ - t = (char *)xstrdup(cmdstring); - for(i=0, s=(char *)strtok(t, " \t"); s; - i++, s=(char *)strtok(NULL," \t")){ - if( i < LAUNCH_ARGS ){ - /* save argument */ - argv[i] = xstrdup(s); - /* change back special char to spaces, if necessary */ - len = strlen(argv[i]); - for(j=0; j<len; j++){ - if( argv[i][j] == LAUNCH_SPACE){ - argv[i][j] = ' '; - } - } - argv[i+1] = NULL; - /* save program name */ - if( i == 0 ) path = argv[i]; - } - } - if( t ) xfree(t); -#ifndef HAVE_CYGWIN - /* this call is broken in cygwin */ - /* for unattached processes, start a new session (with new process id), - so that we do not inherit signals from parent (particularly SIGTERM) */ - if( !attach ) - setsid(); -#endif - /* start up the new program */ - if( execvp(path, argv) ){ - status = 127; -#if LAUNCH_USE_PIPE - if( !attach ){ - write(fd[1], &status, 4); - close(fd[1]); - } -#endif - _exit(status); /* exec error */ - } - } else { /* parent */ - /* wait for program termination from attached process */ - if( attach ){ - while( waitpid(pid, &status, 0) < 0 ){ - if( xerrno != EINTR ){ - status = -1; /* error other than EINTR from waitpid() */ - break; - } - } - } - else{ -#if LAUNCH_USE_WAITPID - status = launch_waitstart(pid); -#endif -#if LAUNCH_USE_PIPE - close(fd[1]); - if( read(fd[0], &status, 4) == 0 ){ - status = 0; - } - close(fd[0]); -#endif - } - } - - /* cleanup temp ipc pipes and move into user space */ - if( pipes ){ - cleanup_pipes(tpipes); - pipes[0] = tpipes[0]; - pipes[1] = tpipes[1]; - } - - /* restore previous signal actions & reset signal mask */ - if( sigaction(SIGINT, &saveintr, NULL) < 0 ) return -1; - if( sigaction(SIGQUIT, &savequit, NULL) < 0 ) return -1; - if( sigprocmask(SIG_SETMASK, &savemask, NULL) < 0 ) return -1; - - /* return the news */ - return status; -} - -#endif - -#if HAVE_POSIX_SPAWN - -#if defined(HAVE__NSGETENVIRON) && defined(HAVE_CRT_EXTERNS_H) -#include <crt_externs.h> -#define environ (*_NSGetEnviron()) -#else -extern char **environ; -#endif - -/* spawn calls POSIX posix_spawn */ -#ifdef ANSI_FUNC -static int launch_posix_spawn(char *cmdstring, int attach, - char **stdfiles, int *pipes) -#else - static int launch_posix_spawn(cmdstring, attach, stdfiles, pipes) - char *cmdstring; - int attach; - char **stdfiles; - int *pipes; -#endif -{ - int i, j, len; - int status=0; - int got=0; - int tpipes[4]; - char *argv[LAUNCH_ARGS+1]; - char *path=NULL; - char *s=NULL, *t=NULL; - posix_spawn_file_actions_t act; - posix_spawn_file_actions_t *pact=NULL; - - /* return false if no command is specified */ - if( !cmdstring || !*cmdstring ) - return -1; - - /* create temp ipc pipes if necessary */ - if( pipes ){ - if( launch_pipes(tpipes, 1) < 0 ) return -1; - } - - /* package up the arguments for new process */ - t = (char *)xstrdup(cmdstring); - for(i=0, s=(char *)strtok(t, " \t"); s; - i++, s=(char *)strtok(NULL," \t")){ - if( i < LAUNCH_ARGS ){ - /* save argument */ - argv[i] = xstrdup(s); - /* change back special char to spaces, if necessary */ - len = strlen(argv[i]); - for(j=0; j<len; j++){ - if( argv[i][j] == LAUNCH_SPACE){ - argv[i][j] = ' '; - } - } - /* last arg is always a NULL */ - argv[i+1] = NULL; - /* save program name */ - if( i == 0 ) path = argv[i]; - /* inc arg count */ - got++; - } - } - if( t ) xfree(t); - /* arrange stdfiles files, if necessary */ - if( stdfiles ){ - if( posix_spawn_file_actions_init(&act) != 0) - return -1; - /* stdin */ - if(stdfiles[0] && - posix_spawn_file_actions_addopen(&act, 0, stdfiles[0], O_RDONLY, 0)) - return -1; - /* stdout */ - if(stdfiles[1] && - posix_spawn_file_actions_addopen(&act, 1, stdfiles[1], O_CREAT|O_WRONLY|O_TRUNC, 0600)) - return -1; - /* stderr */ - if(stdfiles[2] && - posix_spawn_file_actions_addopen(&act, 2, stdfiles[2], O_CREAT|O_WRONLY|O_TRUNC, 0600)) - return -1; - pact = &act; - } - /* start the new process */ - if( (status = posix_spawnp(&pid, path, pact, NULL, argv, environ)) ) - return status; - /* wait for program termination from attached process */ - if( attach ){ - while( waitpid(pid, &status, 0) < 0 ){ - if( xerrno != EINTR ){ - status = -1; /* error other than EINTR from waitpid() */ - break; - } - } - } -#if BIG_DELAY_WHEN_USING_THIS - /* wait for child process to start */ - else{ - status = launch_waitstart(pid); - } -#endif - /* clean up */ - if( stdfiles ) posix_spawn_file_actions_destroy(&act); - /* cleanup temp ipc pipes and move into user space */ - if( pipes ){ - cleanup_pipes(tpipes); - pipes[0] = tpipes[0]; - pipes[1] = tpipes[1]; - } - for(i=0; i<got; i++){ - if( argv[i] ) xfree((char *)argv[i]); - } - /* return status */ - return status; -} - -#endif - -#if HAVE_SPAWNVP - -#ifdef ANSI_FUNC -static int launch_spawnvp(char *cmdstring, int attach, - char **stdfiles, int *pipes) -#else - static int launch_spawnvp(cmdstring, attach, stdfiles, pipes) - char *cmdstring; - int attach; - char **stdfiles; - int *pipes; -#endif -{ - int i, j; - int len; - int got; - int status; - int tpipes[4]; - char *argv[LAUNCH_ARGS+1]; - char *path=NULL; - char *s=NULL, *t=NULL; - struct timeval tv; - - /* return false if no command is specified */ - if( !cmdstring || !*cmdstring ) return -1; - - /* for now, we can't support stdfiles */ - if( stdfiles ) return -1; - - /* create temp ipc pipes if necessary */ - if( pipes ){ -#if HAVE_MINGW32==0 - if( launch_pipes(tpipes, 1) < 0 ) return -1; -#else - fprintf(stderr, "ERROR: launch_pipes() not available in mingw\n"); - exit(1); -#endif - } - - - /* package up the arguments for new process */ - t = (char *)xstrdup(cmdstring); - for(i=0, got=0, s=(char *)strtok(t, " \t"); s; - i++, s=(char *)strtok(NULL," \t")){ - if( i < LAUNCH_ARGS ){ - /* save argument */ - argv[i] = xstrdup(s); - /* change back special char to spaces, if necessary */ - len = strlen(argv[i]); - for(j=0; j<len; j++){ - if( argv[i][j] == LAUNCH_SPACE){ - argv[i][j] = ' '; - } - } - /* last arg is always a NULL */ - argv[i+1] = NULL; - /* save program name */ - if( i == 0 ) path = (char *)argv[i]; - /* inc arg count */ - got++; - } - } - if( t ) xfree(t); - if( attach ) - i = _P_WAIT; - else - i = _P_NOWAIT; - if((status = spawnvp(i, path, (void *)argv)) != -1){ - status = 0; - /* wait for child to start */ - tv.tv_sec = 0; - tv.tv_usec = LAUNCH_WAIT_MSEC; - xselect(1, NULL, NULL, NULL, &tv); - } - /* clean up */ - for(i=0; i<got; i++){ - if( argv[i] ) xfree((char *)argv[i]); - } - /* cleanup temp ipc pipes and move into user space */ - if( pipes ){ -#if HAVE_MINGW32==0 - cleanup_pipes(tpipes); - pipes[0] = tpipes[0]; - pipes[1] = tpipes[1]; -#else - fprintf(stderr, "ERROR: launch_pipes() not available in mingw\n"); - exit(1); -#endif - } - return status; -} - -#endif - -/* - *---------------------------------------------------------------------------- - * - * - * Public Routines and Data - * - * - *---------------------------------------------------------------------------- - */ - -/* - * - * LaunchPid() -- return pid of last launched process - * - */ -#ifdef ANSI_FUNC -pid_t LaunchPid(void) -#else -pid_t LaunchPid() -#endif -{ - return pid; -} - -#ifdef ANSI_FUNC -int Launch(char *cmdstring, int attach, char **stdfiles, int *pipes) -#else -int Launch(cmdstring, attach, stdfiles, piles) - char *cmdstring; - int attach; - char **stdfiles; - int *pipes; -#endif -{ - static int which_launch=0; - static int which_debug=0; - char *s=NULL; - - /* return false if no command is specified */ - if( !cmdstring || !*cmdstring ) return -1; - - /* sanity check: don't specify stdfiles and pipes simultaneously */ - if( stdfiles && pipes ){ - fprintf(stderr, - "ERROR: stdfiles and pipes are mutually exclusive in Launch()\n"); - return -1; - } - - /* if pipes are specified, we don't attach */ - if( pipes ) attach = 0; - - /* determine launch method */ - if( !which_launch ){ - which_launch = LAUNCH_DEFAULT_WHICH; - if( (s=getenv("LAUNCH_ROUTINE")) ){ - /* fork_exec */ - if( !strncasecmp(s, "f", 1) ){ - which_launch = 1; - if( *s == 'F' ) which_debug = 1; - } - /* posix_spawn */ - else if( !strncasecmp(s, "p", 1) ){ - which_launch = 2; - if( *s == 'P' ) which_debug = 1; - } - /* spawnvp */ - else if( !strncasecmp(s, "s", 1) ){ - which_launch = 3; - if( *s == 'S' ) which_debug = 1; - } - else if( *s == 'V' ) { - which_debug = 1; - } - } - } - /* call the correct launch method */ - switch(which_launch){ - case 1: -#if HAVE_MINGW32==0 - if( which_debug ) fprintf(stderr, "launch_fork_exec: %s\n", cmdstring); - return launch_fork_exec(cmdstring, attach, stdfiles, pipes); -#else - fprintf(stderr, "ERROR: fork_exec() not available on this host\n"); - exit(1); -#endif - break; - case 2: -#if HAVE_POSIX_SPAWN - if( which_debug ) fprintf(stderr, "launch_posix_spawn: %s\n", cmdstring); - return launch_posix_spawn(cmdstring, attach, stdfiles, pipes); -#else - fprintf(stderr, "ERROR: posix_spawn() not available on this host\n"); - exit(1); -#endif - break; - case 3: -#if HAVE_SPAWNVP - if( which_debug ) fprintf(stderr, "launch_spawnvp: %s\n", cmdstring); - return launch_spawnvp(cmdstring, attach, stdfiles, pipes); -#else - fprintf(stderr, "ERROR: spawnvp() not available on this host\n"); - exit(1); -#endif - break; - default: -#if HAVE_MINGW32==0 - if( which_debug ) fprintf(stderr, "launch_fork_exec: %s\n", cmdstring); - return launch_fork_exec(cmdstring, attach, stdfiles, pipes); -#else - fprintf(stderr, "ERROR: no launch techniques available on this host\n"); - exit(1); -#endif - break; - } - /* can't happen */ - return -1; -} - |