- 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.

svn path=/trunk/boinc/; revision=14879
This commit is contained in:
David Anderson 2008-03-10 22:36:22 +00:00
parent cc2f1a20a0
commit 671524df2a
8 changed files with 224 additions and 160 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 \

View File

@ -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 <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#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;
}

View File

@ -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);

View File

@ -30,8 +30,11 @@
#ifndef _WIN32
#include "config.h"
#include <sys/types.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <errno.h>
#include <string>
#include <cstring>
#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<argc; i++) {
strcat(cmdline, argv[i]);
if (i<argc-1) {
strcat(cmdline, " ");
}
}
retval = CreateProcess(
file,
cmdline,
NULL,
NULL,
FALSE,
0,
NULL,
dir,
&startup_info,
&process_info
);
if (!retval) {
windows_error_string(error_msg, sizeof(error_msg));
fprintf(stderr, "CreateProcess failed: '%s'\n", error_msg);
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;
}
const char *BOINC_RCSID_ab65c90e1e = "$Id$";

View File

@ -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