campo-sirio/include/execp.cpp
guy 21ea6df4df applicat.cpp Gestione di EdApp oltre che EdMask nelle configurazioni
execp.cpp    Aggiunta forzatura user sulla riga di comando
form.cpp     Aggiunte sezioni ad altezza variabile
form.h       Aggiuto metodo virtual bool TForm_item::is_section() const
isam.cpp     Forzatura user in chiamata delle conversioni
lffiles.h    Sostituito LF_ABPROF con LF_SVRIEP
mask.*       Aggiunto metodo sfield() che ritorna direttamente uno spreadsheet
rdoc.h       Risolti conflitti
relapp.cpp   Corretta cancellazione veloce di documenti protetti
relation.cpp Tolto spazio inutile


git-svn-id: svn://10.65.10.50/trunk@5062 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-08-18 14:11:37 +00:00

364 lines
9.0 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 (default FALSE)
bool utente) // @parm Permette di inserire il nome dell'utente nella riga
// di comando(default TRUE)
// @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())
{
main_app().begin_wait();
#if XVT_OS == XVT_OS_WIN
HL_LOGOUT();
_exitcode = WinExec((char*)(const char*)path, SW_SHOW);
if (_exitcode >= 32)
{
if (!async)
{
TTemp_window tw(TASK_WIN);
if (utente)
{
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 (utente)
{
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
main_app().end_wait();
} 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;
}