Diff for /parser3/src/main/pa_exec.C between versions 1.1 and 1.10

version 1.1, 2001/04/09 16:04:50 version 1.10, 2001/08/06 12:27:46
Line 4 Line 4
         Copyright(c) 2000,2001 ArtLebedev Group(http://www.artlebedev.com)          Copyright(c) 2000,2001 ArtLebedev Group(http://www.artlebedev.com)
   
         Author: Alexander Petrosyan <paf@design.ru>(http://design.ru/paf)          Author: Alexander Petrosyan <paf@design.ru>(http://design.ru/paf)
   
         $Id$  
 */  */
   static const char *RCSId="$Id$"; 
   
 #include "pa_config_includes.h"  #include "pa_config_includes.h"
   
Line 29 Line 28
 #ifdef WIN32  #ifdef WIN32
   
 /// this func from http://www.ccas.ru/~posp/popov/spawn.htm  /// this func from http://www.ccas.ru/~posp/popov/spawn.htm
 static BOOL WINAPI CreateHiddenConsoleProcess( LPCTSTR szChildName,  static BOOL WINAPI CreateHiddenConsoleProcess(LPCTSTR szChildName,
                                                                                 char *szEnv,                                                                                  char *szEnv,
                                         PROCESS_INFORMATION* ppi,                                           PROCESS_INFORMATION* ppi, 
                                         LPHANDLE phInWrite,                                          LPHANDLE phInWrite,
                                         LPHANDLE phOutRead,                                          LPHANDLE phOutRead,
                                         LPHANDLE phErrRead )                                          LPHANDLE phErrRead)
 {  {
     BOOL fCreated;      BOOL fCreated;
     STARTUPINFO si;      STARTUPINFO si;
Line 45  static BOOL WINAPI CreateHiddenConsolePr Line 44  static BOOL WINAPI CreateHiddenConsolePr
   
     // Create pipes      // Create pipes
     // initialize security attributes for handle inheritance (for WinNT)      // initialize security attributes for handle inheritance (for WinNT)
     sa.nLength = sizeof( sa );      sa.nLength=sizeof(sa);
     sa.bInheritHandle = TRUE;      sa.bInheritHandle=TRUE;
     sa.lpSecurityDescriptor  = NULL;      sa.lpSecurityDescriptor=NULL;
   
     // create STDIN pipe      // create STDIN pipe
     if( !CreatePipe( &hInRead, phInWrite, &sa, 0 ))      if(!CreatePipe(&hInRead, phInWrite, &sa, 0))
         goto error;          goto error;
   
     // create STDOUT pipe      // create STDOUT pipe
     if( !CreatePipe( phOutRead, &hOutWrite, &sa, 0 ))      if(!CreatePipe(phOutRead, &hOutWrite, &sa, 0))
         goto error;          goto error;
   
     // create STDERR pipe      // create STDERR pipe
     if( !CreatePipe( phErrRead, &hErrWrite, &sa, 0 ))      if(!CreatePipe(phErrRead, &hErrWrite, &sa, 0))
         goto error;          goto error;
   
     // process startup information      // process startup information
     memset( &si, 0, sizeof( si ));      memset(&si, 0, sizeof(si));
     si.cb = sizeof( si );       si.cb=sizeof(si); 
     si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;      si.dwFlags=STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
     // child process' console must be hidden for Win95 compatibility      // child process' console must be hidden for Win95 compatibility
     si.wShowWindow = SW_HIDE;      si.wShowWindow=SW_HIDE;
     // assign "other" sides of pipes      // assign "other" sides of pipes
 //    si.hStdInput = hInRead;      si.hStdInput=hInRead;
     si.hStdOutput = hOutWrite;      si.hStdOutput=hOutWrite;
     si.hStdError = hErrWrite;      si.hStdError=hErrWrite;
   
     // Create a child process (suspended)      // Create a child process (suspended)
     fCreated = CreateProcess( NULL,      fCreated=CreateProcess(NULL,
                               (LPTSTR)szChildName,                                (LPTSTR)szChildName,
                               NULL,                                NULL,
                               NULL,                                NULL,
                               TRUE,                                TRUE,
                               DETACHED_PROCESS,                                0, //todo CREATE_NO_WINDOW,
                               szEnv,                                szEnv,
                               NULL,                                NULL,
                               &si,                                &si,
                               ppi );                                ppi);
   
     CloseHandle( hInRead );      CloseHandle(hInRead);
     CloseHandle( hOutWrite );      CloseHandle(hOutWrite);
     CloseHandle( hErrWrite );      CloseHandle(hErrWrite);
   
     if( !fCreated )      if(!fCreated)
         goto error;          goto error;
   
     return TRUE;      return TRUE;
   
 error:  error:
     CloseHandle( *phInWrite );      CloseHandle(*phInWrite);
     CloseHandle( *phOutRead );      CloseHandle(*phOutRead);
     CloseHandle( *phErrRead );      CloseHandle(*phErrRead);
   
     return FALSE;      return FALSE;
 }  }
   
 static read_pipe(String& result, HANDLE hOutRead, const char *file_spec){  static void read_pipe(String& result, HANDLE hOutRead, const char *file_spec){
         while(true) {          while(true) {
                 char *buf=(char *)result.pool().malloc(MAX_STRING);                  char *buf=(char *)result.pool().malloc(MAX_STRING);
                 unsigned long size;                  unsigned long size;
                 ReadFile( hOutRead, buf, MAX_STRING, &size, NULL );                  ReadFile(hOutRead, buf, MAX_STRING, &size, NULL);
                 if(!size)                   if(!size) 
                         break;                          break;
                 result.APPEND_CLEAN(buf, size, file_spec, 0);                  result.APPEND_AS_IS(buf, size, file_spec, 0);
     }      }
 }  }
   
Line 116  static read_pipe(String& result, HANDLE Line 115  static read_pipe(String& result, HANDLE
 static const char *buildCommand(Pool& pool,   static const char *buildCommand(Pool& pool, 
                                                                 const String& origin_string,                                                                  const String& origin_string,
                                                                 const char *file_spec_cstr, const Array *argv) {                                                                  const char *file_spec_cstr, const Array *argv) {
         FILE *f=fopen(file_spec_cstr, "r");          const char *result=file_spec_cstr;
         if(f) {          if(FILE *f=fopen(file_spec_cstr, "r")) {
                 char buf[MAX_STRING];                  char buf[MAX_STRING];
                 size_t size=fread(buf, 1, MAX_STRING-1, f);                  size_t size=fread(buf, 1, MAX_STRING-1, f);
                 if(size>2) {                  if(size>2) {
                         buf[size]=0;                          buf[size]=0;
                         if(strncmp(buf, "#!", 2)==0) {                          if(strncmp(buf, "#!", 2)==0) {
                                 char *atEOL=strchr(buf, '\n');                                  const char *begin=buf+2;
                                 if(atEOL) {                                  if(*begin==' ') // alx: were an old magic for some linux-es
                                           begin++;
                                   if(char *end=strchr(begin, '\n')) {
                                         String string(pool);                                          String string(pool);
                                         string.APPEND_CLEAN(buf+2, atEOL-(buf+2),                                           string.APPEND_AS_IS(begin, end-begin, 
                                                 origin_string.origin().file, 0);                                                  origin_string.origin().file, 0);
                                         string << " " << file_spec_cstr;                                          string << " " << file_spec_cstr;
                                         if(argv)                                          if(argv)
                                                 for(int i=0; i<argv->size(); i++)                                                  for(int i=0; i<argv->size(); i++)
                                                         string << argv->get_string(i)->cstr(String::UL_AS_IS);                                                          string << argv->get_string(i)->cstr(String::UL_AS_IS);
                                         file_spec_cstr=string.cstr();                                          result=string.cstr();
                                 }                                  }
                         }                          }
                 }                  }
                 fclose(f);                  fclose(f);
         }          }
         return file_spec_cstr;          if(argv) {
                   String buf(pool);
                   buf << result;
                   for(int i=0; i<argv->size(); i++) {
                           buf << " ";
                           buf << *argv->get_string(i);
                   }
   
                   result=buf.cstr(String::UL_AS_IS);
           }
   
           return result;
 }  }
   
 #else  #else
   
 static int execle_piped(const char *path,   static int execle_piped(const char *path, 
                                                 const char *arg1,                                                  const char *arg1, const char *arg2,
                                                 const char *arg2,                                                  const char *arg3, const char *arg4,
                                                 const char *arg3,                                                  const char *arg5, const char *arg6,
                                                 const char *arg4,                                                  const char *arg7, const char *arg8,
                                                 const char *arg5,                                                  const char *arg9, const char *arg10,
                                                 char * const env[],                                                  char * const env[],
                                                 int *pipe_in, int *pipe_out, int *pipe_err) {                                                  int *pipe_in, int *pipe_out, int *pipe_err) {
         int pid;          int pid;
Line 255  static int get_exit_status(int pid) { Line 267  static int get_exit_status(int pid) {
                 WEXITSTATUS(status) : -2;                  WEXITSTATUS(status) : -2;
 }  }
   
 static read_pipe(String& result, int file, const char *file_spec){  static void read_pipe(String& result, int file, const char *file_spec){
         while(true) {          while(true) {
                 char *buf=(char *)pool.malloc(MAX_STRING);                  char *buf=(char *)result.pool().malloc(MAX_STRING);
                 size_t size=read(file, buf, MAX_STRING);                  size_t size=read(file, buf, MAX_STRING);
                 if(!size)                   if(!size) 
                         break;                          break;
                 result.APPEND_CLEAN(buf, size, file_spec, 0);                  result.APPEND_AS_IS(buf, size, file_spec, 0);
     }      }
 }  }
   
Line 272  static void append_env_pair(const Hash:: Line 284  static void append_env_pair(const Hash::
         String& string=*static_cast<String *>(info);          String& string=*static_cast<String *>(info);
                   
         string << key << "=" << *static_cast<String *>(value);          string << key << "=" << *static_cast<String *>(value);
         string.APPEND_CLEAN("", 1, 0, 0); // zero byte          string.APPEND_AS_IS("", 1, 0, 0); // zero byte
 #else  #else
         String string(key.pool());          String string(key.pool());
         string << key << "=" << *static_cast<String *>(value);          string << key << "=" << *static_cast<String *>(value);
   
         char **env_ptr=static_cast<char **>(info);          char ***env_ref=static_cast<char ***>(info);
         *env_ptr++=string.cstr();          **env_ref=string.cstr();  (*env_ref)++;
 #endif  #endif
 }  }
 int pa_exec(const String& file_spec,   int pa_exec(const String& file_spec, 
Line 304  int pa_exec(const String& file_spec, Line 316  int pa_exec(const String& file_spec,
                 env->for_each(append_env_pair, &string);                  env->for_each(append_env_pair, &string);
                 env_cstr=string.cstr(String::UL_AS_IS);                  env_cstr=string.cstr(String::UL_AS_IS);
         }          }
         if( CreateHiddenConsoleProcess(cmd, env_cstr, &pi, &hInWrite, &hOutRead, &hErrRead )) {          if(CreateHiddenConsoleProcess(cmd, env_cstr, &pi, &hInWrite, &hOutRead, &hErrRead)) {
                 SetCurrentDirectory(pwd);                  SetCurrentDirectory(pwd);
   
                   const char *in_cstr=in.cstr(String::UL_AS_IS);
                   DWORD written_size;
                   WriteFile(hInWrite, in_cstr, in.size(), &written_size, NULL);
                   // EOF for stupid text reads
                   // normally they should read CONTENT_LENGTH bytes,
                   // without this char
                   WriteFile(hInWrite, "\x1A", 1, &written_size, NULL);
                   CloseHandle(hInWrite);
                 read_pipe(out, hOutRead, file_spec_cstr);                  read_pipe(out, hOutRead, file_spec_cstr);
                 read_pipe(err, hErrRead, file_spec_cstr);                  CloseHandle(hOutRead);
                 CloseHandle( hInWrite );                  read_pipe(err, hErrRead, file_spec_cstr);               
                 CloseHandle( hOutRead );                  CloseHandle(hErrRead);
                 CloseHandle( hErrRead );  
 /*        /*      
 from http://www.apache.org/websrc/cvsweb.cgi/apache-1.3/src/main/util_script.c?rev=1.151&content-type=text/vnd.viewcvs-markup  from http://www.apache.org/websrc/cvsweb.cgi/apache-1.3/src/main/util_script.c?rev=1.151&content-type=text/vnd.viewcvs-markup
   
Line 334  from http://www.apache.org/websrc/cvsweb Line 353  from http://www.apache.org/websrc/cvsweb
                           
                 PTHROW(0, 0,                  PTHROW(0, 0,
                         &file_spec,                          &file_spec,
                         "exec failed - %s (%d)",                          "(real filename=\"%s\") exec failed - %s (%ld)",
                                 szErrorDesc,                                  cmd
                                 (long)error);                                  szErrorDesc, (long)error);
         }          }
   
 #else  #else
   
         int pipe_write, pipe_read, pipe_err;          int pipe_write, pipe_read, pipe_err;
         const char *argv_cstr[5]={"", "", "", "", ""};          const char *argv_cstrs[5]={"", "", "", "", ""};
         if(argv) {          if(argv) {
                 int size=min(5, argv->size());                  int size=min(5, argv->size());
                 for(int i=0; i<size; i++)                  for(int i=0; i<size; i++)
                         argv_cstr[i]=argv->get_string(i).cstr(String::UL_AS_IS);                          argv_cstrs[i]=argv->get_string(i)->cstr(String::UL_AS_IS);
         }          }
         const char *file_spec_cstr=file_spec->cstr(String::UL_FILE_NAME);          const char *file_spec_cstr=file_spec.cstr(String::UL_FILE_NAME);
         char **env_cstr=0;          char **env_cstrs=0;
         if(env) {          if(env) {
                 env_cstr_array=                  env_cstrs=
                         (char **)env->pool().malloc(sizeof(char *)*(env->size()+1/*0*/));                          (char **)env->pool().malloc(sizeof(char *)*(env->size()+1/*0*/));
                 char **env_ptr=env_cstr_array;                  char **env_ref=env_cstrs;
                 env->for_each(append_env_pair, &env_ptr);                  env->for_each(append_env_pair, &env_ref);
                 *env_ptr=0;                  *env_ref=0;
         }          }
         if(int pid=execle_piped(sendmail_filespec,           if(int pid=execle_piped(
                 file_spec_cstr,                  file_spec_cstr,
                 argv_cstr[0], argv_cstr[1], argv_cstr[2], argv_cstr[3], argv_cstr[4],                  argv_cstrs[0], argv_cstrs[1], argv_cstrs[2], argv_cstrs[3], argv_cstrs[4],
                 env_cstr,                  argv_cstrs[5], argv_cstrs[6], argv_cstrs[7], argv_cstrs[8], argv_cstrs[9],
                   env_cstrs,
                 &pipe_write, &pipe_read, &pipe_err)) {                  &pipe_write, &pipe_read, &pipe_err)) {
   
                 const char *in_cstr=in.cstr(String::UL_AS_IS);                  const char *in_cstr=in.cstr(String::UL_AS_IS);
                 write(pipe_write, in_cstr, in.size());                  write(pipe_write, in_cstr, in.size());
                 close(pipe_write);                  close(pipe_write);
                 read_pipe(out, pipe_read, file_spec_cstr);                  read_pipe(out, pipe_read, file_spec_cstr);
                 read_pipe(err, pipe_err, file_spec_cstr);  
                 close(pipe_read);                  close(pipe_read);
                   read_pipe(err, pipe_err, file_spec_cstr);
                 close(pipe_err);                  close(pipe_err);
   
                 return get_exit_status(pid); // negative may mean "-errno[execl()]"                  return get_exit_status(pid); // negative may mean "-errno[execl()]"
         } else           } else 
                 PTHROW(0, 0,                  PTHROW(0, 0,
                         file_spec,                          &file_spec,
                         "pipe error");                          "pipe error");
 #endif  #endif
   

Removed from v.1.1  
changed lines
  Added in v.1.10


E-mail: