Changeset a94fd1c in tol


Ignore:
Timestamp:
Sep 4, 2014, 5:36:38 PM (12 years ago)
Author:
Pedro Gea <pgea@…>
Branches:
1941-docker-image-to-test, devel, master
Children:
11f43fe
Parents:
5a1c981
Message:

Refs #1118

Se separa parte del cuerpo del método void BSetPExec::CalcContens() y se traslada a un procedimiento en BSys (BSys::PExecQuiet) que es donde se encuentran las funcionalidades con llamadas al sistema operativo.
Se redirige la salida estándar de errores de la llamada a pexec a un archivo para poder capturarla y así detectar las llamadas con errores. Se usa un mecanismo similar al que usa WinSystem para capturar los errores de las llamadas precedidas por cmd.
Sin embargo, no parece que hay forma de evitar que la ventana de la consola aparezca al ejecutar PExec con Windows.

Para evitar la ventana de la consola, se crea un nuevo procedimiento en BSys (BSys::WinSystemQuiet) parecido al de PExec y que permite realizar la llamada y obtener las salidas sin mostrar la ventana.
Se crea un nuevo par de funciones AnsSystem y AnsSystemQuiet que permiten realizar llamadas al sistema operativo y obtener su respuesta y que se redirigen a BSys::WinSystemQuiet y BSys::PExecQuiet según el sistema operativo sea Windows o no.
La primera: AnsSystem devuelve la salida estándar de la llamada y muestra los errores en caso de haberlos.
La segunda: AnsSystemQuiet devuelve un conjunto con el estado de la llamada al proceso y las salidas estándar y de errores. Con esta función TOL no muestra los errores.

git-svn-id: ​https://www.tol-project.org/svn/tolp/trunk@6280 be4846ae-f051-483a-831f-b64e7d08527f

Location:
tol
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • tol/bbasic/sys.cpp

    r5a1c981 ra94fd1c  
    381381
    382382#ifndef UNIX
     383
    383384//--------------------------------------------------------------------
    384385BBool BSys::WinExecuteFile(const BText& fileName)
    … …  
    435436
    436437//--------------------------------------------------------------------
    437   BBool BSys::WinSystem  (const BText& command, BInt showMode, bool wait)
     438BBool BSys::WinSystem  (const BText& command, BInt showMode, bool wait)
    438439//--------------------------------------------------------------------
    439440{
    … …  
    493494      }
    494495    }
    495     else if(wait)
     496    else if(wait) //(pgea) y esto ?
    496497    {
    497498      result=WaitForSingleObject(piProcInfo.hProcess, 0);
    … …  
    508509}
    509510
    510 
    511 //--------------------------------------------------------------------
    512 //BBool BSys::WinSystem  (const BText& command, BInt showMode)
    513 
    514 /*! Windows operating system call.
    515  * /
    516 //--------------------------------------------------------------------
    517 {
    518   BInt errNum = WinExec(command.String(),showMode);
    519  
    520   BBool err=(errNum<=31);
    521   BText msg;
    522   switch(errNum)
    523   {
    524     case 0:
     511//--------------------------------------------------------------------
     512BBool BSys::WinSystemQuiet(const BText& command,
     513                           BText& output, BText& error)
     514//--------------------------------------------------------------------
     515{
     516  SetLastError(0);
     517
     518  SECURITY_ATTRIBUTES secattr;
     519  memset(&secattr, 0, sizeof(secattr));
     520  secattr.nLength = sizeof(secattr);
     521  secattr.bInheritHandle = TRUE;
     522  HANDLE rPipe, wPipe, rPipeE, wPipeE;
     523  CreatePipe(&rPipe,&wPipe,&secattr,0);
     524  CreatePipe(&rPipeE,&wPipeE,&secattr,0);
     525
     526  STARTUPINFO sInfo;
     527  memset(&sInfo, 0, sizeof(sInfo));
     528  PROCESS_INFORMATION pInfo;
     529  memset(&pInfo, 0, sizeof(pInfo));
     530  sInfo.cb = sizeof(sInfo);
     531  sInfo.dwFlags = STARTF_USESTDHANDLES;
     532  sInfo.hStdInput = NULL;
     533  sInfo.hStdOutput = wPipe;
     534  sInfo.hStdError = wPipeE;
     535
     536  BText cmdRedirected = BText("cmd /c ") + command;
     537  char* cmd = (char*)cmdRedirected.String();
     538
     539  int result = 0;
     540  bool ok = true;
     541
     542  if (!CreateProcess(NULL, cmd, NULL, NULL,
     543       TRUE, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
     544       NULL, NULL, &sInfo, &pInfo))
     545  {
     546    error = I2("Creating process \n",
     547               "Creando el proceso \n") + command;
     548    ok = false;
     549  }
     550  else
     551  {
     552    result = WaitForSingleObject(pInfo.hProcess, INFINITE);
     553    if(result != WAIT_OBJECT_0)
    525554    {
    526       msg = I2("The system is out of memory or resources.",
    527                "El sistema no tiene memoria o recursos");
    528       break;
    529     }
    530     case ERROR_BAD_FORMAT:
     555      error = I2("Waiting for result of process \n",
     556                 "Esperando el resultado del proceso \n") +  command;
     557      ok = false;
     558    }
     559    else
    531560    {
    532       msg = I2("The .EXE file is invalid","El fichero .EXE no es válido.");
    533       break;
    534     }
    535     case ERROR_FILE_NOT_FOUND:
    536     {
    537       msg = I2("The specified file was not found.",
    538                "No se encuentra el fichero especificado");
    539       break;
    540     }
    541     case ERROR_PATH_NOT_FOUND :
    542     {
    543       msg = I2("The specified path was not found.",
    544                "No se encuentra el camino especificado.");
    545     }
    546   }
    547   if(err)
    548   {
    549     Error(I2("Executing commad \n", "Ejecutando el comando \n") +
    550               command + "\n" + msg);
    551   }
    552   return(!err);
    553 }
    554 */
    555 
    556 #else
    557 
    558 
    559 #endif
    560 
    561 
     561      CloseHandle(wPipe);
     562      CloseHandle(wPipeE);
     563
     564      BChar buffer[128];
     565      DWORD reDword;
     566      BOOL res = false;
     567      do {
     568        res=::ReadFile(rPipe, buffer, 128, &reDword, 0);
     569        output += BText(buffer,0,reDword-1);
     570      } while(res);
     571      res = false;
     572      do {
     573        res=::ReadFile(rPipeE, buffer, 128, &reDword, 0);
     574        error += BText(buffer,0,reDword-1);
     575      } while(res);
     576
     577      if(error.HasName()) {
     578        ok = false;
     579      } else {
     580        ok = true;
     581      }
     582    }
     583  }
     584  return(ok); 
     585}
     586
     587#endif
     588
     589//--------------------------------------------------------------------
     590BBool BSys::PExecQuiet(const BText& command,
     591                       BText& output, BText& error)
     592//--------------------------------------------------------------------
     593{
     594  SetLastError(0);
     595  BText errNam = BSys::TempNam();
     596  BText cmdRedirected = command + BText(" 2> ") + errNam;
     597  bool ok = false;
     598  FILE* pipe = popen(cmdRedirected, "r");
     599  if(pipe) {
     600    char buffer[128];
     601    output = "";
     602    while(!feof(pipe)) {
     603      if(fgets(buffer, 128, pipe) != NULL)
     604        output += buffer;
     605    }
     606    pclose(pipe);
     607    if(CheckIsFile(errNam)) {
     608      ReadFile(error,errNam);
     609      remove(errNam.String());
     610    }
     611    if(error.HasName()) {
     612      ok = false;
     613    } else {
     614      error = "";
     615      ok = true;
     616    }
     617  } else {
     618    output = "";
     619    error = I2("Creating process \n",
     620               "Creando el proceso \n") + command;
     621    ok = false;
     622  }
     623  return(ok);
     624};
    562625
    563626//--------------------------------------------------------------------
  • tol/bbasic/tol_bsys.h

    r5a1c981 ra94fd1c  
    3131#include <tol/tol_bout.h>
    3232#include <tol/tol_blist.h>
     33
     34#ifdef WIN32
     35#define popen _popen
     36#define pclose _pclose
     37#endif
    3338
    3439//--------------------------------------------------------------------
    … …  
    114119 
    115120#ifndef   UNIX
    116   static BBool  WinExecuteFile (const BText& fileName);
    117   static BBool  WinSystem  (const BText& command,
    118                                                     BInt        showMode,
    119                             bool  wait=BFALSE);
     121  static BBool  WinExecuteFile(const BText& fileName);
     122  static BBool  WinSystem     (const BText& command,
     123                               BInt  showMode, bool  wait=BFALSE);
     124  static BBool  WinSystemQuiet(const BText& command,
     125                               BText& output, BText& error);
    120126#endif
     127  static BBool  PExecQuiet    (const BText& command,
     128                               BText& output, BText& error);
    121129  static BBool ChildProcess(const BText& command);
    122130  //! Prints a file in the default printer.
  • tol/btol/set_type/setgra.cpp

    r5a1c981 ra94fd1c  
    5252
    5353#include "llkarma.h"
    54 
    55 #ifdef WIN32
    56 #define popen _popen
    57 #define pclose _pclose
    58 #endif
    5954
    6055//static const char* bayesVersionId =
    … …  
    29222917          "(Set Args)",
    29232918          I2("Execute an external program. The output of the program is returned in the member output.",
    2924              "Ejecuta un programa externo. la salida del programa se retorna en el miembro ouput del conjunto resultado."),
     2919             "Ejecuta un programa externo. La salida del programa se retorna en el elemento output del conjunto resultante."),
    29252920          BOperClassify::System_);
    29262921
    … …  
    29942989    }
    29952990    if ( !badArg ) {
    2996       //Std( BText( "*** '" ) + cmd + "' ***" );
    2997       FILE* pipe = popen(cmd, "r");
    2998       if ( pipe ) {
    2999         char buffer[128];
    3000         output = "";
    3001         while( !feof( pipe ) ) {
    3002           if( fgets( buffer, 128, pipe ) != NULL )
    3003             output += buffer;
    3004         }
    3005         status = 1;
    3006         desc = "";
    3007         pclose( pipe );
    3008       }
     2991      status = BSys::PExecQuiet(cmd, output, desc);
    30092992    } else {
    30102993      status = 0;
    … …  
    30283011  contens_.RobElement(result); 
    30293012}
     3013
     3014//--------------------------------------------------------------------
     3015DeclareContensClass(BSet, BSetTemporary, BSetAnsSystemQuiet);
     3016DefExtOpr(1, BSetAnsSystemQuiet, "AnsSystemQuiet", 1, 1, "Text",
     3017  "(Text command)",
     3018  I2("Calls the operative system to execute a command line "
     3019     "and returns the status, the standard output "
     3020     "and the standar error of the call in a set.",
     3021     "Llama al sistema operativo para ejecutar una línea de comandos "
     3022     "y devuelve un conjunto con el estado, "
     3023     "la salida estándar y los erorres de la llamada."),
     3024          BOperClassify::System_);
     3025//--------------------------------------------------------------------
     3026void BSetAnsSystemQuiet::CalcContens()
     3027//--------------------------------------------------------------------
     3028{
     3029  if(CheckNonDeclarativeAction("AnsSystem")) { return; }
     3030  const BText& command = Text(Arg(1));
     3031  BBool status;
     3032  BText output, error; 
     3033#ifndef UNIX
     3034  // Se usa WinSystemQuiet ya que PExecQuiet
     3035  // no puede evitar mostrar la ventana de la consola
     3036  status = BSys::WinSystemQuiet(command, output, error);
     3037#else
     3038  status = BSys::PExecQuiet(command, output, error);
     3039#endif
     3040  BList * result = NIL;
     3041  BSyntaxObject * so;
     3042  result = Cons(so = new BContensText("", error), result);
     3043  so->PutName("std_error");
     3044  result = Cons(so = new BContensText("", output), result);
     3045  so->PutName("std_output");
     3046  result = Cons(so = new BContensDat("", status), result);
     3047  so->PutName("status");
     3048  contens_.RobElement(result); 
     3049}
  • tol/btol/text_type/txtgra.cpp

    r5a1c981 ra94fd1c  
    28202820  contens_ = CompareVersionString(&v1,&v2);
    28212821}
     2822
     2823//--------------------------------------------------------------------
     2824  DeclareContensClass(BText, BTxtTemporary, BTextAnsSystem);
     2825  DefExtOpr(1, BTextAnsSystem, "AnsSystem", 1, 1, "Text", "(Text command)",
     2826  I2("Calls the operative system to execute a command line "
     2827     "and returns the standard output.",
     2828     "Llama al sistema operativo para ejecutar una línea de comandos "
     2829     "y devuelve la salida estándar de la llamada."),
     2830     BOperClassify::System_);
     2831  void BTextAnsSystem::CalcContens()
     2832//--------------------------------------------------------------------
     2833{
     2834  if(CheckNonDeclarativeAction("AnsSystem")) { return; }
     2835  const BText& command = Text(Arg(1));
     2836  BBool status;
     2837  BText output, error;
     2838#ifndef UNIX
     2839  // Se usa WinSystemQuiet ya que PExecQuiet
     2840  // no puede evitar mostrar la ventana de la consola
     2841  status = BSys::WinSystemQuiet(command, output, error);
     2842#else
     2843  status = BSys::PExecQuiet(command, output, error);
     2844#endif
     2845  if(status) {
     2846    contens_ = output;
     2847  } else {
     2848    Error(I2("Operative system error \n",
     2849             "Error del sistema operativo \n")+error);
     2850    contens_ = BText("");
     2851  }
     2852}
Note: See TracChangeset for help on using the changeset viewer.