--- parser3/src/main/pa_exec.C 2002/04/16 09:38:49 1.35 +++ parser3/src/main/pa_exec.C 2002/12/26 11:47:59 1.47 @@ -4,12 +4,11 @@ Copyright(c) 2000,2001, 2002 ArtLebedev Group(http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) - $Id: pa_exec.C,v 1.35 2002/04/16 09:38:49 paf Exp $ - - @todo setrlimit */ +static const char* IDENT_EXEC_C="$Date: 2002/12/26 11:47:59 $"; + #include "pa_config_includes.h" #include "pa_exec.h" @@ -27,14 +26,15 @@ #ifdef WIN32 /// this func from http://www.ccas.ru/~posp/popov/spawn.htm -static BOOL WINAPI CreateHiddenConsoleProcess(LPCTSTR szCmdLine, +static DWORD CreateHiddenConsoleProcess(LPCTSTR szCmdLine, char *szEnv, PROCESS_INFORMATION* ppi, LPHANDLE phInWrite, LPHANDLE phOutRead, LPHANDLE phErrRead) { - BOOL fCreated; + DWORD result=0; + BOOL fCreated; STARTUPINFO si; SECURITY_ATTRIBUTES sa={0}; HANDLE hInRead; @@ -88,6 +88,8 @@ static BOOL WINAPI CreateHiddenConsolePr dir, &si, ppi); + if(!fCreated) + result=GetLastError(); CloseHandle(hInRead); CloseHandle(hOutWrite); @@ -96,14 +98,17 @@ static BOOL WINAPI CreateHiddenConsolePr if(!fCreated) goto error; - return TRUE; + return result; error: + if(!result/*yet*/) + result=GetLastError(); // get it + CloseHandle(*phInWrite); CloseHandle(*phOutRead); CloseHandle(*phErrRead); - return FALSE; + return result; } static void read_pipe(String& result, HANDLE hOutRead, const char *file_spec, @@ -136,9 +141,6 @@ static const char *buildCommand(Pool& po string.APPEND_AS_IS(begin, end-begin, origin_string.origin().file, 0); string << " " << file_spec_cstr; - if(argv) - for(int i=0; isize(); i++) - string << argv->get_string(i)->cstr(); result=string.cstr(); } } @@ -161,10 +163,10 @@ static const char *buildCommand(Pool& po #else -static int execve_piped(const char *file_spec_cstr, +static pid_t execve_piped(const char *file_spec_cstr, char * const argv[], char * const env[], int *pipe_in, int *pipe_out, int *pipe_err) { - int pid; + pid_t pid; int in_fds[2]; int out_fds[2]; int err_fds[2]; @@ -209,7 +211,7 @@ static int execve_piped(const char *file close(err_fds[0]); close(err_fds[1]); } errno=save_errno; - return 0; + return -1; } if(!pid) { @@ -233,7 +235,8 @@ static int execve_piped(const char *file close(err_fds[1]); } - /* HP-UX SIGCHLD fix goes here, if someone will remind me what it is... */ + /* grabbed this from Apache source: */ + /* HP-UX SIGCHLD fix goes here, if someone will remind me what it is... */ signal(SIGCHLD, SIG_DFL); /* Was that it? */ // chdir to script's directory @@ -278,8 +281,8 @@ static int get_exit_status(int pid) { static void read_pipe(String& result, int file, const char *file_spec, String::Untaint_lang lang){ while(true) { char *buf=(char *)result.pool().malloc(MAX_STRING); - size_t size=read(file, buf, MAX_STRING); - if(!size) + ssize_t size=read(file, buf, MAX_STRING); + if(size<=0) break; result.APPEND(buf, size, lang, file_spec, 0); } @@ -299,7 +302,7 @@ static void append_env_pair(const Hash:: string << key << "=" << *static_cast(value); char ***env_ref=static_cast(info); - **env_ref=string.cstr(); (*env_ref)++; + **env_ref=string.cstr(String::UL_UNSPECIFIED); (*env_ref)++; #endif } @@ -328,9 +331,23 @@ int pa_exec( if(env) { String string(env->pool()); env->for_each(append_env_pair, &string); - env_cstr=string.cstr(); + env_cstr=string.cstr(String::UL_UNSPECIFIED); } - if(CreateHiddenConsoleProcess(cmd, env_cstr, &pi, &hInWrite, &hOutRead, &hErrRead)) { + if(DWORD error=CreateHiddenConsoleProcess(cmd, env_cstr, &pi, &hInWrite, &hOutRead, &hErrRead)) { + char szErrorDesc[MAX_STRING]; + char *param="the file you tried to run"; + size_t error_size=FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ARGUMENT_ARRAY , NULL, error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), + szErrorDesc, sizeof(szErrorDesc), ¶m); + if(error_size>3) // ".\r\n" + szErrorDesc[error_size-3]=0; + + throw Exception(0, + &file_spec, + "exec failed - %s (%ld). Consider adding shbang line (#!x:\\interpreter\\command line)", + error_size?szErrorDesc:"", (long)error); + } else { const char *in_cstr=in.cstr(); DWORD written_size; WriteFile(hInWrite, in_cstr, in.size(), &written_size, NULL); @@ -351,21 +368,6 @@ from http://www.apache.org/websrc/cvsweb */ CloseHandle(pi.hProcess); CloseHandle(pi.hThread); - } else { - DWORD error=GetLastError(); - char szErrorDesc[MAX_STRING]; - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, - MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), - szErrorDesc, sizeof(szErrorDesc), NULL); - size_t error_size=strlen(szErrorDesc); - if(error_size>3) // ".\r\n" - szErrorDesc[error_size-3]=0; - - throw Exception(0, - &file_spec, - "(real command line=\"%s\") exec failed - %s (%ld)", - cmd, - szErrorDesc, (long)error); } #else @@ -373,7 +375,7 @@ from http://www.apache.org/websrc/cvsweb int pipe_write, pipe_read, pipe_err; char *file_spec_cstr=file_spec.cstr(String::UL_FILE_SPEC); -#ifdef NO_FOREIGN_GROUP_FILES +#ifdef PA_SAFE_MODE if(!forced_allow) { struct stat finfo; if(stat(file_spec_cstr, &finfo)!=0) @@ -382,10 +384,11 @@ from http://www.apache.org/websrc/cvsweb "stat failed: %s (%d), actual filename '%s'", strerror(errno), errno, file_spec_cstr); - if(finfo.st_gid/*foreign?*/!=getegid()) - throw Exception("parser.runtime", - &file_spec, - "parser executing files of foreign group is disabled [recompile parser without --disable-foreign-group-files configure option], actual filename '%s'", + if(finfo.st_uid/*foreign?*/!=geteuid() + && finfo.st_gid/*foreign?*/!=getegid()) + throw Exception("parser.runtime", + &file_spec, + "parser is in safe mode: executing files of foreign group and user disabled [recompile parser with --disable-safe-mode configure option], actual filename '%s'", file_spec_cstr); } #endif @@ -411,14 +414,15 @@ from http://www.apache.org/websrc/cvsweb *env_ref=0; } - int pid=execve_piped( + pid_t pid=execve_piped( file_spec_cstr, argv_cstrs, env_cstrs, &pipe_write, &pipe_read, &pipe_err); - if(pid) { + if(pid>0) { // in child const char *in_cstr=in.cstr(); - write(pipe_write, in_cstr, in.size()); + if(*in_cstr) // there is some in data + write(pipe_write, in_cstr, in.size()); close(pipe_write); read_pipe(out, pipe_read, file_spec_cstr, String::UL_AS_IS); close(pipe_read); @@ -429,7 +433,7 @@ from http://www.apache.org/websrc/cvsweb } else throw Exception(0, &file_spec, - "pipe error"); + "%s error: %s (%d)", pid<0?"fork":"pipe", strerror(errno), errno); #endif return 0;