campo-sirio/include/execp.cpp
guy 55a36762ef archives.cpp Tolto include windows.h
checks.cpp      Tolto include windows.h
colors.cpp      Tolto include windows.h
controls.cpp    Aggiunto cambiamento del font runtime dei TText_control
execp.cpp       Tolto include windows.h
form.cpp        Tolto include windows.h
mask.cpp        Corretta formattazione di due righe
maskfld.cpp     Aggiunto messaggio CHECK
msksheet.cpp    Tolto include windows.h
relapp.cpp      Tolto include windows.h
strings.pp      Corretto CHECK della TFixed_string::format()
viswin.cpp      Tolto include windows.h
window.cpp      Tolto include windows.h
xvtility.cpp    Corretto calcolo altezza righe delle maschere


git-svn-id: svn://10.65.10.50/trunk@4085 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-01-17 11:07:43 +00:00

227 lines
5.7 KiB
C++
Executable File

#include <stdio.h>
#define XVT_INCL_NATIVE
#define STRICT
#include <xvt.h>
#if XVT_OS == XVT_OS_SCOUNIX
#include <sys/fcntl.h>
#include <sys/wait.h>
#endif
#if XVT_OS == XVT_OS_WIN
#include <toolhelp.h>
#include <hlapi_c.h>
#endif
#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
{
TString256 path(_path);
if (utente)
path << " /u" << user();
_error = 0;
_exitcode = 0;
// save cwd
xvt_fsys_save_dir();
#if XVT_OS == XVT_OS_WIN
if (can_run())
{
TFilename dir(_path);
dir = dir.path();
if (dir.not_empty())
{
DIRECTORY d;
if (xvt_fsys_convert_str_to_dir((char *) (const char *) dir, &d))
xvt_fsys_set_dir(&d);
}
main_app().begin_wait();
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();
}
main_app().end_wait();
} else _exitcode = 1;
_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 (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;
}