diff --git a/checkin_notes b/checkin_notes index d833bdd56f..743138dfe9 100644 --- a/checkin_notes +++ b/checkin_notes @@ -2179,3 +2179,18 @@ David Mar 10 2008 util.C,h sched/ server_types.C,h + +David Mar 10 2008 + - Second pass at the above. We still need run_program() in util.C. + The problem was that there's a lot of extra stuff needed + for running apps on Windows (e.g. related to sandboxing). + This needed to be a new function. + + clientgui/ + MainDocument.cpp + clientscr/ + screensaver.cpp + lib/ + Makefile.am + proc_control.C,h + util.C,h diff --git a/clientgui/MainDocument.cpp b/clientgui/MainDocument.cpp index 45318267ca..63e215f412 100644 --- a/clientgui/MainDocument.cpp +++ b/clientgui/MainDocument.cpp @@ -1257,12 +1257,11 @@ int CMainDocument::WorkShowGraphics(RESULT* result) argv[0] = "--graphics"; argv[1] = 0; - iRetVal = run_program( + iRetVal = run_app_windows( result->slot_path.c_str(), result->graphics_exec_path.c_str(), 1, argv, - 0, id ); #endif diff --git a/clientscr/screensaver.cpp b/clientscr/screensaver.cpp index ef60d5bf01..c08ece957f 100644 --- a/clientscr/screensaver.cpp +++ b/clientscr/screensaver.cpp @@ -175,6 +175,7 @@ int CScreensaver::launch_screensaver(RESULT* rp, int& graphics_application) argv[0] = "app_graphics"; // not used argv[1] = "--fullscreen"; argv[2] = 0; +#ifdef _WIN32 retval = run_program( rp->slot_path.c_str(), rp->graphics_exec_path.c_str(), @@ -183,6 +184,15 @@ int CScreensaver::launch_screensaver(RESULT* rp, int& graphics_application) 0, graphics_application ); +#else + retval = run_app_windows( + rp->slot_path.c_str(), + rp->graphics_exec_path.c_str(), + 2, + argv, + graphics_application + ); +#endif #endif } else { // V5 and Older diff --git a/lib/Makefile.am b/lib/Makefile.am index 354599e6c0..73b8968742 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -74,7 +74,6 @@ libboinc_a_SOURCES = \ parse.C \ prefs.C \ procinfo_unix.C \ - proc_control.C \ proxy_info.C \ shmem.C \ str_util.C \ diff --git a/lib/proc_control.C b/lib/proc_control.C index aa946111f3..d8b97e7a45 100644 --- a/lib/proc_control.C +++ b/lib/proc_control.C @@ -17,35 +17,23 @@ // or write to the Free Software Foundation, Inc., // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// Code used by BOINC components (screensaver, manager, updater) -// Don't include this in libboinc +// Code to run a BOINC application (main or graphics) under Windows +// Don't include this in applications #if defined(_WIN32) && !defined(__STDWX_H__) && !defined(_BOINC_WIN_) && !defined(_AFX_STDAFX_H_) #include "boinc_win.h" #endif -#ifdef _WIN32 #include "win_util.h" -#else -#include -#include -#include -#include -#include -#include -#endif #include "filesys.h" #include "error_numbers.h" #include "common_defs.h" #include "util.h" -#ifdef _WIN32 HANDLE sandbox_account_token = NULL; PSID sandbox_account_sid = NULL; -#endif -#ifdef _WIN32 void get_sandbox_account_token() { FILE* f; char buf[256]; @@ -118,17 +106,13 @@ void get_sandbox_account_token() { } } } -#endif +// Run application, Windows. // chdir into the given directory, and run a program there. -// If nsecs is nonzero, make sure it's still running after that many seconds. -// // argv is set up Unix-style, i.e. argv[0] is the program name // - -#ifdef _WIN32 -int run_program( - const char* dir, const char* file, int argc, char *const argv[], double nsecs, HANDLE& id +int run_app_windows( + const char* dir, const char* file, int argc, char *const argv[], HANDLE& id ) { int retval; PROCESS_INFORMATION process_info; @@ -235,125 +219,6 @@ int run_program( return -1; // CreateProcess returns 1 if successful, false if it failed. } - if (nsecs) { - boinc_sleep(nsecs); - if (GetExitCodeProcess(process_info.hProcess, &status)) { - if (status != STILL_ACTIVE) { - return -1; - } - } - } - id = process_info.hProcess; - return 0; } -#else -int run_program( - const char* dir, const char* file, int , char *const argv[], double nsecs, int& id -) { - int retval; - int pid = fork(); - if (pid == 0) { - if (dir) { - retval = chdir(dir); - if (retval) return retval; - } - execv(file, argv); - perror("execv"); - exit(errno); - } - - if (nsecs) { - boinc_sleep(3); - if (waitpid(pid, 0, WNOHANG) == pid) { - return -1; - } - } - id = pid; - return 0; -} -#endif - -#ifdef _WIN32 -void kill_program(HANDLE pid) { - TerminateProcess(pid, 0); -} -#else -void kill_program(int pid) { - kill(pid, SIGKILL); -} -#endif - -#ifdef _WIN32 -int get_exit_status(HANDLE pid_handle) { - unsigned long status=1; - while (1) { - if (GetExitCodeProcess(pid_handle, &status)) { - if (status == STILL_ACTIVE) { - boinc_sleep(1); - } - } - } - return (int) status; -} -bool process_exists(HANDLE h) { - unsigned long status=1; - if (GetExitCodeProcess(h, &status)) { - if (status == STILL_ACTIVE) return true; - } - return false; -} - -#else -int get_exit_status(int pid) { - int status; - waitpid(pid, &status, 0); - return status; -} -bool process_exists(int pid) { - int p = waitpid(pid, 0, WNOHANG); - if (p == pid) return false; // process has exited - if (p == -1) return false; // PID doesn't exist - return true; -} -#endif - -#ifdef _WIN32 -static int get_client_mutex(const char*) { - char buf[MAX_PATH] = ""; - - // Global mutex on Win2k and later - // - if (IsWindows2000Compatible()) { - strcpy(buf, "Global\\"); - } - strcat( buf, RUN_MUTEX); - - HANDLE h = CreateMutex(NULL, true, buf); - if ((h==0) || (GetLastError() == ERROR_ALREADY_EXISTS)) { - return ERR_ALREADY_RUNNING; - } -#else -static int get_client_mutex(const char* dir) { - char path[1024]; - static FILE_LOCK file_lock; - - sprintf(path, "%s/%s", dir, LOCK_FILE_NAME); - if (file_lock.lock(path)) { - return ERR_ALREADY_RUNNING; - } -#endif - return 0; -} - -int wait_client_mutex(const char* dir, double timeout) { - double start = dtime(); - while (1) { - int retval = get_client_mutex(dir); - if (!retval) return 0; - boinc_sleep(1); - if (dtime() - start > timeout) break; - } - return ERR_ALREADY_RUNNING; -} diff --git a/lib/proc_control.h b/lib/proc_control.h index 78c204824f..a4dad1b2cc 100644 --- a/lib/proc_control.h +++ b/lib/proc_control.h @@ -4,21 +4,6 @@ extern HANDLE sandbox_account_token; extern PSID sandbox_account_sid; extern void get_sandbox_account_token(); -extern int run_program( - const char* path, const char* cdir, int argc, char *const argv[], double, HANDLE& +extern int run_app_windows( + const char* path, const char* cdir, int argc, char *const argv[], HANDLE& ); - -extern void kill_program(HANDLE); -extern int get_exit_status(HANDLE); -extern bool process_exists(HANDLE); - -#else -extern int run_program( - const char* path, const char* cdir, int argc, char *const argv[], double, int& -); -extern void kill_program(int); -extern int get_exit_status(int); -extern bool process_exists(int); -#endif - -extern int wait_client_mutex(const char* dir, double timeout); diff --git a/lib/util.C b/lib/util.C index c91ae257d9..694f590e48 100644 --- a/lib/util.C +++ b/lib/util.C @@ -30,8 +30,11 @@ #ifndef _WIN32 #include "config.h" +#include #include +#include #include +#include #include #include #endif @@ -338,4 +341,172 @@ int read_file_string(const char* path, string& result, int max_len, bool tail) { return 0; } +// chdir into the given directory, and run a program there. +// If nsecs is nonzero, make sure it's still running after that many seconds. +// +// argv is set up Unix-style, i.e. argv[0] is the program name +// + +#ifdef _WIN32 +int run_program( + const char* dir, const char* file, int argc, char *const argv[], double nsecs, HANDLE& id +) { + int retval; + PROCESS_INFORMATION process_info; + STARTUPINFO startup_info; + char cmdline[1024]; + char error_msg[1024]; + unsigned long status; + + memset(&process_info, 0, sizeof(process_info)); + memset(&startup_info, 0, sizeof(startup_info)); + startup_info.cb = sizeof(startup_info); + + strcpy(cmdline, ""); + for (int i=0; i timeout) break; + } + return ERR_ALREADY_RUNNING; +} + const char *BOINC_RCSID_ab65c90e1e = "$Id$"; diff --git a/lib/util.h b/lib/util.h index 12f145405c..ad52811801 100644 --- a/lib/util.h +++ b/lib/util.h @@ -75,4 +75,24 @@ extern void boinc_crash(); extern int read_file_malloc(const char* path, char*&, int max_len=0, bool tail=false); extern int read_file_string(const char* path, std::string&, int max_len=0, bool tail=false); +#ifdef _WIN32 + +extern int run_program( + const char* path, const char* cdir, int argc, char *const argv[], double, HANDLE& +); + +extern void kill_program(HANDLE); +extern int get_exit_status(HANDLE); +extern bool process_exists(HANDLE); + +#else +extern int run_program( + const char* path, const char* cdir, int argc, char *const argv[], double, int& +); +extern void kill_program(int); +extern int get_exit_status(int); +extern bool process_exists(int); +#endif + +extern int wait_client_mutex(const char* dir, double timeout); #endif