--- parser3/src/main/pa_exec.C 2001/08/02 09:58:34 1.9 +++ parser3/src/main/pa_exec.C 2002/02/26 13:45:12 1.26 @@ -1,14 +1,21 @@ /** @file Parser: program executing for different OS-es. - Copyright(c) 2000,2001 ArtLebedev Group(http://www.artlebedev.com) + Copyright(c) 2000,2001, 2002 ArtLebedev Group(http://www.artlebedev.com) + Author: Alexandr Petrosian (http://paf.design.ru) - Author: Alexander Petrosyan (http://design.ru/paf) + $Id: pa_exec.C,v 1.26 2002/02/26 13:45:12 paf Exp $ + + + @todo setrlimit */ -static const char *RCSId="$Id: pa_exec.C,v 1.9 2001/08/02 09:58:34 parser Exp $"; #include "pa_config_includes.h" +#include "pa_exec.h" +#include "pa_exception.h" +#include "pa_common.h" + #ifdef WIN32 # include #else @@ -17,18 +24,10 @@ static const char *RCSId="$Id: pa_exec.C # include #endif -#include -#include - -#include "pa_exec.h" -#include "pa_exception.h" -#include "pa_common.h" - - #ifdef WIN32 /// this func from http://www.ccas.ru/~posp/popov/spawn.htm -static BOOL WINAPI CreateHiddenConsoleProcess(LPCTSTR szChildName, +static BOOL WINAPI CreateHiddenConsoleProcess(LPCTSTR szCmdLine, char *szEnv, PROCESS_INFORMATION* ppi, LPHANDLE phInWrite, @@ -73,7 +72,7 @@ static BOOL WINAPI CreateHiddenConsolePr // Create a child process (suspended) fCreated=CreateProcess(NULL, - (LPTSTR)szChildName, + (LPTSTR)szCmdLine, NULL, NULL, TRUE, @@ -132,7 +131,7 @@ static const char *buildCommand(Pool& po string << " " << file_spec_cstr; if(argv) for(int i=0; isize(); i++) - string << argv->get_string(i)->cstr(String::UL_AS_IS); + string << argv->get_string(i)->cstr(); result=string.cstr(); } } @@ -147,7 +146,7 @@ static const char *buildCommand(Pool& po buf << *argv->get_string(i); } - result=buf.cstr(String::UL_AS_IS); + result=buf.cstr(); } return result; @@ -235,7 +234,7 @@ static int execle_piped(const char *path /* HP-UX SIGCHLD fix goes here, if someone will remind me what it is... */ signal(SIGCHLD, SIG_DFL); /* Was that it? */ - execle(path, arg1, arg2, arg3, arg4, arg5, NULL, env); + execle(path, path, arg1, arg2, arg3, arg4, arg5, NULL, env); exit(-errno); } @@ -303,23 +302,23 @@ int pa_exec(const String& file_spec, char pwd[MAX_STRING]; GetCurrentDirectory(sizeof(pwd), pwd); - char *dir=file_spec.cstr(String::UL_FILE_NAME); + char *dir=file_spec.cstr(String::UL_FILE_SPEC); rsplit(dir, '/'); SetCurrentDirectory(dir); PROCESS_INFORMATION pi; HANDLE hInWrite, hOutRead, hErrRead; - char *file_spec_cstr=file_spec.cstr(String::UL_FILE_NAME); + char *file_spec_cstr=file_spec.cstr(String::UL_FILE_SPEC); const char *cmd=buildCommand(file_spec.pool(), file_spec, file_spec_cstr, argv); char *env_cstr=0; if(env) { String string(env->pool()); env->for_each(append_env_pair, &string); - env_cstr=string.cstr(String::UL_AS_IS); + env_cstr=string.cstr(); } if(CreateHiddenConsoleProcess(cmd, env_cstr, &pi, &hInWrite, &hOutRead, &hErrRead)) { SetCurrentDirectory(pwd); - const char *in_cstr=in.cstr(String::UL_AS_IS); + const char *in_cstr=in.cstr(); DWORD written_size; WriteFile(hInWrite, in_cstr, in.size(), &written_size, NULL); // EOF for stupid text reads @@ -351,23 +350,31 @@ from http://www.apache.org/websrc/cvsweb if(error_size>3) // ".\r\n" szErrorDesc[error_size-3]=0; - PTHROW(0, 0, + throw Exception(0, 0, &file_spec, - "exec failed - %s (%d)", - szErrorDesc, - (long)error); + "(real command line=\"%s\") exec failed - %s (%ld)", + cmd, + szErrorDesc, (long)error); } #else int pipe_write, pipe_read, pipe_err; - const char *argv_cstrs[5]={"", "", "", "", ""}; + const char *argv_cstrs[10]={ + "", "", "", "", "", + "", "", "", "", "" + }; if(argv) { - int size=min(5, argv->size()); - for(int i=0; iget_string(i)->cstr(String::UL_AS_IS); + const int argv_size=argv->size(); + const int argv_max=sizeof(argv_cstrs)/sizeof(argv_cstrs[0]); + if(argv_size>argv_max) + throw Exception(0, 0, + &file_spec, + "too many arguments (%d > max %d)", argv_size, argv_max); + for(int i=0; iget_string(i)->cstr(); } - const char *file_spec_cstr=file_spec.cstr(String::UL_FILE_NAME); + const char *file_spec_cstr=file_spec.cstr(String::UL_FILE_SPEC); char **env_cstrs=0; if(env) { env_cstrs= @@ -376,14 +383,22 @@ from http://www.apache.org/websrc/cvsweb env->for_each(append_env_pair, &env_ref); *env_ref=0; } - if(int pid=execle_piped( + const char *pwd=getcwd(NULL, 0); + char dir[MAX_STRING]; + strncpy(dir, file_spec_cstr, MAX_STRING); + rsplit(dir,'/'); // trim filename + chdir(dir); + int pid=execle_piped( file_spec_cstr, argv_cstrs[0], argv_cstrs[1], argv_cstrs[2], argv_cstrs[3], argv_cstrs[4], argv_cstrs[5], argv_cstrs[6], argv_cstrs[7], argv_cstrs[8], argv_cstrs[9], env_cstrs, - &pipe_write, &pipe_read, &pipe_err)) { - - const char *in_cstr=in.cstr(String::UL_AS_IS); + &pipe_write, &pipe_read, &pipe_err); + if (pwd) + chdir(pwd); + if(pid) { + // in child + const char *in_cstr=in.cstr(); write(pipe_write, in_cstr, in.size()); close(pipe_write); read_pipe(out, pipe_read, file_spec_cstr); @@ -393,7 +408,7 @@ from http://www.apache.org/websrc/cvsweb return get_exit_status(pid); // negative may mean "-errno[execl()]" } else - PTHROW(0, 0, + throw Exception(0, 0, &file_spec, "pipe error"); #endif