Added soft link support.

svn path=/trunk/boinc/; revision=120
This commit is contained in:
Eric Heien 2002-06-20 23:46:51 +00:00
parent 08522256ed
commit acadf606fb
3 changed files with 167 additions and 94 deletions

View File

@ -24,6 +24,7 @@
#include "windows_cpp.h" #include "windows_cpp.h"
#ifdef _WIN32 #ifdef _WIN32
#include <io.h>
#else #else
#include <unistd.h> #include <unistd.h>
#include <sys/wait.h> #include <sys/wait.h>
@ -35,6 +36,8 @@
#include <ctype.h> #include <ctype.h>
#include <signal.h> #include <signal.h>
#include <time.h> #include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include "client_types.h" #include "client_types.h"
#include "client_state.h" #include "client_state.h"
@ -95,14 +98,14 @@ int ACTIVE_TASK::init(RESULT* rp) {
} }
int ACTIVE_TASK::start(bool first_time) { int ACTIVE_TASK::start(bool first_time) {
char exec_name[256], file_path[256], link_path[256]; char exec_name[256], file_path[256], link_path[256],temp[256];
char* argv[100]; char* argv[100];
unsigned int i; unsigned int i;
FILE_REF file_ref; FILE_REF file_ref;
FILE_INFO* fip; FILE_INFO* fip;
int fd, retval; int retval;
char prefs_path[256]; char prefs_path[256],init_path[256];
FILE *prefs_fd; FILE *prefs_fd,*init_file;
APP_IN app_prefs; APP_IN app_prefs;
// These should be chosen in a better manner // These should be chosen in a better manner
@ -111,20 +114,106 @@ int ACTIVE_TASK::start(bool first_time) {
app_prefs.graphics.refresh_period = 5; app_prefs.graphics.refresh_period = 5;
app_prefs.checkpoint_period = 5; app_prefs.checkpoint_period = 5;
app_prefs.poll_period = 5; app_prefs.poll_period = 5;
//app_gfx_prefs.shared_mem_key = ftok(dirname, 'B'); // Generate a unique identifier
// Write out the app prefs // Write out the app prefs
sprintf( prefs_path, "%s/%s", dirname, CORE_TO_APP_FILE ); sprintf( prefs_path, "%s/%s", dirname, CORE_TO_APP_FILE );
prefs_fd = fopen( prefs_path, "w" ); prefs_fd = fopen( prefs_path, "wb" );
if( !prefs_fd ) { if( !prefs_fd ) {
if( log_flags.task_debug ) { if( log_flags.task_debug ) {
printf( "Failed to open core to app prefs file %s.\n", prefs_path ); printf( "Failed to open core to app prefs file %s.\n", prefs_path );
} }
exit(-1); return -1;
} }
rewind( prefs_fd );
write_core_file( prefs_fd,app_prefs ); write_core_file( prefs_fd,app_prefs );
fclose(prefs_fd); fclose(prefs_fd);
sprintf( init_path, "%s/%s", dirname, BOINC_INIT_FILE );
init_file = fopen( init_path, "wb" );
if( !init_file ) {
if( log_flags.task_debug ) {
printf( "Failed to open init file %s.\n", init_path );
}
return -1;
}
rewind( init_file );
// make a link to the executable
//
for (i=0; i<app_version->app_files.size(); i++) {
fip = app_version->app_files[i].file_info;
get_pathname(fip, file_path);
if (i == 0) {
strcpy(exec_name, fip->name);
}
if (first_time) {
sprintf(link_path, "%s/%s", dirname, fip->name);
sprintf(temp, "../../%s", file_path );
retval = boinc_link( temp, link_path);
if (log_flags.task_debug) {
printf("link %s to %s\n", file_path, link_path);
}
if (retval) {
perror("link");
fclose( init_file );
return retval;
}
}
}
// create symbolic links, and hook up descriptors, for input files
//
for (i=0; i<wup->input_files.size(); i++) {
file_ref = wup->input_files[i];
get_pathname(file_ref.file_info, file_path);
if (strlen(file_ref.open_name)) {
if (first_time) {
sprintf(link_path, "%s/%s", dirname, file_ref.open_name);
sprintf(temp, "../../%s", file_path );
if (log_flags.task_debug) {
printf("link %s to %s\n", file_path, link_path);
}
retval = boinc_link( temp, link_path);
if (retval) {
perror("link");
fclose( init_file );
return retval;
}
}
} else {
sprintf( temp, "../../%s", file_path );
write_init_file( init_file, temp, file_ref.fd, 1 );
}
}
// hook up the output files
//
for (i=0; i<result->output_files.size(); i++) {
file_ref = result->output_files[i];
get_pathname(file_ref.file_info, file_path);
if (strlen(file_ref.open_name)) {
if (first_time) {
creat(file_path, 0660);
sprintf(link_path, "%s/%s", dirname, file_ref.open_name);
sprintf(temp, "../../%s", file_path );
if (log_flags.task_debug) {
printf("link %s to %s\n", file_path, link_path);
}
retval = boinc_link( temp, link_path);
if (retval) {
fclose( init_file );
perror("link");
return retval;
}
}
} else {
sprintf( temp, "../../%s", file_path );
write_init_file( init_file, temp, file_ref.fd, 0 );
}
}
fclose( init_file );
#ifdef unix #ifdef unix
pid = fork(); pid = fork();
if (pid == 0) { if (pid == 0) {
@ -133,88 +222,6 @@ int ACTIVE_TASK::start(bool first_time) {
// If an error happens, exit nonzero so that the core client // If an error happens, exit nonzero so that the core client
// knows there was a problem. // knows there was a problem.
// make a link to the executable
//
for (i=0; i<app_version->app_files.size(); i++) {
fip = app_version->app_files[i].file_info;
get_pathname(fip, file_path);
if (i == 0) {
strcpy(exec_name, fip->name);
}
if (first_time) {
sprintf(link_path, "%s/%s", dirname, fip->name);
retval = link(file_path, link_path);
if (log_flags.task_debug) {
printf("link %s to %s\n", file_path, link_path);
}
if (retval) {
perror("link");
exit(retval);
}
}
}
// create symbolic links, and hook up descriptors, for input files
//
for (i=0; i<wup->input_files.size(); i++) {
file_ref = wup->input_files[i];
get_pathname(file_ref.file_info, file_path);
if (strlen(file_ref.open_name)) {
if (first_time) {
sprintf(link_path, "%s/%s", dirname, file_ref.open_name);
if (log_flags.task_debug) {
printf("link %s to %s\n", file_path, link_path);
}
retval = link(file_path, link_path);
if (retval) {
perror("link");
exit(retval);
}
}
} else {
fd = open(file_path, O_RDONLY);
if (fd != file_ref.fd) {
retval = dup2(fd, file_ref.fd);
if (retval < 0) {
fprintf(stderr, "dup2 %d %d returned %d\n", fd, file_ref.fd, retval);
exit(retval);
}
close(fd);
}
}
}
// hook up the output files
//
for (i=0; i<result->output_files.size(); i++) {
file_ref = result->output_files[i];
get_pathname(file_ref.file_info, file_path);
if (strlen(file_ref.open_name)) {
if (first_time) {
creat(file_path, 0660);
sprintf(link_path, "%s/%s", dirname, file_ref.open_name);
if (log_flags.task_debug) {
printf("link %s to %s\n", file_path, link_path);
}
retval = link(file_path, link_path);
if (retval) {
perror("link");
exit(retval);
}
}
} else {
fd = open(file_path, O_WRONLY|O_CREAT, 0660);
if (fd != file_ref.fd) {
retval = dup2(fd, file_ref.fd);
if (retval < 0) {
fprintf(stderr, "dup2 %d %d returned %d\n", fd, file_ref.fd, retval);
exit(retval);
}
close(fd);
}
}
}
// chdir() into the slot directory // chdir() into the slot directory
// //
retval = chdir(dirname); retval = chdir(dirname);
@ -230,7 +237,8 @@ int ACTIVE_TASK::start(bool first_time) {
argv[0] = exec_name; argv[0] = exec_name;
parse_command_line(wup->command_line, argv+1); parse_command_line(wup->command_line, argv+1);
if (log_flags.task_debug) print_argv(argv); if (log_flags.task_debug) print_argv(argv);
retval = execv(exec_name, argv); boinc_resolve_link( exec_name, temp );
retval = execv(temp, argv);
fprintf(stderr, "execv failed: %d\n", retval); fprintf(stderr, "execv failed: %d\n", retval);
perror("execv"); perror("execv");
exit(1); exit(1);
@ -239,7 +247,52 @@ int ACTIVE_TASK::start(bool first_time) {
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
//CreateProcess PROCESS_INFORMATION process_info;
STARTUPINFO startup_info;
HINSTANCE inst;
memset( &process_info, 0, sizeof( process_info ) );
memset( &startup_info, 0, sizeof( startup_info ) );
startup_info.cb = sizeof(startup_info);
startup_info.lpReserved = NULL;
startup_info.lpDesktop = "";
// hook up stderr to a specially-named file (do this inside the new process)
//
//freopen(STDERR_FILE, "a", stderr);
// Need to condense argv into a single string
//if (log_flags.task_debug) print_argv(argv);
sprintf( temp, "%s/%s", dirname, exec_name );
boinc_resolve_link( temp, exec_name );
if( !CreateProcess( exec_name,
wup->command_line,
NULL, // not sure about this for security
NULL, // not sure about this for security
FALSE,
CREATE_NEW_PROCESS_GROUP|NORMAL_PRIORITY_CLASS,
NULL,
dirname,
&startup_info,
&process_info ) ) {
state = GetLastError();
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
state,
0, // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
}
pid_handle = process_info.hProcess;
#endif #endif
#ifdef macintosh #ifdef macintosh
@ -264,7 +317,7 @@ int ACTIVE_TASK_SET::insert(ACTIVE_TASK* atp) {
// //
bool ACTIVE_TASK_SET::poll() { bool ACTIVE_TASK_SET::poll() {
int stat; int stat;
ACTIVE_TASK* atp; ACTIVE_TASK* atp = NULL;
char path[256]; char path[256];
int n; int n;
@ -304,6 +357,10 @@ bool ACTIVE_TASK_SET::poll() {
// Not sure what to do here // Not sure what to do here
} }
} }
if( atp == NULL ) {
return false;
}
#endif #endif
#ifdef unix #ifdef unix
@ -379,12 +436,12 @@ void ACTIVE_TASK_SET::unsuspend_all() {
#ifdef _WIN32 #ifdef _WIN32
void ACTIVE_TASK::suspend() { void ACTIVE_TASK::suspend() {
// figure out a way to do this // figure out a way to do this, perhaps via trigger file?
//kill(atp->pid, SIGSTOP); //kill(atp->pid, SIGSTOP);
} }
void ACTIVE_TASK::unsuspend() { void ACTIVE_TASK::unsuspend() {
// figure out a way to do this // figure out a way to do this, perhaps via trigger file?
//kill(atp->pid, SIGCONT); //kill(atp->pid, SIGCONT);
} }
#else #else

View File

@ -180,6 +180,21 @@ int file_size(char* path, int& size) {
return 0; return 0;
} }
/* boinc_link creates a file (new) which contains an XML
reference to existing. */
int boinc_link( char *existing, char *new_link ) {
FILE *fp;
fp = fopen( new_link, "wb" );
if (!fp) return ERR_FOPEN;
rewind( fp );
fprintf( fp, "<soft_link>%s</soft_link>\n", existing );
fclose( fp );
return 0;
}
int clean_out_dir(char* dirpath) { int clean_out_dir(char* dirpath) {
char filename[256], path[256]; char filename[256], path[256];
int retval; int retval;

View File

@ -22,4 +22,5 @@ extern int dir_scan(char*);
extern void dir_close(); extern void dir_close();
extern int file_delete(char*); extern int file_delete(char*);
extern int file_size(char*, int&); extern int file_size(char*, int&);
extern int boinc_link( char *existing, char *new_link );
extern int clean_out_dir(char*); extern int clean_out_dir(char*);