HB_FHANDLE hb_fsProcessOpen( const char * pszFilename, HB_FHANDLE * phStdin, HB_FHANDLE * phStdout, HB_FHANDLE * phStderr, HB_BOOL fDetach, HB_ULONG * pulPID ) { HB_FHANDLE hPipeIn [ 2 ] = { FS_ERROR, FS_ERROR }, hPipeOut[ 2 ] = { FS_ERROR, FS_ERROR }, hPipeErr[ 2 ] = { FS_ERROR, FS_ERROR }; HB_FHANDLE hResult = FS_ERROR; HB_BOOL fError = HB_FALSE; HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessOpen(%s, %p, %p, %p, %d, %p)", pszFilename, phStdin, phStdout, phStderr, fDetach, pulPID ) ); if( phStdin != NULL ) fError = ! hb_fsPipeCreate( hPipeIn ); if( ! fError && phStdout != NULL ) fError = ! hb_fsPipeCreate( hPipeOut ); if( ! fError && phStderr != NULL ) { if( phStdout == phStderr ) { hPipeErr[ 0 ] = hPipeOut[ 0 ]; hPipeErr[ 1 ] = hPipeOut[ 1 ]; } else fError = ! hb_fsPipeCreate( hPipeErr ); } if( ! fError ) { #if defined( HB_OS_WIN ) PROCESS_INFORMATION pi; STARTUPINFO si; DWORD dwFlags = 0; LPTSTR lpCommand = HB_CHARDUP( pszFilename ); # if ! defined( HB_OS_WIN_CE ) if( phStdin != NULL ) SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 1 ] ), HANDLE_FLAG_INHERIT, 0 ); if( phStdout != NULL ) SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 0 ] ), HANDLE_FLAG_INHERIT, 0 ); if( phStderr != NULL && phStdout != phStderr ) SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 0 ] ), HANDLE_FLAG_INHERIT, 0 ); # endif memset( &pi, 0, sizeof( pi ) ); memset( &si, 0, sizeof( si ) ); si.cb = sizeof( si ); # ifdef STARTF_USESTDHANDLES si.dwFlags = STARTF_USESTDHANDLES; # endif if( fDetach ) { # ifdef STARTF_USESHOWWINDOW si.dwFlags |= STARTF_USESHOWWINDOW; # endif si.wShowWindow = SW_HIDE; si.hStdInput = ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ); si.hStdOutput = ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ); si.hStdError = ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ); # ifdef DETACHED_PROCESS dwFlags |= DETACHED_PROCESS; # endif } else { si.hStdInput = phStdin ? ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ) : GetStdHandle( STD_INPUT_HANDLE ); si.hStdOutput = phStdout ? ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ) : GetStdHandle( STD_OUTPUT_HANDLE ); si.hStdError = phStderr ? ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ) : GetStdHandle( STD_ERROR_HANDLE ); } fError = ! CreateProcess( NULL, /* lpAppName */ lpCommand, NULL, /* lpProcessAttr */ NULL, /* lpThreadAttr */ TRUE, /* bInheritHandles */ dwFlags, /* dwCreationFlags */ NULL, /* lpEnvironment */ NULL, /* lpCurrentDirectory */ &si, &pi ); hb_fsSetIOError( ! fError, 0 ); hb_xfree( lpCommand ); if( ! fError ) { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pi.dwProcessId; CloseHandle( pi.hThread ); hResult = ( HB_FHANDLE ) pi.hProcess; } #elif defined( HB_OS_UNIX ) && \ ! defined( HB_OS_VXWORKS ) && ! defined( HB_OS_SYMBIAN ) pid_t pid = fork(); if( pid == -1 ) fError = HB_TRUE; else if( pid != 0 ) /* parent process */ { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } else /* child process */ { if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) ) { HB_FHANDLE hNull = open( "/dev/null", O_RDWR ); if( ! phStdin ) dup2( hNull, 0 ); if( ! phStdout ) dup2( hNull, 1 ); if( ! phStderr ) dup2( hNull, 2 ); if( hNull != FS_ERROR ) hb_fsClose( hNull ); } if( phStdin != NULL ) { dup2( hPipeIn[ 0 ], 0 ); hb_fsClose( hPipeIn[ 1 ] ); } if( phStdout != NULL ) { dup2( hPipeOut[ 1 ], 1 ); hb_fsClose( hPipeOut[ 0 ] ); } if( phStderr != NULL ) { dup2( hPipeErr[ 1 ], 2 ); if( phStdout != phStderr ) hb_fsClose( hPipeErr[ 0 ] ); } /* close all non std* handles */ { int iMaxFD, i; iMaxFD = sysconf( _SC_OPEN_MAX ); if( iMaxFD < 3 ) iMaxFD = 1024; for( i = 3; i < iMaxFD; ++i ) hb_fsClose( i ); } /* reset extended process attributes */ setuid( getuid() ); setgid( getgid() ); /* execute command */ { char ** argv; argv = hb_buildArgs( pszFilename ); # if defined( __WATCOMC__ ) execvp( argv[ 0 ], ( const char ** ) argv ); # else execvp( argv[ 0 ], argv ); # endif hb_freeArgs( argv ); exit( -1 ); } } #elif defined( HB_OS_OS2 ) || defined( HB_OS_WIN ) int hStdIn, hStdOut, hStdErr; char ** argv; int pid; hStdIn = dup( 0 ); hStdOut = dup( 1 ); hStdErr = dup( 2 ); if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) ) { HB_FHANDLE hNull = open( "NUL:", O_RDWR ); if( ! phStdin ) dup2( hNull, 0 ); if( ! phStdout ) dup2( hNull, 1 ); if( ! phStderr ) dup2( hNull, 2 ); if( hNull != FS_ERROR ) close( hNull ); } if( phStdin != NULL ) dup2( hPipeIn[ 0 ], 0 ); if( phStdout != NULL ) dup2( hPipeOut[ 1 ], 1 ); if( phStderr != NULL ) dup2( hPipeErr[ 1 ], 2 ); argv = hb_buildArgs( pszFilename ); #if defined( _MSC_VER ) || defined( __LCC__ ) || \ defined( __XCC__ ) || defined( __POCC__ ) pid = _spawnvp( _P_NOWAIT, argv[ 0 ], argv ); #elif defined( __MINGW32__ ) || defined( __WATCOMC__ ) pid = spawnvp( P_NOWAIT, argv[ 0 ], ( const char * const * ) argv ); #else pid = spawnvp( P_NOWAIT, argv[ 0 ], ( char * const * ) argv ); #endif hb_freeArgs( argv ); dup2( hStdIn, 0 ); close( hStdIn ); dup2( hStdOut, 1 ); close( hStdOut ); dup2( hStdErr, 2 ); close( hStdErr ); if( pid < 0 ) fError = HB_TRUE; else if( pid != 0 ) /* parent process */ { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } #else int iTODO; /* TODO: for given platform */ HB_SYMBOL_UNUSED( pszFilename ); HB_SYMBOL_UNUSED( fDetach ); HB_SYMBOL_UNUSED( pulPID ); hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); #endif } hb_fsSetIOError( ! fError, 0 ); if( hPipeIn[ 0 ] != FS_ERROR ) hb_fsClose( hPipeIn[ 0 ] ); if( hPipeIn[ 1 ] != FS_ERROR ) hb_fsClose( hPipeIn[ 1 ] ); if( hPipeOut[ 0 ] != FS_ERROR ) hb_fsClose( hPipeOut[ 0 ] ); if( hPipeOut[ 1 ] != FS_ERROR ) hb_fsClose( hPipeOut[ 1 ] ); if( phStdout != phStderr ) { if( hPipeErr[ 0 ] != FS_ERROR ) hb_fsClose( hPipeErr[ 0 ] ); if( hPipeErr[ 1 ] != FS_ERROR ) hb_fsClose( hPipeErr[ 1 ] ); } return hResult; }
int kmk_builtin_test(int argc, char **argv, char **envp, char ***ppapszArgvSpawn) { int res; char **argv_spawn; int i; g_progname = argv[0]; /* look for the '--', '--help' and '--version'. */ argv_spawn = NULL; for (i = 1; i < argc; i++) { if ( argv[i][0] == '-' && argv[i][1] == '-') { if (argv[i][2] == '\0') { argc = i; argv[i] = NULL; /* skip blank arguments (happens inside kmk) */ while (argv[++i]) { const char *psz = argv[i]; while (isspace(*psz)) psz++; if (*psz) break; } argv_spawn = &argv[i]; break; } if (!strcmp(argv[i], "--help")) return usage(argv[0]); if (!strcmp(argv[i], "--version")) return kbuild_version(argv[0]); } } /* are we '['? then check for ']'. */ if (strcmp(g_progname, "[") == 0) { /** @todo should skip the path in g_progname */ if (strcmp(argv[--argc], "]")) return errx(1, "missing ]"); argv[argc] = NULL; } /* evaluate the expression */ if (argc < 2) res = 1; else { t_wp = &argv[1]; res = oexpr(t_lex(*t_wp)); if (res != -42 && *t_wp != NULL && *++t_wp != NULL) res = syntax(*t_wp, "unexpected operator"); if (res == -42) return 1; /* don't mix syntax errors with the argv_spawn ignore */ res = !res; } /* anything to execute on success? */ if (argv_spawn) { if (res != 0 || !argv_spawn[0]) res = 0; /* ignored */ else { #ifdef kmk_builtin_test /* try exec the specified process */ # if defined(_MSC_VER) res = _spawnvp(_P_WAIT, argv_spawn[0], argv_spawn); if (res == -1) res = err(1, "_spawnvp(_P_WAIT,%s,..)", argv_spawn[0]); # else execvp(argv_spawn[0], argv_spawn); res = err(1, "execvp(%s,..)", argv_spawn[0]); # endif #else /* in kmk */ /* let job.c spawn the process, make a job.c style argv_spawn copy. */ char *buf, *cur, **argv_new; size_t sz = 0; int argc_new = 0; while (argv_spawn[argc_new]) { size_t len = strlen(argv_spawn[argc_new]) + 1; sz += (len + sizeof(void *) - 1) & ~(sizeof(void *) - 1); argc_new++; } argv_new = xmalloc((argc_new + 1) * sizeof(char *)); buf = cur = xmalloc(sz); for (i = 0; i < argc_new; i++) { size_t len = strlen(argv_spawn[i]) + 1; argv_new[i] = memcpy(cur, argv_spawn[i], len); cur += (len + sizeof(void *) - 1) & ~(sizeof(void *) - 1); } argv_new[i] = NULL; *ppapszArgvSpawn = argv_new; res = 0; #endif /* in kmk */ } } return res; }
void StartServer(int argc,char **argv) { int pid,time_to_run = false; time_t now = time(NULL); #ifdef HAVE_PTHREAD_H pthread_t tid = 1; #else int tid = -1 #endif Banner("Starting server"); if ((!NO_FORK) && (fork() != 0)) { snprintf(OUTPUT,CF_BUFSIZE*2,"cfexecd starting %.24s\n",ctime(&now)); CfLog(cfinform,OUTPUT,""); exit(0); } if (!ONCE) { if (!GetLock("cfexecd","execd",0,0,VUQNAME,now)) { snprintf(OUTPUT,CF_BUFSIZE*2,"cfexecd: Couldn't get a lock -- exists or too soon: IfElapsed %d, ExpireAfter %d\n",0,0); CfLog(cfverbose,OUTPUT,""); return; } SaveExecLock(); } if (!NO_FORK) { ActAsDaemon(0); } WritePID("cfexecd.pid"); signal(SIGINT,(void *)ExitCleanly); signal(SIGTERM,(void *)ExitCleanly); signal(SIGHUP,SIG_IGN); signal(SIGPIPE,SIG_IGN); signal(SIGUSR1,HandleSignal); signal(SIGUSR2,HandleSignal); umask(077); if (ONCE) { GetCfStuff(); LocalExec((void *)0); } else { char **nargv; int i; /* * Append --once option to our arguments for spawned monitor process. */ nargv = malloc(sizeof(char *) * (argc+2)); for (i = 0; i < argc; i++) { nargv[i] = argv[i]; } nargv[i++] = strdup("--once"); nargv[i++] = NULL; GetCfStuff(); while (true) { time_to_run = ScheduleRun(); if (time_to_run) { if (!GetLock("cfd","exec",CF_EXEC_IFELAPSED,CF_EXEC_EXPIREAFTER,VUQNAME,time(NULL))) { snprintf(OUTPUT,CF_BUFSIZE*2,"cfexecd: Couldn't get exec lock -- exists or too soon: IfElapsed %d, ExpireAfter %d\n",CF_EXEC_IFELAPSED,CF_EXEC_EXPIREAFTER); CfLog(cfverbose,OUTPUT,""); continue; } GetCfStuff(); #ifdef NT /* * Spawn a separate process - spawn will work if the cfexecd binary * has changed (where cygwin's fork() would fail). */ Debug("Spawning %s\n", nargv[0]); pid = _spawnvp((int)_P_NOWAIT,nargv[0],nargv); if (pid < 1) { CfLog(cfinform,"Can't spawn run","spawnvp"); } #endif #ifndef NT #if (defined HAVE_LIBPTHREAD || defined BUILDTIN_GCC_THREAD) pthread_attr_init(&PTHREADDEFAULTS); pthread_attr_setdetachstate(&PTHREADDEFAULTS,PTHREAD_CREATE_DETACHED); #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE pthread_attr_setstacksize(&PTHREADDEFAULTS,(size_t)2048*1024); #endif if (pthread_create(&tid,&PTHREADDEFAULTS,LocalExec,(void *)1) != 0) { CfLog(cfinform,"Can't create thread!","pthread_create"); LocalExec((void *)1); } pthread_attr_destroy(&PTHREADDEFAULTS); #else LocalExec((void *)1); #endif #endif ReleaseCurrentLock(); } } } }
void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_08_bad() { char * data; char dataBuffer[100] = ""; data = dataBuffer; if(staticReturnsTrue()) { { #ifdef _WIN32 WSADATA wsaData; int wsaDataInit = 0; #endif int recvResult; struct sockaddr_in service; char *replace; SOCKET connectSocket = INVALID_SOCKET; size_t dataLen = strlen(data); do { #ifdef _WIN32 if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { break; } wsaDataInit = 1; #endif /* POTENTIAL FLAW: Read data using a connect socket */ connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (connectSocket == INVALID_SOCKET) { break; } memset(&service, 0, sizeof(service)); service.sin_family = AF_INET; service.sin_addr.s_addr = inet_addr(IP_ADDRESS); service.sin_port = htons(TCP_PORT); if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) { break; } /* Abort on error or the connection was closed, make sure to recv one * less char than is in the recv_buf in order to append a terminator */ /* Abort on error or the connection was closed */ recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); if (recvResult == SOCKET_ERROR || recvResult == 0) { break; } /* Append null terminator */ data[dataLen + recvResult / sizeof(char)] = '\0'; /* Eliminate CRLF */ replace = strchr(data, '\r'); if (replace) { *replace = '\0'; } replace = strchr(data, '\n'); if (replace) { *replace = '\0'; } } while (0); if (connectSocket != INVALID_SOCKET) { CLOSE_SOCKET(connectSocket); } #ifdef _WIN32 if (wsaDataInit) { WSACleanup(); } #endif } } { char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG2, COMMAND_ARG3, NULL}; /* spawnvp - searches for the location of the command among * the directories specified by the PATH environment variable */ /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ _spawnvp(_P_WAIT, COMMAND_INT, args); } }
int main(int argc, char **argv){ char *prog; int i; int debug; int argstart=-1; float delay_time=0.0; int cpu_usage, cpu_usage_max=25; int mem_usage, mem_usage_max=75; #ifdef pp_LINUX char command_buffer[1024]; char user_path[1024]; FILE *stream=NULL; #endif #ifdef pp_OSX char command_buffer[1024]; char user_path[1024]; #endif int itime; char *arg; char *command; #ifdef pp_LINUX hostlistfile=NULL; host=NULL; strcpy(user_path,""); sprintf(pid,"%i",getpid()); #endif #ifdef pp_OSX sprintf(pid,"%i",getpid()); #endif debug=0; prog=argv[0]; if(argc==1){ version(); return 1; } for(i=1;i<argc;i++){ int lenarg; arg=argv[i]; lenarg=strlen(arg); if(arg[0]=='-'){ if(lenarg>1){ switch(arg[1]){ case 'd': if(strlen(arg)<=2||strcmp(arg,"-debug")!=0){ i++; if(i<argc){ arg=argv[i]; sscanf(arg,"%f",&delay_time); if(delay_time<0.0)delay_time=0.0; } } else{ debug=1; } break; case 'h': #ifdef pp_LINUX if(strlen(arg)<=2||strcmp(arg,"-hosts")!=0){ #endif usage(prog); return 1; #ifdef pp_LINUX } else{ i++; if(i<argc){ arg=argv[i]; hostlistfile=malloc(strlen(arg)+1); strcpy(hostlistfile,arg); } } break; case 'p': i++; if(i<argc){ arg=argv[i]; if(strlen(arg)>0){ strcpy(user_path,arg); } } break; #endif case 'm': i++; if(i<argc){ arg=argv[i]; sscanf(arg,"%i",&mem_usage_max); if(mem_usage_max<25)mem_usage_max=25; if(mem_usage_max>90)mem_usage_max=90; } break; case 'u': i++; if(i<argc){ arg=argv[i]; sscanf(arg,"%i",&cpu_usage_max); if(cpu_usage_max<25)cpu_usage_max=25; if(cpu_usage_max>100)cpu_usage_max=100; } break; case 'v': version(); return 1; default: printf("Unknown option: %s\n",arg); usage(prog); return 1; } } } else{ argstart=i; break; } } #ifdef pp_LINUX nhostinfo=0; if(hostlistfile!=NULL){ stream=fopen(hostlistfile,"r"); } if(hostlistfile!=NULL&&stream!=NULL){ char buffer[255]; while(!feof(stream)){ if(fgets(buffer,255,stream)==NULL)break; nhostinfo++; } if(nhostinfo>0){ hostdata *hd; hostinfo=malloc(nhostinfo*sizeof(hostdata)); hd = hostinfo; rewind(stream); while(!feof(stream)){ char *hostname; if(fgets(buffer,255,stream)==NULL)break; trim(buffer); hostname=malloc(strlen(buffer)+1); strcpy(hostname,buffer); hd->hostname=hostname; hd->ncores=get_host_ncores(hostname); printf("host: %s ncores=%i\n",hostname,hd->ncores); hd++; } } } if(stream!=NULL)fclose(stream); #endif if(argstart<0)return 0; itime = delay_time*1000; if(itime>0){ Sleep(itime); } #ifdef WIN32 GetSystemTimesAddress(); cpu_usage=cpuusage(); mem_usage=memusage(); Sleep(200); cpu_usage=cpuusage(); mem_usage=memusage(); while(cpu_usage>cpu_usage_max||mem_usage>mem_usage_max){ Sleep(1000); cpu_usage=cpuusage(); mem_usage=memusage(); } command=argv[argstart]; _spawnvp(_P_NOWAIT,command, argv+argstart); #endif #ifdef pp_LINUXOSX strcpy(command_buffer,""); if(hostinfo==NULL){ cpu_usage=cpuusage(); mem_usage=memusage(); Sleep(200); cpu_usage=cpuusage(); mem_usage=memusage(); host=NULL; while(cpu_usage>cpu_usage_max||mem_usage>mem_usage_max){ Sleep(1000); cpu_usage=cpuusage(); mem_usage=memusage(); } } else{ int doit=0; while(doit==0){ for(i=0;i<nhostinfo;i++){ hostdata *hd; float fusage; hd = hostinfo + i; host = hd->hostname; cpu_usage=cpuusage_host(host,hd->ncores); fusage=(float)cpu_usage/255.0; if(debug==1)printf("host: %s cpu_usage=%f\n",host,fusage); if(cpu_usage<cpu_usage_max){ if(debug==1)printf(" host %s is now free\n",host); doit=1; if(strlen(user_path)==0){ getcwd(user_path,1024); } strcat(command_buffer,"ssh "); strcat(command_buffer,host); strcat(command_buffer," \"( cd "); strcat(command_buffer,user_path); strcat(command_buffer,";"); break; } } if(doit==0)Sleep(1000); } } for(i=argstart;i<argc;i++){ arg=argv[i]; strcat(command_buffer,arg); if(i<argc-1){ strcat(command_buffer," "); } } if(nhostinfo>0)strcat(command_buffer,")\""); strcat(command_buffer,"&"); system(command_buffer); #endif return 0; }
static int hb_fsProcessExec( const char * pszFileName, HB_FHANDLE hStdin, HB_FHANDLE hStdout, HB_FHANDLE hStderr ) { int iResult = FS_ERROR; HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessExec(%s, %p, %p, %p)", pszFileName, ( void * ) ( HB_PTRUINT ) hStdin, ( void * ) ( HB_PTRUINT ) hStdout, ( void * ) ( HB_PTRUINT ) hStderr ) ); #if defined( HB_OS_WIN_CE ) { LPTSTR lpAppName, lpParams; HB_BOOL fError; HB_SYMBOL_UNUSED( hStdin ); HB_SYMBOL_UNUSED( hStdout ); HB_SYMBOL_UNUSED( hStderr ); hb_getCommand( pszFileName, &lpAppName, &lpParams ); hb_vmUnlock(); fError = ! CreateProcess( lpAppName, /* lpAppName */ lpParams, /* lpCommandLine */ NULL, /* lpProcessAttr */ NULL, /* lpThreadAttr */ FALSE, /* bInheritHandles */ 0, /* dwCreationFlags */ NULL, /* lpEnvironment */ NULL, /* lpCurrentDirectory */ NULL, /* lpStartupInfo */ NULL ); /* lpProcessInformation */ hb_fsSetIOError( ! fError, 0 ); if( ! fError ) iResult = 0; hb_vmLock(); if( lpAppName ) hb_xfree( lpAppName ); if( lpParams ) hb_xfree( lpParams ); } #elif defined( HB_OS_DOS ) || defined( HB_OS_WIN ) || defined( HB_OS_OS2 ) || \ defined( HB_OS_UNIX ) { int iStdIn, iStdOut, iStdErr; char ** argv; argv = hb_buildArgs( pszFileName ); hb_vmUnlock(); iStdIn = iStdOut = iStdErr = FS_ERROR; if( hStdin != FS_ERROR ) { iStdIn = dup( 0 ); dup2( hStdin, 0 ); } if( hStdout != FS_ERROR ) { iStdOut = dup( 1 ); dup2( hStdout, 1 ); } if( hStderr != FS_ERROR ) { iStdErr = dup( 2 ); dup2( hStderr, 2 ); } #if defined( HB_OS_UNIX ) && ! defined( HB_OS_VXWORKS ) && ! defined( HB_OS_SYMBIAN ) { pid_t pid = fork(); if( pid == 0 ) { /* close all non std* handles */ { int iMaxFD, i; iMaxFD = sysconf( _SC_OPEN_MAX ); if( iMaxFD < 3 ) iMaxFD = 1024; for( i = 3; i < iMaxFD; ++i ) hb_fsClose( i ); } /* reset extended process attributes */ ( void ) setuid( getuid() ); ( void ) setgid( getgid() ); /* execute command */ execvp( argv[ 0 ], argv ); exit( -1 ); } else if( pid != -1 ) { int iStatus; HB_FAILURE_RETRY( iResult, waitpid( pid, &iStatus, 0 ) ); #ifdef ERESTARTSYS if( iResult < 0 && errno != ERESTARTSYS ) #else if( iResult < 0 ) #endif iResult = -2; else if( iResult == 0 ) iResult = -1; else iResult = WIFEXITED( iStatus ) ? WEXITSTATUS( iStatus ) : 0; } else hb_fsSetIOError( HB_FALSE, 0 ); } #else # if defined( _MSC_VER ) || defined( __LCC__ ) || \ defined( __XCC__ ) || defined( __POCC__ ) iResult = _spawnvp( _P_WAIT, argv[ 0 ], argv ); # elif defined( __MINGW32__ ) || defined( __WATCOMC__ ) iResult = spawnvp( P_WAIT, argv[ 0 ], ( const char * const * ) argv ); # else iResult = spawnvp( P_WAIT, argv[ 0 ], ( char * const * ) argv ); # endif hb_fsSetIOError( iResult >= 0, 0 ); #endif if( iStdIn != FS_ERROR ) { dup2( iStdIn, 0 ); hb_fsCloseRaw( iStdIn ); } if( iStdOut != FS_ERROR ) { dup2( iStdOut, 1 ); hb_fsCloseRaw( iStdOut ); } if( iStdErr != FS_ERROR ) { dup2( iStdErr, 2 ); hb_fsCloseRaw( iStdErr ); } hb_vmLock(); hb_freeArgs( argv ); } #else { int iTODO; /* TODO: for given platform */ HB_SYMBOL_UNUSED( pszFileName ); HB_SYMBOL_UNUSED( hStdin ); HB_SYMBOL_UNUSED( hStdout ); HB_SYMBOL_UNUSED( hStderr ); hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); } #endif return iResult; }
static int make_ofile(int kflag, char **Cflags, char *o_file, char *c_file) { #if !defined(USE_WIN32) int pid; #endif struct stat stat_c, stat_o; static char *cnp = (char *)NULL; char *av[64]; /* hope that this is enough! */ int status; int ac, i; /* FIRSTLY, ENSURE THAT THE SOURCEFILE EXISTS AND NEEDS RECOMPILING */ if(stat(c_file, &stat_c) == -1) { fprintf(stderr,"%s: cannot find sourcefile %s\n",argv0,c_file); ++nerrors; return(-1); } if(stat(o_file, &stat_o) == 0 && stat_c.st_mtime <= stat_o.st_mtime) return(0); #if CHECK_RECEIVE_SPELLING if(spell_check(c_file) == FALSE) return(-1); #endif if(cnp == (char *)NULL) { cnp = find_cnetfile("cnet.h", TRUE, TRUE); if(vflag) fprintf(stderr,"using include directory \"%s\"\n", cnp); } #if defined(USE_WIN32) ac = 0; av[ac++] = "CL"; av[ac++] = OS_DEFINE; av[ac++] = "/DHAVE_LONG_LONG=1"; sprintf(chararray, "/DSIZEOF_INT=%d", sizeof(int)); av[ac++] = strdup(chararray); sprintf(chararray, "/DSIZEOF_LONG=%d", sizeof(long)); av[ac++] = strdup(chararray); sprintf(chararray, "/I%s", cnp); av[ac++] = strdup(chararray); while(*Cflags) /* add C compiler switches */ av[ac++] = *Cflags++; av[ac++] = "/c"; sprintf(chararray, "/Fo%s", o_file); av[ac++] = strdup(chararray); if(!vflag) av[ac++] = "/NOLOGO"; av[ac++] = c_file; av[ac ] = NULL; if(dflag) { fputs(av[0], stderr); for(i=1 ; i<ac ; i++) fprintf(stderr," %s",av[i]); fputc('\n',stderr); } else fprintf(stderr,"compiling %s\n", c_file); status = _spawnvp(_P_WAIT, av[0], &av[1]); if(status != 0) { if(status == -1) fprintf(stderr,"%s: spawn of %s unsuccessful: %s\n", argv0,av[0],_sys_errlist[(int)errno]); exit(1); } #else switch (pid = fork()) { case -1 : fprintf(stderr,"%s: cannot fork\n",argv0); exit(1); break; case 0 : ac = 0; #if USE_GCC_COMPILER av[ac++] = findenv("CNETGCC", CNETGCC); av[ac++] = "gcc"; if(!kflag) /* not using "old" K&R C */ av[ac++] = "-ansi"; #if GCC_WERROR_WANTED av[ac++] = "-Werror"; #endif #if GCC_WALL_WANTED av[ac++] = "-Wall"; #endif #else av[ac++] = findenv("CNETCC", CNETCC); av[ac++] = "cc"; #endif ac = add_compile_args(ac, av, kflag); av[ac++] = OS_DEFINE; #if HAVE_LONG_LONG av[ac++] = "-DHAVE_LONG_LONG=1"; #endif sprintf(chararray, "-DSIZEOF_INT=%d", sizeof(int)); av[ac++] = strdup(chararray); sprintf(chararray, "-DSIZEOF_LONG=%d", sizeof(long)); av[ac++] = strdup(chararray); while(*Cflags) /* add C compiler switches */ av[ac++] = *Cflags++; sprintf(chararray, "-I%s", cnp); av[ac++] = strdup(chararray); av[ac++] = "-c"; av[ac++] = "-o"; av[ac++] = o_file; av[ac++] = c_file; av[ac ] = NULL; if(dflag) { fputs(av[0], stderr); for(i=2 ; i<ac ; i++) fprintf(stderr," %s",av[i]); fputc('\n',stderr); } else fprintf(stderr,"compiling %s\n", c_file); execvp(av[0], &av[1]); fprintf(stderr,"%s: cannot exec %s\n",argv0,av[0]); exit(1); break; default : while(wait(&status) != pid) ; if(status != 0) exit(1); break; } #endif return(0); }
/* spawn a subprocess PROGNAME and pass it the arguments ARGV[] ARGV must be a NULL-terminated array of strings. Also pass it two arrays of strings: PIPE_TO_PROC[2] and PIPE_FROM_PROC[2]. These are going to be the arrays of fds for the communication pipes This function is protected from being called by more than one thread at a time by a mutex: the context is passed in for error handling. */ static int xsb_spawn (CTXTdeclc char *progname, char *argv[], int callno, int pipe_to_proc[], int pipe_from_proc[],int pipe_from_stderr[], FILE *toprocess_fptr, FILE *fromprocess_fptr, FILE *fromproc_stderr_fptr) { int pid; int stdin_saved, stdout_saved, stderr_saved; static char shell_command[MAX_CMD_LEN]; if ( (pipe_to_proc != NULL) && PIPE(pipe_to_proc) < 0 ) { /* can't open pipe to process */ xsb_warn("[SPAWN_PROCESS] Can't open pipe for subprocess input"); return PIPE_TO_PROC_FAILED; } if ( (pipe_from_proc != NULL) && PIPE(pipe_from_proc) < 0 ) { /* can't open pipe from process */ xsb_warn("[SPAWN_PROCESS] Can't open pipe for subprocess output"); return PIPE_FROM_PROC_FAILED; } if ( (pipe_from_stderr != NULL) && PIPE(pipe_from_stderr) < 0 ) { /* can't open stderr pipe from process */ xsb_warn("[SPAWN_PROCESS] Can't open pipe for subprocess errors"); return PIPE_FROM_PROC_FAILED; } /* The following is due to the awkwardness of windoze process creation. We commit this atrocity in order to be portable between Unix and Windows. 1. Save stdio of the parent process. 2. Redirect main process stdio to the pipes. 3. Spawn subprocess. The subprocess inherits the redirected I/O 4. Restore the original stdio for the parent process. On the bright side, this trick allowed us to cpature the I/O streams of the shell commands invoked by system() */ /* save I/O */ stdin_saved = dup(fileno(stdin)); stdout_saved = dup(fileno(stdout)); stderr_saved = dup(fileno(stderr)); if ((fileno(stdin) < 0) || (stdin_saved < 0)) xsb_warn("[SPAWN_PROCESS] Bad stdin=%d; stdin closed by mistake?", fileno(stdin)); if ((fileno(stdout) < 0) || (stdout_saved < 0)) xsb_warn("[SPAWN_PROCESS] Bad stdout=%d; stdout closed by mistake?", fileno(stdout)); if ((fileno(stderr) < 0) || (stderr_saved < 0)) xsb_warn("[SPAWN_PROCESS] Bad stderr=%d; stderr closed by mistake?", fileno(stderr)); if (pipe_to_proc != NULL) { /* close child stdin, bind it to the reading part of pipe_to_proc */ if (dup2(pipe_to_proc[0], fileno(stdin)) < 0) { xsb_warn("[SPAWN_PROCESS] Can't connect pipe %d to subprocess stdin", pipe_to_proc[0]); return PIPE_TO_PROC_FAILED; } close(pipe_to_proc[0]); /* close the parent read end of pipe */ } /* if stdin must be captured in an existing I/O port -- do it */ if (toprocess_fptr != NULL) if (dup2(fileno(toprocess_fptr), fileno(stdin)) < 0) { xsb_warn("[SPAWN_PROCESS] Can't connect stream %d to subprocess stdin", fileno(toprocess_fptr)); return PIPE_TO_PROC_FAILED; } if (pipe_from_proc != NULL) { /* close child stdout, bind it to the write part of pipe_from_proc */ if (dup2(pipe_from_proc[1], fileno(stdout)) < 0) { xsb_warn("[SPAWN_PROCESS] Can't connect subprocess stdout to pipe %d", pipe_from_proc[1]); return PIPE_TO_PROC_FAILED; } close(pipe_from_proc[1]); /* close the parent write end of pipe */ } /* if stdout must be captured in an existing I/O port -- do it */ if (fromprocess_fptr != NULL) if (dup2(fileno(fromprocess_fptr), fileno(stdout)) < 0) { xsb_warn("[SPAWN_PROCESS] Can't connect subprocess stdout to stream %d", fileno(fromprocess_fptr)); return PIPE_TO_PROC_FAILED; } if (pipe_from_stderr != NULL) { /* close child stderr, bind it to the write part of pipe_from_proc */ if (dup2(pipe_from_stderr[1], fileno(stderr)) < 0) { xsb_warn("[SPAWN_PROCESS] Can't connect subprocess stderr to pipe %d", pipe_from_stderr[1]); return PIPE_TO_PROC_FAILED; } close(pipe_from_stderr[1]); /* close the parent write end of pipe */ } /* if stderr must be captured in an existing I/O port -- do it */ if (fromproc_stderr_fptr != NULL) if (dup2(fileno(fromproc_stderr_fptr), fileno(stderr)) < 0) { xsb_warn("[SPAWN_PROCESS] Can't connect subprocess stderr to stream %d", fileno(fromproc_stderr_fptr)); return PIPE_TO_PROC_FAILED; } if (callno == SPAWN_PROCESS) { #ifdef WIN_NT static char bufQuoted[MAX_CMD_LEN + 2*(MAX_SUBPROC_PARAMS + 2)]; const char * argvQuoted[MAX_SUBPROC_PARAMS + 2]; char * argq = bufQuoted; char * arge = bufQuoted + sizeof(bufQuoted); char ** argp = argv; size_t len = 0; int i; for (i = 0; i < MAX_SUBPROC_PARAMS + 2; ++i) { if (*argp && (argq + (len = strlen(*argp)) + 4 < arge)) { argvQuoted[i] = argq; *argq++ = '"'; strncpy(argq, *argp, len); argq += len; *argq++ = '"'; *argq++ = '\0'; ++argp; } else { *argq = '\0'; argvQuoted[i] = 0; break; } } pid = (int)_spawnvp(P_NOWAIT, progname, argvQuoted); // should pid be Integer? #else pid = fork(); #endif if (pid < 0) { /* failed */ xsb_warn("[SPAWN_PROCESS] Can't fork off subprocess"); return pid; } else if (pid == 0) { /* child process */ /* Close the writing side of child's in-pipe. Must do this or else the child won't see EOF when parent closes its end of this pipe. */ if (pipe_to_proc != NULL) close(pipe_to_proc[1]); /* Close the reading part of child's out-pipe and stderr-pipe */ if (pipe_from_proc != NULL) close(pipe_from_proc[0]); if (pipe_from_stderr != NULL) close(pipe_from_stderr[0]); #ifndef WIN_NT /* Unix: must exec */ execvp(progname, argv); /* if we ever get here, this means that invocation of the process has failed */ exit(SUB_PROC_FAILED); #endif } } else { /* SHELL command */ /* no separator */ concat_array(CTXTc argv, "", shell_command, MAX_CMD_LEN); pid = system(shell_command); } /* main process continues */ /* duplicate saved copies of stdio fds back into main process stdio */ if (dup2(stdin_saved, fileno(stdin)) < 0) { perror("SPAWN_PROCESS"); close(stdin_saved); close(stdout_saved); close(stderr_saved); return PIPE_TO_PROC_FAILED; } if (dup2(stdout_saved, fileno(stdout)) < 0) { perror("SPAWN_PROCESS"); close(stdin_saved); close(stdout_saved); close(stderr_saved); return PIPE_TO_PROC_FAILED; } if (dup2(stderr_saved, fileno(stderr)) < 0) { perror("SPAWN_PROCESS"); close(stdin_saved); close(stdout_saved); close(stderr_saved); return PIPE_TO_PROC_FAILED; } close(stdin_saved); close(stdout_saved); close(stderr_saved); return pid; }
void CSerial::WaitForConnection() { struct sockaddr_in Address; socklen_t nAddressSize = sizeof(struct sockaddr_in); const char* telnet_options = "%c%c%c"; char buffer[8]; char s[1000]; char* nargv = s; int i = 0; #if !defined(LS_SLAVE) char s2[200]; char* argv[20]; strncpy(s, myCfg->get_text_value("action", ""), 999); s[999] = '\0'; //printf("%s: Specified : %s\n",devid_string,s); if(strcmp(s, "")) { // spawn external program (telnet client)... while(*nargv) { argv[i] = nargv; if(nargv[0] == '\"') nargv = strchr(nargv + 1, '\"'); if(nargv) nargv = strchr(nargv, ' '); if(!nargv) break; *nargv++ = '\0'; i++; argv[i] = NULL; } argv[i + 1] = NULL; strcpy(s2, argv[0]); nargv = s2; if(nargv[0] == '\"') { nargv++; *(strchr(nargv, '\"')) = '\0'; } //printf("%s: Starting %s\n", devid_string,nargv); #if defined(_WIN32) if (_spawnvp(_P_NOWAIT, nargv, argv) < 0) FAILURE_1(Runtime,"Exec of '%s' has failed.\n", argv[0]); #elif !defined(__VMS) pid_t child; int status; if(!(child = fork())) { execvp(argv[0], argv); FAILURE_1(Runtime,"Exec of '%s' failed.\n", argv[0]); } else { sleep(1); // give it a chance to start up. waitpid(child, &status, WNOHANG); // reap it, if needed. if(kill(child, 0) < 0) { // uh oh, no kiddo. FAILURE_1(Runtime,"Exec of '%s' has failed.\n", argv[0]); } } #endif } #endif Address.sin_addr.s_addr = INADDR_ANY; Address.sin_port = htons((u16) listenPort); Address.sin_family = AF_INET; // Wait until we have a connection connectSocket = INVALID_SOCKET; while(connectSocket == INVALID_SOCKET) { connectSocket = (int) accept(listenSocket, (struct sockaddr*) &Address, &nAddressSize); } state.serial_cycles = 0; if (state.iNumber != 1) { // Send some control characters to the telnet client to handle // character-at-a-time mode. sprintf(buffer, telnet_options, IAC, DO, TELOPT_ECHO); write_cstr(buffer); sprintf(buffer, telnet_options, IAC, DO, TELOPT_NAWS); write_cstr(buffer); sprintf(buffer, telnet_options, IAC, DO, TELOPT_LFLOW); write_cstr(buffer); sprintf(buffer, telnet_options, IAC, WILL, TELOPT_ECHO); write_cstr(buffer); sprintf(buffer, telnet_options, IAC, WILL, TELOPT_SGA); write_cstr(buffer); sprintf(s, "This is serial port #%d on ES40 Emulator\r\n", state.iNumber); write_cstr(s); } }
int main(int argc, char *argv[]) { char *filename_p = 0; char ** argv_; argv_ = new char* [argc]; int k = 0; DEBUG0 (DEBUG_L_CALL, "DEBUG: parsing arguments\n"); for (int i = 0; i < argc; i++) { if (!argv[i]) { break; } if (argv[i][0] != '-') { argv_[k++] = strdup(argv[i]); continue; } int j = 1; if (argv[i][1] == '-') { if (argv[i][2] == 0) { break; } // handle -- end of options j = 2; // handle --argument } if (strstr((argv[i] + j), "ORB")) { continue; } if (! strcmp((argv[i] + j), "help") || strchr((argv[i] + j), 'h')) { // -h or --help cout << argv[0] << version << endl << "Usage: " << argv[0] << "[CORBA OPTIONS] [OPTIONS]" << endl << "\t-h : This help text" << endl << "\t-v : Prints out the version" << endl << "\t-file Filename : Probe to Execute" << endl << "\t-f Filename : Probe to Execute" << endl ; exit (0); } if (! strcmp((argv[i] + j), "version") || strchr((argv[i] + j), 'v')) { cout << argv[0] << ": Version "<< version << endl; exit (0); } if (! strcmp((argv[i] + j), "file") || strchr((argv[i] + j), 'f')) { filename_p = strdup(argv[++i]); continue; } argv_[k++] = strdup(argv[i]); } if(!filename_p) { std::cerr << "Error: Failed to feploy probe: missing path" << std::endl; exit(EXIT_FAILURE);; } /* end of if(!this->filename_p) */ if(argv_[0]) { free (argv_[0]); } /* end of if(argv_[0]) */ argv_[0] = strdup(filename_p); /// The control pipe int ctrlpipe[2]; /// The data pipe int datapipe[2]; #if defined(_WIN32) if ( _pipe( ctrlpipe, BUFSIZ+8192, O_BINARY | O_NOINHERIT ) < 0 ) { perror("Error while creating the ctrlpipe"); return -1; } /* end of if(pipe(this->ctrlpipe)) */ if ( _pipe( datapipe, BUFSIZ+8192, O_BINARY | O_NOINHERIT ) < 0 ) { perror("Error while creating the datapipe"); return -1; } /* end of if(pipe(this->datapipe) < 0) */ #else if(pipe(ctrlpipe) < 0) { perror("Error while creating the ctrlpipe"); return -1; } /* end of if(pipe(this->ctrlpipe)) */ if(pipe(datapipe) < 0) { perror("Error while creating the datapipe"); return -1; } /* end of if(pipe(this->datapipe) < 0) */ #endif try { #if defined(_WIN32) char buff[BUFSIZ + 8192]; int n, hStdOut, hStdIn, nExitCode = STILL_ACTIVE; HANDLE hProcess; DEBUG0 (4, "Saving the stdin and stdout file descriptors\n"); hStdOut = _dup(_fileno(stdout)); hStdIn = _dup(_fileno(stdin)); DEBUG0 (4, "Using _dup2 on datapipe write and ctrlpipe read ends\n"); if(_dup2(datapipe[1], _fileno(stdout)) != 0) perror("Error in using dup2 on datapipe[1]"); if(_dup2(ctrlpipe[0], _fileno(stdin)) != 0) perror ("Error in using dup2 on ctrlpipe[0]"); DEBUG0 (4, "Closing the datapipe write and ctrlpipe read ends\n"); close(datapipe[1]); close(ctrlpipe[0]); DEBUG0 (4, "Spawning the process \n"); hProcess = (HANDLE)_spawnvp(P_NOWAIT, filename_p ,argv_); DEBUG0 (4, "Changing original file descriptors back to stdin and stdout\n"); if(_dup2(hStdOut, _fileno(stdout)) != 0) { perror("Error in making hStdOut as stdout\n"); exit(1); } if(_dup2(hStdIn, _fileno(stdin)) != 0) { perror ("Error in making hStdIn as stdin\n"); exit(1); } DEBUG0 (4, "Closing the original file descriptors\n"); close(hStdOut); close(hStdIn); strcpy(buff,"start\n"); n = strlen(buff); DEBUG0 (4, "DEBUG: In NT parent: writing start"); ssize_t nleft = n; ssize_t nwritten = 0; char *ptr = buff; while(nleft > 0) { if((nwritten = write(ctrlpipe[1], ptr, nleft)) <= 0) { if(errno == EINTR) { nwritten = 0; } /* end of if(errno == EINTR) */ else { perror ("Error while writing start on to pipe"); } /* end of else */ } /* end of if((nwritten = write(sockfd, ptr, nleft)) <= 0) */ nleft -= nwritten; ptr += nwritten; } /* end of while(nleft > 0) */ string message; string raw_data; DEBUG0 (4, "DEBUG: In parent: reading"); if (hProcess) { while (nExitCode == STILL_ACTIVE) { n = read (datapipe[0], buff, BUFSIZ + 8192); buff[n] = 0; DEBUG2 (2, "DEBUG: Read %d bytes --> \n%s", n, buff); raw_data.append(buff); string::size_type index = raw_data.find(STDC::QMS::Citizen::delimiter); while(index != string::npos) { // we have at least one complete message in here message.assign(raw_data, 0, index); raw_data.erase(0, index + strlen(STDC::QMS::Citizen::delimiter)); index = raw_data.find(STDC::QMS::Citizen::delimiter); std::cerr << "Probe says: " << message << std::endl; } /* end of while(message.find(delimiter) != string::npos) */ if(!GetExitCodeProcess(hProcess,(unsigned long*)&nExitCode)) perror ("Error in getting Child process exit status"); } /* end of while((n = read(datapipe[0], buff, BUFSIZ + 8192) ) > 0)*/ DEBUG0 (4, "*******Child Exited********\n"); } // end of if (hProcess) DEBUG0 (6, "DEBUG: In parent: finished reading"); #else int childpid = fork(); if(childpid < 0) { perror("Fork Failed"); return childpid; } /* end of if(childpid < 0) */ if(childpid == 0) { // in the child DEBUG0 (4, "DEBUG: Handling descriptors in the child"); if (close(ctrlpipe[1]) != 0) perror ("close"); if (close(datapipe[0]) != 0) perror ("close"); DEBUG0 (2, "Continuous_Pipe_Proxy:: Handling stdin in the child"); if (ctrlpipe[0] != STDIN_FILENO ) { if ( dup2 ( ctrlpipe[0], STDIN_FILENO ) != STDIN_FILENO ) { fprintf(stderr, "Problem with STDIN dup2\n"); return (-1); } if (close ( ctrlpipe[0]) != 0) perror("close"); } DEBUG0 (2, "Continuous_Pipe_Proxy:: Handling stdout in the child"); if ( datapipe[1] != STDOUT_FILENO ) { if ( dup2 ( datapipe[1], STDOUT_FILENO ) != STDOUT_FILENO ) { // Problems fprintf(stderr, "Problem with STDOUT dup2\n"); return (-1); } if (close ( datapipe[1]) != 0) perror("close datapipe[0]"); } DEBUG1 (2, "DEBUG: Continuous_Pipe_Proxy::deploy exec %s", filename_p); // DEBUG!!! if(!argv_) { fprintf(stderr, "No arguments!!!\n"); return (-1); } /* end of if(!this->argv_) */ #ifndef SILENT_MODE else { int i = 0; std::cerr << "\tCommand: '"; while(argv_[i]) { std::cerr << argv_[i++] << " "; } /* end of while(this->argv_[i]) */ std::cerr << "'" << std::endl; } /* end of else */ #endif int ret = execvp(filename_p, argv_); perror("Failed execve"); DEBUG1 (8, "DEBUG: Failed execve %d", ret); } /* end of if(int childpid = fork()) */ else { // in the parent DEBUG0 (4, "DEBUG: Handling descriptors in parent"); if (close(ctrlpipe[0]) != 0) perror ("close"); if (close(datapipe[1]) != 0) perror ("close"); char buff[BUFSIZ + 8192]; ssize_t length ; ssize_t n ; DEBUG0 (6, "DEBUG: In parent: writing start"); strcpy (buff, "start\n"); length = strlen(buff); ssize_t nleft = length; ssize_t nwritten = 0; char *ptr = buff; while(nleft > 0) { if((nwritten = write(ctrlpipe[1], ptr, nleft)) <= 0) { if(errno == EINTR) { nwritten = 0; } /* end of if(errno == EINTR) */ else { perror ("Error while writing start on to pipe"); } /* end of else */ } /* end of if((nwritten = write(sockfd, ptr, nleft)) <= 0) */ nleft -= nwritten; ptr += nwritten; } /* end of while(nleft > 0) */ string message; string raw_data; bool done = false; DEBUG0 (4, "DEBUG: In parent: reading"); while(!done) { n = read(datapipe[0], buff, BUFSIZ + 8192); if(n < 0) { if(errno == EINTR) { continue; } /* end of if(errno == EINTR) */ else { break; } /* end of else */ } /* end of if(n < 0) */ if(n == 0) { break; } /* end of if(n == 0) */ buff[n] = 0; DEBUG2 (2, "DEBUG: Read %d bytes --> \n%s", n, buff); raw_data.append(buff); string::size_type index = raw_data.find(STDC::QMS::Citizen::delimiter); while(index != string::npos) { // we have at least one complete message in here message.assign(raw_data, 0, index); raw_data.erase(0, index + strlen(STDC::QMS::Citizen::delimiter)); index = raw_data.find(STDC::QMS::Citizen::delimiter); std::cerr << "Probe says: " << message << std::endl; } /* end of while(message.find(delimiter) != string::npos) */ } /* end of while((n = read(datapipe[0], buff, BUFSIZ + 8192) ) > 0)*/ if(n == -1) { perror("read from child\n"); } /* end of if(n == -1) */ DEBUG0 (6, "DEBUG: In parent: finished reading"); int status = 0; pid_t pid_ret; while((pid_ret = waitpid(childpid, &status, WNOHANG) ) > 0 ) { DEBUG1(4, "DEBUG: Exited Childpid ->%d", pid_ret); if(WIFEXITED(status)) { DEBUG0(4, "DEBUG: Child Exited Normally"); } /* end of if(WIFEXITED(status)) */ else { DEBUG1(6, "DEBUG: Child Exited Abnormally with status %d", WEXITSTATUS(status)); if(WIFSIGNALED(status)) { DEBUG1(6, "DEBUG: Child got signal %d", WTERMSIG(status)); } /* end of if(WIFSIGNALED(status)) */ } /* end of else if(WIFEXITED(status)) */ } /* end of while(pid_ret = waitpid(childpid, &status, 0)) */ DEBUG0 (4, "DEBUG: Parent closing file descriptors"); if (close(ctrlpipe[1]) != 0) perror ("close"); if (close(datapipe[0]) != 0) perror ("close"); } /* end of else */ #endif } catch (...) { std::cerr << "caught an exception while deploying" << std::endl; exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
int main(int argc, char* argv[]) { xsCreation creation_mc = { 25*1024, /* initial chunk size */ 2048, /* incremental chunk size */ 50*1024/16, /* initial heap count -- will be calculated later */ 128, /* incremental heap count -- wasting 16 bytes / allocation */ 548, /* stack count */ 2048+512, /* key count */ 97, /* name modulo */ 127, /* symbol modulo */ }; xsCreation creation_tool = { 128 * 1024 * 1024, /* initialChunkSize */ 16 * 1024 * 1024, /* incrementalChunkSize */ 8 * 1024 * 1024, /* initialHeapCount */ 1 * 1024 * 1024, /* incrementalHeapCount */ 4096, /* stackCount */ 4096*3, /* keyCount */ 1993, /* nameModulo */ 127 /* symbolModulo */ }; xsCreation* creation = &creation_tool; int error = 0; int argi = 1; void* archive = NULL; xsBooleanValue program = 0; xsBooleanValue xsbug = 0; xsMachine* machine; char path[PATH_MAX]; char modulePath[PATH_MAX]; xsStringValue extension; xsStringValue slash; xsStringValue name; int size; if (argi < argc) { if (!strcmp(argv[argi], "-a")) { argi++; if (argi < argc) { if (realpath(argv[argi], path)) { archive = fxMapArchive(path, NULL); if (!archive) { fprintf(stderr, "# invalid archive: %s\n", path); return 1; } if (strstr(path, "mc.xsa")) { creation = &creation_mc; } } else { fprintf(stderr, "# archive not found: %s\n", argv[argi]); return 1; } argi++; } } } while (argi < argc) { if (!strcmp(argv[argi], "-p")) { program = 1; argi++; } else if (!strcmp(argv[argi], "-x")) { xsbug = 1; argi++; } else break; } gargc = argc; gargi = argi; gargv = argv; machine = xsCreateMachine(creation, archive, "xsr6", NULL); xsBeginHost(machine); { xsVars(2); //xsStartProfiling(); { xsTry { xsVar(0) = xsNewInstanceOf(xsObjectPrototype); if (xsbug) xsVar(1) = xsNewHostFunction(console_log_xsbug, 0); else xsVar(1) = xsNewHostFunction(console_log, 0); xsSet(xsVar(0), xsID("log"), xsVar(1)); xsSet(xsGlobal, xsID("console"), xsVar(0)); xsVar(0) = xsNewHostObject(weakTest); xsVar(1) = xsNewHostConstructor(WeakTest, 1, xsVar(0)); xsSet(xsGlobal, xsID("WeakTest"), xsVar(1)); xsVar(1) = xsNewHostFunction(gc, 0); xsSet(xsGlobal, xsID("gc"), xsVar(1)); xsResult = xsModulePaths(); if (archive) { slash = strrchr(path, mxSeparator); if (slash) { *(slash + 1) = 0; xsCall1(xsResult, xsID("add"), xsString(path)); } } realpath(argv[0], modulePath); slash = strrchr(modulePath, mxSeparator); if (slash) { strcpy(slash + 1, "modules"); size = c_strlen(modulePath); modulePath[size++] = mxSeparator; modulePath[size] = 0; xsCall1(xsResult, xsID("add"), xsString(modulePath)); } if (argi == argc) { fprintf(stderr, "# no module, no program\n"); error = 1; } else if (program) { xsVar(0) = xsNewHostFunction(print, 0); xsSet(xsGlobal, xsID("print"), xsVar(0)); xsStartProfiling(); while (argi < argc) { if (argv[argi][0] != '-') { xsElseError(realpath(argv[argi], path)); strcpy(modulePath, path); slash = strrchr(modulePath, mxSeparator); *(slash + 1) = 0; xsCall1(xsResult, xsID("add"), xsString(modulePath)); strcat(modulePath, "modules/"); xsCall1(xsResult, xsID("add"), xsString(modulePath)); fxRunProgram(the, path); } argi++; } fxRunLoop(the); xsStopProfiling(); } else { xsVar(0) = xsNewInstanceOf(xsObjectPrototype); xsVar(1) = xsNewHostFunction(process_cwd, 0); xsSet(xsVar(0), xsID("cwd"), xsVar(1)); #ifdef mxDebug xsSet(xsVar(0), xsID("debug"), xsTrue); #else xsSet(xsVar(0), xsID("debug"), xsFalse); #endif xsVar(1) = xsNewHostFunction(process_execArgv, 0); xsSet(xsVar(0), xsID("execArgv"), xsVar(1)); xsVar(1) = xsNewHostFunction(process_getenv, 0); xsSet(xsVar(0), xsID("getenv"), xsVar(1)); xsVar(1) = xsNewHostFunction(process_then, 1); xsSet(xsVar(0), xsID("then"), xsVar(1)); xsSet(xsVar(0), xsID("platform"), xsString("darwin")); xsSet(xsGlobal, xsID("process"), xsVar(0)); strcpy(path, argv[argi]); slash = strrchr(path, mxSeparator); if (slash) { *slash = 0; realpath(path, modulePath); size = c_strlen(modulePath); modulePath[size++] = mxSeparator; modulePath[size] = 0; xsCall1(xsResult, xsID("add"), xsString(modulePath)); strcat(modulePath, "modules"); size = c_strlen(modulePath); modulePath[size++] = mxSeparator; modulePath[size] = 0; xsCall1(xsResult, xsID("add"), xsString(modulePath)); name = slash + 1; } else { realpath(".", modulePath); size = c_strlen(modulePath); modulePath[size++] = mxSeparator; modulePath[size] = 0; xsCall1(xsResult, xsID("add"), xsString(modulePath)); strcat(modulePath, "modules"); size = c_strlen(modulePath); modulePath[size++] = mxSeparator; modulePath[size] = 0; xsCall1(xsResult, xsID("add"), xsString(modulePath)); name = path; } extension = strrchr(name, '.'); if (extension) *extension = 0; xsStartProfiling(); fxRunModule(the, name); xsStopProfiling(); } } xsCatch { xsStringValue message = xsToString(xsException); fprintf(stderr, "### %s\n", message); error = 1; } } //xsStopProfiling(); } xsEndHost(the); xsDeleteMachine(machine); fxUnmapArchive(archive); if (!error && process_then_parameters) { #if mxWindows if (_spawnvp(_P_WAIT, process_then_parameters[0], process_then_parameters) < 0) fprintf(stderr, "### Cannot execute %s!\n", process_then_parameters[0]); #else execvp(process_then_parameters[0], process_then_parameters); #endif } return error; }
int archdep_spawn(const char *name, char **argv, char **pstdout_redir, const char *stderr_redir) { #ifndef WATCOM_COMPILE int new_stdout, new_stderr; int old_stdout_mode, old_stderr_mode; int old_stdout, old_stderr; int retval; char *stdout_redir = NULL; if (pstdout_redir != NULL) { if (*pstdout_redir == NULL) { *pstdout_redir = archdep_tmpnam(); } stdout_redir = *pstdout_redir; } new_stdout = new_stderr = old_stdout = old_stderr = -1; /* Make sure we are in binary mode. */ old_stdout_mode = _setmode(STDOUT_FILENO, _O_BINARY); old_stderr_mode = _setmode(STDERR_FILENO, _O_BINARY); /* Redirect stdout and stderr as requested, saving the old descriptors. */ if (stdout_redir != NULL) { old_stdout = _dup(STDOUT_FILENO); new_stdout = _open(stdout_redir, _O_WRONLY | _O_TRUNC | _O_CREAT, _S_IWRITE | _S_IREAD); if (new_stdout == -1) { log_error(LOG_DEFAULT, "open(\"%s\") failed: %s.", stdout_redir, strerror(errno)); retval = -1; goto cleanup; } _dup2(new_stdout, STDOUT_FILENO); } if (stderr_redir != NULL) { old_stderr = _dup(STDERR_FILENO); new_stderr = _open(stderr_redir, _O_WRONLY | _O_TRUNC | _O_CREAT, _S_IWRITE | _S_IREAD); if (new_stderr == -1) { log_error(LOG_DEFAULT, "open(\"%s\") failed: %s.", stderr_redir, strerror(errno)); retval = -1; goto cleanup; } _dup2(new_stderr, STDERR_FILENO); } /* Spawn the child process. */ retval = (int)_spawnvp(_P_WAIT, name, (const char **)argv); cleanup: if (old_stdout >= 0) { _dup2(old_stdout, STDOUT_FILENO); _close(old_stdout); } if (old_stderr >= 0) { _dup2(old_stderr, STDERR_FILENO); _close(old_stderr); } if (old_stdout_mode >= 0) { _setmode(STDOUT_FILENO, old_stdout_mode); } if (old_stderr_mode >= 0) { _setmode(STDERR_FILENO, old_stderr_mode); } if (new_stdout >= 0) { _close(new_stdout); } if (new_stderr >= 0) { _close(new_stderr); } return retval; #else return -1; #endif }
int spawnvp(int pmode,const char *path,const char *const argv[]) { return _spawnvp(pmode,path,argv); }
int InvokeProgram(int oftype) { List p = NULL; char **cmd; char *file; int status = 0; switch (oftype) { case PP_FILE: if (Option.cfiles == NULL) return 0; for (p = Option.cfiles; p != NULL; p = p->next) { PPFiles = ListAppend(PPFiles, FileName(p->str, ".i")); } Option.pfiles = ListCombine(Option.pfiles, PPFiles); cmd = BuildCommand(CPPProg, Option.pflags, Option.cfiles, PPFiles); status = _spawnvp(_P_WAIT, cmd[0], cmd); for (p = PPFiles; p != NULL; p = p->next) { if ((file = strrchr(p->str, '\\')) || (file = strrchr(p->str, '/'))) { rename(file + 1, p->str); } } break; case ASM_FILE: if (Option.pfiles == NULL) return 0; for (p = Option.pfiles; p != NULL; p = p->next) { ASMFiles = ListAppend(ASMFiles, FileName(p->str, ".asm")); } Option.afiles = ListCombine(Option.afiles, ASMFiles); cmd = BuildCommand(CCProg, Option.cflags, Option.pfiles, ASMFiles); status = _spawnvp(_P_WAIT, cmd[0], cmd); break; case OBJ_FILE: if (Option.afiles == NULL) return 0; for (p = Option.aflags, Option.aflags = NULL; p != NULL; p = p->next) { Option.aflags = ListCombine(Option.aflags, ParseOption(p->str + 4)); } for (p = Option.afiles; p != NULL; p = p->next) { file = FileName(p->str, ".obj"); OBJFiles = ListAppend(OBJFiles, file); cmd = BuildCommand(ASProg, Option.aflags, ListAppend(NULL, p->str), ListAppend(NULL, file)); status = _spawnvp(_P_WAIT, cmd[0], cmd); } Option.ofiles = ListCombine(Option.ofiles, OBJFiles); break; case LIB_FILE: break; case EXE_FILE: if (Option.ofiles == NULL) return 0; if (Option.out == NULL) { Option.out = Option.ofiles->str; } Option.out = FileName(Option.out, ".exe"); for (p = Option.lflags, Option.lflags = NULL; p != NULL; p = p->next) { Option.lflags = ListCombine(Option.lflags, ParseOption(p->str + 4)); } cmd = BuildCommand(LDProg, Option.lflags, Option.linput, ListAppend(NULL, Option.out)); status = _spawnvp(_P_WAIT, cmd[0], cmd); break; } return status; }
void CWE78_OS_Command_Injection__char_listen_socket_w32_spawnvp_15_bad() { char * data; char dataBuffer[100] = ""; data = dataBuffer; switch(6) { case 6: { #ifdef _WIN32 WSADATA wsaData; int wsaDataInit = 0; #endif int recvResult; struct sockaddr_in service; char *replace; SOCKET listenSocket = INVALID_SOCKET; SOCKET acceptSocket = INVALID_SOCKET; size_t dataLen = strlen(data); do { #ifdef _WIN32 if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { break; } wsaDataInit = 1; #endif /* POTENTIAL FLAW: Read data using a listen socket */ listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (listenSocket == INVALID_SOCKET) { break; } memset(&service, 0, sizeof(service)); service.sin_family = AF_INET; service.sin_addr.s_addr = INADDR_ANY; service.sin_port = htons(TCP_PORT); if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) { break; } if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) { break; } acceptSocket = accept(listenSocket, NULL, NULL); if (acceptSocket == SOCKET_ERROR) { break; } /* Abort on error or the connection was closed */ recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); if (recvResult == SOCKET_ERROR || recvResult == 0) { break; } /* Append null terminator */ data[dataLen + recvResult / sizeof(char)] = '\0'; /* Eliminate CRLF */ replace = strchr(data, '\r'); if (replace) { *replace = '\0'; } replace = strchr(data, '\n'); if (replace) { *replace = '\0'; } } while (0); if (listenSocket != INVALID_SOCKET) { CLOSE_SOCKET(listenSocket); } if (acceptSocket != INVALID_SOCKET) { CLOSE_SOCKET(acceptSocket); } #ifdef _WIN32 if (wsaDataInit) { WSACleanup(); } #endif } break; default: /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ printLine("Benign, fixed string"); break; } { char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG2, COMMAND_ARG3, NULL}; /* spawnvp - searches for the location of the command among * the directories specified by the PATH environment variable */ /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ _spawnvp(_P_WAIT, COMMAND_INT, args); } }
int spawn(char *prog, char **argv) { return _spawnvp(P_NOWAIT, prog, (const char**)argv); }
void LaunchService::Launch(const stringVector &origLaunchArgs, bool doBridge, SocketConnection **conn) { const char *mName = "LaunchService::LaunchProcess: "; debug1 << mName << "start" << endl; stringVector launchArgs(origLaunchArgs); bool readOutput = conn != NULL; if(readOutput) *conn = NULL; if(launchArgs.empty()) return; // Set up a socket bridge if we need one. if(doBridge) SetupGatewaySocketBridgeIfNeeded(launchArgs); std::string remoteProgram(launchArgs[0]); debug1 << mName << "LaunchRPC command = " << remoteProgram.c_str() << ", args=("; // Make a command line array for the exec functions. char **args = new char *[launchArgs.size() + 1]; memset(args, 0, (launchArgs.size() + 1) * sizeof(char *)); for(size_t i = 0; i < launchArgs.size(); ++i) { args[i] = new char[launchArgs[i].size() + 1]; strcpy(args[i], launchArgs[i].c_str()); if(i > 0) { debug1 << launchArgs[i].c_str() << " "; } } debug1 << ")" << endl; // We have command line arguments for a command to launch. int remoteProgramPid = 0; #if defined(_WIN32) // Do it the WIN32 way where we use the _spawnvp system call. remoteProgramPid = _spawnvp(_P_NOWAIT, remoteProgram.c_str(), args); #else // Watch for a process who died childDied[remoteProgramPid] = false; signal(SIGCHLD, DeadChildHandler); #ifdef CAPTURE_CHILD_OUTPUT // Create a pipe. int f_des[2]; if(pipe(f_des) == -1) readOutput = false; #endif switch (remoteProgramPid = fork()) { case -1: // Could not fork. exit(-1); // HOOKS_IGNORE break; case 0: // Close stdin and any other file descriptors. fclose(stdin); #ifdef CAPTURE_CHILD_OUTPUT // Send the process' stdout/stderr to our pipe. if(readOutput) { dup2(f_des[1], fileno(stdout)); dup2(f_des[1], fileno(stderr)); close(f_des[0]); close(f_des[1]); } #endif for (int k = 3 ; k < 32 ; ++k) { close(k); } // Execute the process on the local machine. remoteProgram = FileFunctions::ExpandPath(remoteProgram); execvp(remoteProgram.c_str(), args); exit(-1); // HOOKS_IGNORE break; // OCD default: #ifdef CAPTURE_CHILD_OUTPUT if(readOutput) close(f_des[1]); #endif break; } // Stop watching for dead children signal(SIGCHLD, SIG_DFL); // If we had a dead child, try and connect back to the client that // wanted to connect to the dead child. if(childDied[remoteProgramPid]) { // Create a temp array of pointers to the strings that we // created and pass the temp array to the TerminateConnectionRequest // method because it creates a ParentProcess object that will // rearrange the pointers in the array. char **args2 = new char *[launchArgs.size() + 1]; for(size_t i = 0; i < launchArgs.size(); ++i) args2[i] = args[i]; // Tell the client that we could not connect. TerminateConnectionRequest(launchArgs.size(), args2); delete [] args2; } #ifdef CAPTURE_CHILD_OUTPUT else if(readOutput) { // Add the child's output pipe to the list of descriptors that // we will check. We add the pipe file descriptor as a // SocketConnection object. *conn = new SocketConnection(f_des[0]); } #endif #endif // Free the command line storage. for(size_t i = 0; i < launchArgs.size(); ++i) delete [] args[i]; delete [] args; debug1 << mName << "end" << endl; }
static string maketex (kpathsea kpse, kpse_file_format_type format, string* args) { /* New implementation, use fork/exec pair instead of popen, since * the latter is virtually impossible to make safe. */ unsigned len; string *s; string ret = NULL; string fn; #if defined(WIN32) char fullbin[256], *wrp; wrp = kpathsea_var_value(kpse, "SELFAUTOLOC"); if(wrp == NULL) { fprintf(stderr, "I cannot get SELFAUTOLOC\n"); exit(100); } strcpy(fullbin, wrp); free(wrp); for(wrp=fullbin; *wrp; wrp++) { if(*wrp == '/') *wrp = '\\'; } strcat(fullbin, "\\"); strcat(fullbin, args[0]); #endif if (!kpse->make_tex_discard_errors) { fprintf (stderr, "\nkpathsea: Running"); for (s = &args[0]; *s != NULL; s++) fprintf (stderr, " %s", *s); fputc('\n', stderr); } #if defined (AMIGA) /* Amiga has a different interface. */ { string cmd; string newcmd; cmd = xstrdup(args[0]); for (s = &args[1]; *s != NULL; s++) { newcmd = concat(cmd, *s); free (cmd); cmd = newcmd; } ret = system(cmd) == 0 ? getenv ("LAST_FONT_CREATED"): NULL; free (cmd); } #elif defined (MSDOS) && !defined(__DJGPP__) #error Implement new MSDOS mktex call interface here #else /* WIN32 or Unix */ { #if defined (WIN32) /* spawnvp(_P_NOWAIT, ...) and pipe --ak 2002/12/15 */ unsigned long nexitcode = STILL_ACTIVE; HANDLE hchild; int hstdout, childpipe[2]; int hstderr = -1; FILE *Hnul = NULL; fn = NULL; if(_pipe(childpipe, 1024, O_TEXT | _O_NOINHERIT) == -1) { perror("kpathsea: pipe()"); goto labeldone; } hstdout = _dup(fileno(stdout)); if(_dup2(childpipe[1], fileno(stdout)) != 0) { close(hstdout); close(childpipe[0]); close(childpipe[1]); goto labeldone; } close(childpipe[1]); if(kpse->make_tex_discard_errors) { Hnul = fopen("nul", "w"); if(!Hnul) { perror("kpathsea: fopen(\"nul\")"); } else { hstderr = _dup(fileno(stderr)); _dup2(fileno(Hnul), fileno(stderr)); } } fprintf(stderr, "\nThe command name is %s\n", fullbin); hchild = (HANDLE)_spawnvp(_P_NOWAIT, fullbin, (const char * const *) args); _dup2(hstdout, fileno(stdout)); close(hstdout); if(hchild == (HANDLE)(-1)) { close(childpipe[0]); goto labeldone; } if(hchild) { char buf[1024+1]; int num; fn = xstrdup(""); while(nexitcode == STILL_ACTIVE) { num = read(childpipe[0], buf, sizeof(buf)-1); if(num) { string newfn; buf[num] = '\0'; newfn = concat(fn, buf); free(fn); fn = newfn; } if(!GetExitCodeProcess(hchild, &nexitcode)) { fn = NULL; close(childpipe[0]); goto labeldone; } } close(childpipe[0]); } labeldone: if(kpse->make_tex_discard_errors && Hnul) { _dup2(hstderr, fileno(stderr)); close(hstderr); fclose(Hnul); } #else /* !WIN32 */ /* Standard input for the child. Set to /dev/null */ int childin; /* Standard output for the child, what we're interested in. */ int childout[2]; /* Standard error for the child, same as parent or /dev/null */ int childerr; /* Child pid. */ pid_t childpid; /* Open the channels that the child will use. */ /* A fairly horrible uses of gotos for here for the error case. */ if ((childin = open("/dev/null", O_RDONLY)) < 0) { perror("kpathsea: open(\"/dev/null\", O_RDONLY)"); goto error_childin; } if (pipe(childout) < 0) { perror("kpathsea: pipe()"); goto error_childout; } if ((childerr = open("/dev/null", O_WRONLY)) < 0) { perror("kpathsea: open(\"/dev/null\", O_WRONLY)"); goto error_childerr; } if ((childpid = fork()) < 0) { perror("kpathsea: fork()"); close(childerr); error_childerr: close(childout[0]); close(childout[1]); error_childout: close(childin); error_childin: fn = NULL; } else if (childpid == 0) { /* Child * * We can use vfork, provided we're careful about what we * do here: do not return from this function, do not modify * variables, call _exit if there is a problem. * * Complete setting up the file descriptors. * We use dup(2) so the order in which we do this matters. */ close(childout[0]); /* stdin -- the child will not receive input from this */ if (childin != 0) { close(0); if (dup(childin) != 0) { perror("kpathsea: dup(2) failed for stdin"); close(childin); _exit(1); } close(childin); } /* stdout -- the output of the child's action */ if (childout[1] != 1) { close(1); if (dup(childout[1]) != 1) { perror("kpathsea: dup(2) failed for stdout"); close(childout[1]); _exit(1); } close(childout[1]); } /* stderr -- use /dev/null if we discard errors */ if (childerr != 2) { if (kpse->make_tex_discard_errors) { close(2); if (dup(childerr) != 2) { perror("kpathsea: dup(2) failed for stderr"); close(childerr); _exit(1); } } close(childerr); } /* FIXME: We could/should close all other file descriptors as well. */ /* exec -- on failure a call of _exit(2) it is the only option */ if (execvp(args[0], args)) perror(args[0]); _exit(1); } else { /* Parent */ char buf[1024+1]; int num; /* Clean up child file descriptors that we won't use anyway. */ close(childin); close(childout[1]); close(childerr); /* Get stdout of child from the pipe. */ fn = xstrdup(""); while ((num = read(childout[0],buf,sizeof(buf)-1)) != 0) { if (num == -1) { if (errno != EINTR) { perror("kpathsea: read()"); break; } } else { string newfn; buf[num] = '\0'; newfn = concat(fn, buf); free(fn); fn = newfn; } } /* End of file on pipe, child should have exited at this point. */ close(childout[0]); /* We don't really care about the exit status at this point. */ wait(NULL); } #endif /* !WIN32 */ if (fn) { len = strlen(fn); /* Remove trailing newlines and returns. */ while (len && (fn[len - 1] == '\n' || fn[len - 1] == '\r')) { fn[len - 1] = '\0'; len--; } ret = len == 0 ? NULL : kpathsea_readable_file (kpse, fn); if (!ret && len > 1) { WARNING2 ("kpathsea: %s output `%s' instead of a filename", args[0], fn); } /* Free the name if we're not returning it. */ if (fn != ret) free (fn); } } #endif /* WIN32 or Unix */ if (ret == NULL) misstex (kpse, format, args); else kpathsea_db_insert (kpse, ret); return ret; }
HB_FHANDLE hb_fsProcessOpen( const char * pszFileName, HB_FHANDLE * phStdin, HB_FHANDLE * phStdout, HB_FHANDLE * phStderr, HB_BOOL fDetach, HB_ULONG * pulPID ) { HB_FHANDLE hPipeIn [ 2 ] = { FS_ERROR, FS_ERROR }, hPipeOut[ 2 ] = { FS_ERROR, FS_ERROR }, hPipeErr[ 2 ] = { FS_ERROR, FS_ERROR }; HB_FHANDLE hResult = FS_ERROR; HB_BOOL fError = HB_FALSE; HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessOpen(%s, %p, %p, %p, %d, %p)", pszFileName, ( void * ) phStdin, ( void * ) phStdout, ( void * ) phStderr, fDetach, ( void * ) pulPID ) ); if( phStdin != NULL ) fError = ! hb_fsPipeCreate( hPipeIn ); if( ! fError && phStdout != NULL ) fError = ! hb_fsPipeCreate( hPipeOut ); if( ! fError && phStderr != NULL ) { if( phStdout == phStderr ) { hPipeErr[ 0 ] = hPipeOut[ 0 ]; hPipeErr[ 1 ] = hPipeOut[ 1 ]; } else fError = ! hb_fsPipeCreate( hPipeErr ); } if( ! fError ) { #if defined( HB_OS_WIN ) PROCESS_INFORMATION pi; STARTUPINFO si; DWORD dwFlags = 0; LPTSTR lpCommand = HB_CHARDUP( pszFileName ); # if ! defined( HB_OS_WIN_CE ) if( phStdin != NULL ) SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 1 ] ), HANDLE_FLAG_INHERIT, 0 ); if( phStdout != NULL ) SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 0 ] ), HANDLE_FLAG_INHERIT, 0 ); if( phStderr != NULL && phStdout != phStderr ) SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 0 ] ), HANDLE_FLAG_INHERIT, 0 ); # endif memset( &pi, 0, sizeof( pi ) ); memset( &si, 0, sizeof( si ) ); si.cb = sizeof( si ); # ifdef STARTF_USESTDHANDLES si.dwFlags = STARTF_USESTDHANDLES; # endif if( fDetach ) { # ifdef STARTF_USESHOWWINDOW si.dwFlags |= STARTF_USESHOWWINDOW; # endif si.wShowWindow = SW_HIDE; si.hStdInput = ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ); si.hStdOutput = ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ); si.hStdError = ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ); # ifdef DETACHED_PROCESS dwFlags |= DETACHED_PROCESS; # endif } else { si.hStdInput = phStdin ? ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ) : GetStdHandle( STD_INPUT_HANDLE ); si.hStdOutput = phStdout ? ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ) : GetStdHandle( STD_OUTPUT_HANDLE ); si.hStdError = phStderr ? ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ) : GetStdHandle( STD_ERROR_HANDLE ); } fError = ! CreateProcess( NULL, /* lpAppName */ lpCommand, NULL, /* lpProcessAttr */ NULL, /* lpThreadAttr */ TRUE, /* bInheritHandles */ dwFlags, /* dwCreationFlags */ NULL, /* lpEnvironment */ NULL, /* lpCurrentDirectory */ &si, &pi ); hb_fsSetIOError( ! fError, 0 ); hb_xfree( lpCommand ); if( ! fError ) { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pi.dwProcessId; CloseHandle( pi.hThread ); hResult = ( HB_FHANDLE ) pi.hProcess; } #elif defined( HB_OS_OS2 ) HFILE hNull = ( HFILE ) FS_ERROR; ULONG ulState = 0; APIRET ret = NO_ERROR; PID pid = ( PID ) -1; PHB_GT pGT; if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) ) { HB_FHANDLE hFile; ret = hb_fsOS2DosOpen( "NUL:", &hFile, &ulState, 0, FILE_NORMAL, OPEN_ACCESS_READWRITE, OPEN_ACTION_OPEN_IF_EXISTS ); if( ret == NO_ERROR ) hNull = ( HFILE ) hFile; } if( ret == NO_ERROR && phStdin != NULL ) { ret = DosQueryFHState( hPipeIn[ 1 ], &ulState ); if( ret == NO_ERROR && ( ulState & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hPipeIn[ 1 ], ( ulState & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); } if( ret == NO_ERROR && phStdout != NULL ) { ret = DosQueryFHState( hPipeOut[ 0 ], &ulState ); if( ret == NO_ERROR && ( ulState & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hPipeOut[ 0 ], ( ulState & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); } if( ret == NO_ERROR && phStderr != NULL && phStdout != phStderr ) { ret = DosQueryFHState( hPipeErr[ 0 ], &ulState ); if( ret == NO_ERROR && ( ulState & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hPipeErr[ 0 ], ( ulState & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); } if( ret == NO_ERROR && ( pGT = hb_gt_Base() ) != NULL ) { ULONG ulStateIn, ulStateOut, ulStateErr; HFILE hStdIn, hStdErr, hStdOut, hDup; ulStateIn = ulStateOut = ulStateErr = OPEN_FLAGS_NOINHERIT; hStdIn = hStdErr = hStdOut = ( HFILE ) FS_ERROR; if( ret == NO_ERROR && ( phStdin != NULL || fDetach ) ) { hDup = 0; ret = DosDupHandle( hDup, &hStdIn ); if( ret == NO_ERROR ) { ret = DosQueryFHState( hStdIn, &ulStateIn ); if( ret == NO_ERROR && ( ulStateIn & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hStdIn, ( ulStateIn & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); if( ret == NO_ERROR ) ret = DosDupHandle( phStdin != NULL ? ( HFILE ) hPipeIn[ 0 ] : hNull, &hDup ); } } if( ret == NO_ERROR && ( phStdout != NULL || fDetach ) ) { hDup = 1; ret = DosDupHandle( hDup, &hStdOut ); if( ret == NO_ERROR ) { ret = DosQueryFHState( hStdOut, &ulStateOut ); if( ret == NO_ERROR && ( ulStateOut & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hStdOut, ( ulStateOut & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); if( ret == NO_ERROR ) ret = DosDupHandle( phStdout != NULL ? ( HFILE ) hPipeOut[ 1 ] : hNull, &hDup ); } } if( ret == NO_ERROR && ( phStderr != NULL || fDetach ) ) { hDup = 2; ret = DosDupHandle( hDup, &hStdErr ); if( ret == NO_ERROR ) { ret = DosQueryFHState( hStdErr, &ulStateErr ); if( ret == NO_ERROR && ( ulStateErr & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hStdErr, ( ulStateErr & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); if( ret == NO_ERROR ) ret = DosDupHandle( phStderr != NULL ? ( HFILE ) hPipeErr[ 1 ] : hNull, &hDup ); } } if( ret == NO_ERROR ) { char * pArgs = hb_buildArgsOS2( pszFileName, &ret ); char uchLoadError[ CCHMAXPATH ] = { 0 }; RESULTCODES ChildRC = { 0, 0 }; if( pArgs ) { ret = DosExecPgm( uchLoadError, sizeof( uchLoadError ), fDetach ? EXEC_BACKGROUND : EXEC_ASYNCRESULT, ( PCSZ ) pArgs, NULL /* env */, &ChildRC, ( PCSZ ) pArgs ); if( ret == NO_ERROR ) pid = ChildRC.codeTerminate; hb_freeArgsOS2( pArgs ); } } if( hNull != ( HFILE ) FS_ERROR ) DosClose( hNull ); if( hStdIn != ( HFILE ) FS_ERROR ) { hDup = 0; DosDupHandle( hStdIn, &hDup ); DosClose( hStdIn ); if( ( ulStateIn & OPEN_FLAGS_NOINHERIT ) == 0 ) DosSetFHState( hDup, ulStateIn & 0xFF00 ); } if( hStdOut != ( HFILE ) FS_ERROR ) { hDup = 1; DosDupHandle( hStdOut, &hDup ); DosClose( hStdOut ); if( ( ulStateOut & OPEN_FLAGS_NOINHERIT ) == 0 ) DosSetFHState( hDup, ulStateOut & 0xFF00 ); } if( hStdErr != ( HFILE ) FS_ERROR ) { hDup = 2; DosDupHandle( hStdErr, &hDup ); DosClose( hStdErr ); if( ( ulStateErr & OPEN_FLAGS_NOINHERIT ) == 0 ) DosSetFHState( hDup, ulStateErr & 0xFF00 ); } hb_gt_BaseFree( pGT ); } else { if( hNull != ( HFILE ) FS_ERROR ) DosClose( hNull ); if( ret == NO_ERROR ) ret = ( APIRET ) FS_ERROR; } fError = ret != NO_ERROR; if( ! fError ) { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } hb_fsSetError( ( HB_ERRCODE ) ret ); #elif defined( HB_OS_UNIX ) && \ ! defined( HB_OS_VXWORKS ) && ! defined( HB_OS_SYMBIAN ) char ** argv = hb_buildArgs( pszFileName ); pid_t pid = fork(); if( pid == -1 ) fError = HB_TRUE; else if( pid != 0 ) /* parent process */ { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } else /* child process */ { if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) ) { HB_FHANDLE hNull = open( "/dev/null", O_RDWR ); if( ! phStdin ) dup2( hNull, 0 ); if( ! phStdout ) dup2( hNull, 1 ); if( ! phStderr ) dup2( hNull, 2 ); if( hNull != FS_ERROR ) hb_fsClose( hNull ); } if( phStdin != NULL ) { dup2( hPipeIn[ 0 ], 0 ); hb_fsClose( hPipeIn[ 1 ] ); } if( phStdout != NULL ) { dup2( hPipeOut[ 1 ], 1 ); hb_fsClose( hPipeOut[ 0 ] ); } if( phStderr != NULL ) { dup2( hPipeErr[ 1 ], 2 ); if( phStdout != phStderr ) hb_fsClose( hPipeErr[ 0 ] ); } /* close all non std* handles */ { int iMaxFD, i; iMaxFD = sysconf( _SC_OPEN_MAX ); if( iMaxFD < 3 ) iMaxFD = 1024; for( i = 3; i < iMaxFD; ++i ) hb_fsClose( i ); } /* reset extended process attributes */ if( setuid( getuid() ) == -1 ) {} if( setgid( getgid() ) == -1 ) {} /* execute command */ { # if defined( __WATCOMC__ ) execvp( argv[ 0 ], ( const char ** ) argv ); # else execvp( argv[ 0 ], argv ); # endif exit( -1 ); } } hb_fsSetIOError( ! fError, 0 ); hb_freeArgs( argv ); #elif defined( HB_OS_OS2 ) || defined( HB_OS_WIN ) int hStdIn, hStdOut, hStdErr; char ** argv; int pid; hStdIn = dup( 0 ); hStdOut = dup( 1 ); hStdErr = dup( 2 ); if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) ) { HB_FHANDLE hNull = open( "NUL:", O_RDWR ); if( ! phStdin ) dup2( hNull, 0 ); if( ! phStdout ) dup2( hNull, 1 ); if( ! phStderr ) dup2( hNull, 2 ); if( hNull != FS_ERROR ) close( hNull ); } if( phStdin != NULL ) dup2( hPipeIn[ 0 ], 0 ); if( phStdout != NULL ) dup2( hPipeOut[ 1 ], 1 ); if( phStderr != NULL ) dup2( hPipeErr[ 1 ], 2 ); argv = hb_buildArgs( pszFileName ); #if defined( _MSC_VER ) || defined( __LCC__ ) || \ defined( __XCC__ ) || defined( __POCC__ ) pid = _spawnvp( _P_NOWAIT, argv[ 0 ], argv ); #elif defined( __MINGW32__ ) || defined( __WATCOMC__ ) pid = spawnvp( P_NOWAIT, argv[ 0 ], ( const char * const * ) argv ); #else pid = spawnvp( P_NOWAIT, argv[ 0 ], ( char * const * ) argv ); #endif hb_freeArgs( argv ); dup2( hStdIn, 0 ); close( hStdIn ); dup2( hStdOut, 1 ); close( hStdOut ); dup2( hStdErr, 2 ); close( hStdErr ); if( pid < 0 ) fError = HB_TRUE; else if( pid != 0 ) /* parent process */ { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } hb_fsSetIOError( ! fError, 0 ); #else int iTODO; /* TODO: for given platform */ HB_SYMBOL_UNUSED( pszFileName ); HB_SYMBOL_UNUSED( fDetach ); HB_SYMBOL_UNUSED( pulPID ); hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); #endif } if( hPipeIn[ 0 ] != FS_ERROR ) hb_fsCloseRaw( hPipeIn[ 0 ] ); if( hPipeIn[ 1 ] != FS_ERROR ) hb_fsCloseRaw( hPipeIn[ 1 ] ); if( hPipeOut[ 0 ] != FS_ERROR ) hb_fsCloseRaw( hPipeOut[ 0 ] ); if( hPipeOut[ 1 ] != FS_ERROR ) hb_fsCloseRaw( hPipeOut[ 1 ] ); if( phStdout != phStderr ) { if( hPipeErr[ 0 ] != FS_ERROR ) hb_fsCloseRaw( hPipeErr[ 0 ] ); if( hPipeErr[ 1 ] != FS_ERROR ) hb_fsCloseRaw( hPipeErr[ 1 ] ); } return hResult; }
int main(int argc, char *argv[]) { char buf[1024]; char *vec[8192]; char *fvec[200]; char **svec; char type[64]; int i; int vp=2; #ifndef _WIN32 pid_t pid; #endif if(chdir(getenv("TOPDIR"))) { perror("chdir"); exit(1); } /* * Build the exec array ahead of time. */ vec[0]="kernel-doc"; vec[1]="-docbook"; for(i=1;vp<8189;i++) { if(argv[i]==NULL) break; vec[vp++]=type; vec[vp++]=argv[i]; } vec[vp++]=buf+2; vec[vp++]=NULL; /* * Now process the template */ while(fgets(buf, 1024, stdin)) { if(*buf!='!') { printf("%s", buf); continue; } fflush(stdout); svec = vec; if(buf[1]=='E') strcpy(type, "-function"); else if(buf[1]=='I') strcpy(type, "-nofunction"); else if(buf[1]=='F') { int snarf = 0; fvec[0] = "kernel-doc"; fvec[1] = "-docbook"; strcpy (type, "-function"); vp = 2; for (i = 2; buf[i]; i++) { if (buf[i] == ' ' || buf[i] == '\n') { buf[i] = '\0'; snarf = 1; continue; } if (snarf) { snarf = 0; fvec[vp++] = type; fvec[vp++] = &buf[i]; } } fvec[vp++] = &buf[2]; fvec[vp] = NULL; svec = fvec; } else { fprintf(stderr, "Unknown ! escape.\n"); exit(1); } #ifdef _WIN32 if(!_spawnvp(_P_WAIT, "doc/kernel-doc", svec)) { perror("exec scripts/kernel-doc"); exit(1); } #else switch(pid=fork()) { case -1: perror("fork"); exit(1); case 0: execvp("doc/kernel-doc", svec); perror("exec scripts/kernel-doc"); exit(1); default: waitpid(pid, NULL,0); } #endif } exit(0); }