cfiles.cpp      Corretta costruzione della stringa __ptprf
                (senza doppi slash e controlslash consecutivi)
config.cpp      Megafigata: Dopo anni e anni le chiavi vengono salvate
                in ordine alfabetico e non in disordine hash!
execp.cpp       Aggiunti due flag al metodo TExternal_app::run
                Uno per specificare l'iconizzazione del programma chiamante
                e uno per la visibilita' del programma chiamato
prefix.cpp      Migliorata costruzione path dei dati
strings.cpp     Aggiunta #define della dimensione di default delle stringhe
		Corretto metodo TFilename::add
utility.cpp     Megafigata: Dopo anni e anni aggiunto il metodo fsize(const char*)
git-svn-id: svn://10.65.10.50/trunk@5498 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
	
			
		
			
				
	
	
		
			365 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			365 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <stdio.h>
 | 
						|
 | 
						|
#define STRICT
 | 
						|
#define XVT_INCL_NATIVE
 | 
						|
#include <xvt.h>
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_WIN
 | 
						|
#include <toolhelp.h>
 | 
						|
#include <string.h>
 | 
						|
#include <ctype.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_SCOUNIX
 | 
						|
#include <sys/fcntl.h>
 | 
						|
#include <sys/wait.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <hlapi_c.h>
 | 
						|
 | 
						|
#include <applicat.h>
 | 
						|
#include <execp.h> 
 | 
						|
#include <prefix.h>
 | 
						|
#include <utility.h>
 | 
						|
#include <window.h>
 | 
						|
#include <extcdecl.h>
 | 
						|
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Controlla se il processo puo' essere eseguito
 | 
						|
//
 | 
						|
// @rdesc Ritorna i seguenti valori:
 | 
						|
//
 | 
						|
// @flag TRUE | Se l'applicazione puo' essere eseguita
 | 
						|
// @flag FALSE | Se l'applicazione non puo' essere eseguita
 | 
						|
bool TExternal_app::can_run() const
 | 
						|
 | 
						|
// @comm Se si opera sotto Windows si controlla se vi sono risorse necessarie
 | 
						|
//       per l'esecuzione del processo, altrimenti viene tornato sempre TRUE.
 | 
						|
{                    
 | 
						|
#if XVT_OS == XVT_OS_WIN
 | 
						|
  const TFixed_string p(_path);           
 | 
						|
  const bool big = p.find("cg0") == 0 && p.right(2) == "-1";
 | 
						|
  const int richieste = big ? 50 : 15;
 | 
						|
  const int libere = GetFreeSystemResources(GFSR_SYSTEMRESOURCES);
 | 
						|
  return libere >= richieste;
 | 
						|
#else
 | 
						|
  return TRUE;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
                   
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Esegue il processo
 | 
						|
//
 | 
						|
// @rdesc Ritorna il codice di uscita del processo (-1 in caso di errore).
 | 
						|
word TExternal_app::run(
 | 
						|
  bool async,   // @parm Per eseguire il processo in parallelo 
 | 
						|
  bool utente,  // @parm Permette di inserire il nome dell'utente nella riga di comando
 | 
						|
  bool iconize, // @parm Iconizza il programma chiamante
 | 
						|
  bool show)    // @parm Mostra o nascondi il programma chiamato
 | 
						|
 | 
						|
  // @comm Se <p asyn> e' FALSE aspetta che termini il processo in esecuzione prima di iniziare il nuovo
 | 
						|
 | 
						|
{
 | 
						|
  TFilename path(_path);                                  
 | 
						|
  TString name(path.name()); 
 | 
						|
  int p = name.find(' ');
 | 
						|
  
 | 
						|
  if (p >=0)
 | 
						|
    name = name.left(p);
 | 
						|
  
 | 
						|
  if (utente == TRUE)   // utente puo' essere 0 = No, 1 = Si, 3 = Forzatura
 | 
						|
  {
 | 
						|
    bool our_app = name.len() > 2;
 | 
						|
    if (our_app && atoi(name) < 70)
 | 
						|
    {
 | 
						|
      our_app = isalpha(name[0]) && isalpha(name[1]) && isdigit(name[2]);
 | 
						|
    }
 | 
						|
    if (!our_app)
 | 
						|
      utente = FALSE;
 | 
						|
  }  
 | 
						|
  
 | 
						|
  if (utente)
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_WIN32
 | 
						|
    path << " /u" << user();
 | 
						|
#else 
 | 
						|
    path << " -u" << user();
 | 
						|
#endif    
 | 
						|
  
 | 
						|
  _error = 0;
 | 
						|
  _exitcode =  0;
 | 
						|
 | 
						|
  // save cwd
 | 
						|
  xvt_fsys_save_dir();
 | 
						|
 | 
						|
  const TFilename dir(path.path()); 
 | 
						|
 | 
						|
  if (dir.not_empty())
 | 
						|
  {
 | 
						|
    DIRECTORY d;
 | 
						|
  
 | 
						|
    if (xvt_fsys_convert_str_to_dir((char *) (const char *) dir, &d))
 | 
						|
      xvt_fsys_set_dir(&d);
 | 
						|
  }                
 | 
						|
  
 | 
						|
/* Gestione programmi spezzati  
 | 
						|
  if (our_app)
 | 
						|
  {
 | 
						|
    TString parms(_path);  
 | 
						|
    TString new_suffix;
 | 
						|
    int p = parms.find(' ');
 | 
						|
  
 | 
						|
    if (p < 0)
 | 
						|
    {
 | 
						|
      parms = "";
 | 
						|
      new_suffix = "_0";
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      parms = parms.mid(p + 1); 
 | 
						|
      p = parms.find(' ');
 | 
						|
      if (p >= 0)
 | 
						|
        new_suffix = parms.left(p);
 | 
						|
      else new_suffix = parms;
 | 
						|
      if (new_suffix[0] == '-') new_suffix[0] = '_';
 | 
						|
      else new_suffix = "__";
 | 
						|
    }
 | 
						|
  
 | 
						|
    TFilename newpath(dir);
 | 
						|
  
 | 
						|
    if (newpath.not_empty())
 | 
						|
      newpath << '/';
 | 
						|
    newpath << name << new_suffix;
 | 
						|
    newpath.ext("exe");
 | 
						|
    if (fexist(newpath))
 | 
						|
    {
 | 
						|
      newpath.ext("");
 | 
						|
      newpath << parms;
 | 
						|
      path = newpath;
 | 
						|
      if (utente)
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_WIN32
 | 
						|
        path << " /u" << user();
 | 
						|
#else 
 | 
						|
        path << " -u" << user();
 | 
						|
#endif    
 | 
						|
    
 | 
						|
    }
 | 
						|
  }
 | 
						|
*/  
 | 
						|
  
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_WIN32
 | 
						|
  if (can_run())
 | 
						|
  {                
 | 
						|
    TWait_cursor hourglass;
 | 
						|
#if XVT_OS == XVT_OS_WIN
 | 
						|
    HL_LOGOUT();
 | 
						|
    _exitcode = WinExec(path.get_buffer(), show ? SW_SHOWNORMAL : SW_HIDE);
 | 
						|
 | 
						|
    if (_exitcode >= 32)
 | 
						|
    {        
 | 
						|
      if (!async)
 | 
						|
      {                            
 | 
						|
        TTemp_window tw(TASK_WIN);
 | 
						|
        if (iconize)
 | 
						|
        {
 | 
						|
          tw.iconize();
 | 
						|
          tw.deactivate();
 | 
						|
        }  
 | 
						|
        
 | 
						|
        HTASK child = NULL;
 | 
						|
        TASKENTRY te; te.dwSize = sizeof(TASKENTRY); 
 | 
						|
        for (bool ok = TaskFirst(&te); ok; ok = TaskNext(&te))
 | 
						|
          if (te.hInst == (HINSTANCE)_exitcode)
 | 
						|
          {
 | 
						|
            child = te.hTask;
 | 
						|
            break;
 | 
						|
          }  
 | 
						|
        
 | 
						|
        // Warning! child could be NULL if you run that beast called Foxpro        
 | 
						|
        
 | 
						|
        main_app().wait_for((word)child); 
 | 
						|
        for (byte i = 0; main_app().waiting() == (word)child; i++)
 | 
						|
        {          
 | 
						|
          // Esegue il controllo solo ogni 256 cicli
 | 
						|
          if (i == 0 && ok && TaskFindHandle(&te, child) == FALSE) 
 | 
						|
          {       
 | 
						|
            main_app().wake_up(); // Annulla attesa del processo
 | 
						|
            break;
 | 
						|
          }  
 | 
						|
          xvt_app_process_pending_events();
 | 
						|
        }
 | 
						|
        
 | 
						|
        if (iconize)
 | 
						|
        {
 | 
						|
          tw.maximize();
 | 
						|
          tw.activate();             
 | 
						|
        }  
 | 
						|
        xvt_app_process_pending_events();
 | 
						|
      }
 | 
						|
      xvt_statbar_refresh();
 | 
						|
    }  
 | 
						|
#else
 | 
						|
    STARTUPINFO start; 
 | 
						|
    PROCESS_INFORMATION pi;
 | 
						|
 | 
						|
    start.cb = sizeof(start);
 | 
						|
    start.lpReserved = start.lpDesktop = start.lpTitle = NULL;                                             
 | 
						|
    start.dwX = start.dwY = start.dwXSize = start.dwYSize = CW_USEDEFAULT;
 | 
						|
    start.dwXCountChars = start.dwYCountChars = start.dwFillAttribute = 0L;
 | 
						|
    start.dwFlags = STARTF_USESHOWWINDOW;
 | 
						|
    start.wShowWindow = SW_SHOW ;
 | 
						|
    start.cbReserved2 = 0;
 | 
						|
    start.lpReserved2 = NULL;
 | 
						|
    start.hStdInput = NULL;  
 | 
						|
    start.hStdOutput = NULL ;
 | 
						|
    start.hStdError = NULL;
 | 
						|
    BOOL started = CreateProcess(NULL,(char*)(const char*)path, NULL, NULL, FALSE, 0,
 | 
						|
                                 NULL, NULL, &start, &pi); 
 | 
						|
    if (started)
 | 
						|
    {
 | 
						|
      HANDLE hProcess = pi.hProcess;
 | 
						|
 | 
						|
      if (!async)
 | 
						|
      {
 | 
						|
        TTemp_window tw(TASK_WIN);
 | 
						|
        if (utente) 
 | 
						|
        {
 | 
						|
          tw.iconize();
 | 
						|
          tw.deactivate();
 | 
						|
        }  
 | 
						|
        if (WaitForSingleObject(hProcess, INFINITE) != 0xFFFFFFFF)
 | 
						|
        {
 | 
						|
          unsigned long exitcode;
 | 
						|
          if (GetExitCodeProcess(hProcess, &exitcode))
 | 
						|
            _exitcode = (int) exitcode;
 | 
						|
           else
 | 
						|
            _exitcode = -2;
 | 
						|
        }
 | 
						|
        if (utente) 
 | 
						|
        {
 | 
						|
          tw.maximize();
 | 
						|
          tw.activate();             
 | 
						|
        }  
 | 
						|
      }
 | 
						|
      else
 | 
						|
        _exitcode = 0;
 | 
						|
      CloseHandle(pi.hThread);
 | 
						|
      CloseHandle(hProcess);
 | 
						|
    }
 | 
						|
    else _exitcode  = -1;
 | 
						|
 | 
						|
#endif
 | 
						|
  } else _exitcode = 1;
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_WIN
 | 
						|
  _error = _exitcode;
 | 
						|
  switch (_exitcode)
 | 
						|
  {
 | 
						|
  case 0:          
 | 
						|
  case 1:
 | 
						|
    error_box("Risorse insufficienti per eseguire '%s'", (const char*)_path); break;
 | 
						|
  case 2:
 | 
						|
  case 3:
 | 
						|
    error_box("Impossibile trovare '%s'", (const char*)_path); break;
 | 
						|
  case 16:
 | 
						|
    error_box("'%s' e' gia' in esecuzione", (const char*)_path); break;
 | 
						|
  default:
 | 
						|
    if (_exitcode < 32 && _exitcode != 8)
 | 
						|
      error_box("Impossibile eseguire '%s':\nErrore %u", (const char*)_path, _exitcode); 
 | 
						|
    else
 | 
						|
    {
 | 
						|
      if (_exitcode != 8) _error = 0;
 | 
						|
      _exitcode = 0;  
 | 
						|
    }  
 | 
						|
    break;
 | 
						|
  }  
 | 
						|
#else
 | 
						|
  switch (_exitcode)
 | 
						|
  {
 | 
						|
    case -2:
 | 
						|
      error_box("Impossibile ricevere il valore di ritorno da '%s':\nErrore %ld", (const char*)_path, GetLastError()); break;
 | 
						|
    case -1:
 | 
						|
      error_box("Impossibile eseguire '%s':\nErrore %ld", (const char*)_path, GetLastError()); break;
 | 
						|
    case 8:
 | 
						|
      error_box("Risorse insufficienti per eseguire '%s'", (const char*)_path); break;
 | 
						|
    case 0:
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      error_box("Valore di ritorno di '%s':\n %ld", (const char*)_path, _exitcode); break;
 | 
						|
  }
 | 
						|
#endif
 | 
						|
#else
 | 
						|
 | 
						|
  switch (fork())
 | 
						|
  {
 | 
						|
  case -1:
 | 
						|
    _error = errno;
 | 
						|
    _exitcode = -1;
 | 
						|
    break;
 | 
						|
  case 0:
 | 
						|
    const char* s = strdup(path);
 | 
						|
    char* p = strchr(s, ' ');
 | 
						|
    if (p) *p = '\0';
 | 
						|
    const char* pathn = strdup(s);
 | 
						|
    const char* args[21];
 | 
						|
    int i = 0;
 | 
						|
    args[i++] = pathn;
 | 
						|
    while ((i < 20) && (p))
 | 
						|
    {
 | 
						|
      s = p + 1;
 | 
						|
      p = strchr(s, ' ');
 | 
						|
      if (p) *p = '\0';
 | 
						|
      args[i++] = strdup(s);
 | 
						|
    }
 | 
						|
    args[i] = NULL;
 | 
						|
    for (i = 3; i < _NFILE; i++) fcntl(i,F_SETFD,1);
 | 
						|
    // execvp( path, NULL);
 | 
						|
    execvp ( pathn , args );
 | 
						|
    exit ( -1 );
 | 
						|
  default:
 | 
						|
    if(wait(&_exitcode) == -1)
 | 
						|
    {
 | 
						|
      error_box("Impossibile eseguire '%s':\nErrore %d", (const char*)_path, _exitcode);
 | 
						|
      _exitcode = -1;
 | 
						|
    }
 | 
						|
    else _exitcode = _exitcode >> 8;
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  _error = errno;
 | 
						|
  xvt_app_escape(XVT_ESC_CH_REFRESH);
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
  // restore cwd
 | 
						|
  xvt_fsys_restore_dir();
 | 
						|
 | 
						|
  // update counts
 | 
						|
  if (_exitcode == 0)
 | 
						|
    _count++;
 | 
						|
#if XVT_OS == XVT_OS_WIN    
 | 
						|
  // Ignora volutamente il return code da HL_LOGIN(). Se va bene riprende il posto
 | 
						|
  // altrimenti fa lo stesso. Infatti puo' capitare con una chiave di rete, che
 | 
						|
  // nel lasso di tempo trascorso dalla HL_LOGOUT() dell'applicazione chiamata,
 | 
						|
  // a questa HL_LOGIN() [approssimativamente qualche decimo di secondo], qualche altro
 | 
						|
  // programma si inserisca, occupando magari anche l'ultimo posto disponibile.
 | 
						|
  // Quindi se si  verificasse tale sfigatissima condizione, sicuramente
 | 
						|
  // non ci saranno piu' posti liberi nell'HL_server: il programma comunque non
 | 
						|
  // puo' interrompersi a meta'; ecco perche il valore di ritorno di HL_LOGIN viene
 | 
						|
  // ignorato.
 | 
						|
  HL_LOGIN(ModAd, DONT_CARE, REFKEY, VERKEY);
 | 
						|
#endif
 | 
						|
  return _exitcode;
 | 
						|
}
 | 
						|
 | 
						|
TExternal_app::TExternal_app(const char* p)
 | 
						|
{
 | 
						|
  _path =  p;
 | 
						|
  _count = 0;
 | 
						|
  _error = 0;
 | 
						|
  _exitcode =  0;
 | 
						|
}
 | 
						|
 |