campo-sirio/include/execp.cpp
angelo 71922f801f Rimossa la copia del file per lanciare piu' istanze della stessa
applicazione. Cio' era valido per Win95. Ora per lo stesso sistema
operativo del futuro, si utilizza un altro metodo, implementato
da Alex. Vedi commit del 20 giugno 1996 di applicat.cpp, xvtility.cpp.


git-svn-id: svn://10.65.10.50/trunk@3034 c028cbd2-c16b-5b4b-a496-9718f37d4682
1996-06-20 15:20:25 +00:00

223 lines
5.5 KiB
C++
Executable File

#include <stdio.h>
#include <xvt.h>
#if XVT_OS == XVT_OS_SCOUNIX
#include <sys/fcntl.h>
#include <sys/wait.h>
#endif
#if XVT_OS == XVT_OS_WIN
#define STRICT
#include <windows.h>
#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)
#if XVT_OS == XVT_OS_WIN
path << " /u" << user();
#else
path << " -u" << user();
#endif
_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++)
{
if (i == 0 && ok && TaskFindHandle(&te, child) == FALSE)
break;
xvt_app_process_pending_events();
}
if (utente)
{
tw.maximize();
tw.activate();
}
}
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++;
// 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);
return _exitcode;
}
TExternal_app::TExternal_app(const char* p)
{
_path = p;
_count = 0;
_error = 0;
_exitcode = 0;
}