#include #include #if XVT_OS == XVT_OS_SCOUNIX #include #include #endif #if XVT_OS == XVT_OS_WIN #define STRICT #include #include #endif #include #include #include #include #include // @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). int 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

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(); _exitcode = WinExec((char*)(const char*)path, SW_SHOW); for (int maxtry = 5 ; maxtry > 0 && _exitcode == 16; maxtry--) { int spc = path.find(' '); if (spc < 0) spc = path.len(); TFilename name(path.left(spc)), oldname(name); name.ext(""); if (isdigit(name.right(1)[0])) name << 'a'; else name[name.len() - 1]++; name.ext("exe"); if (!fexist(name)) { oldname.ext("exe"); fcopy(oldname, name); } name << path.mid(spc); path = name; _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 = 8; switch (_exitcode) { case 0: case 8: 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) error_box("Impossibile eseguire '%s':\nErrore %d", (const char*)_path, _exitcode); else _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++; return _exitcode; } TExternal_app::TExternal_app(const char* p) { _path = p; _count = 0; _error = 0; _exitcode = 0; }