mirror of https://github.com/BOINC/boinc.git
- 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:
parent
cc2f1a20a0
commit
671524df2a
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
171
lib/util.C
171
lib/util.C
|
@ -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$";
|
||||
|
|
20
lib/util.h
20
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
|
||||
|
|
Loading…
Reference in New Issue