diff --git a/checkin_notes b/checkin_notes index c346a8fa9e..a5a5696ea9 100755 --- a/checkin_notes +++ b/checkin_notes @@ -2625,3 +2625,15 @@ David Dec 11 2002 tools_work.html test/ *wu + +David Dec 13 2002 + - use lock file mechanism to prevent multiple instances of + core client from running in same directory + + configure + configure.in + client/ + file_names.h + main.C + lib/ + util.C,y diff --git a/client/file_names.h b/client/file_names.h index 789fe069ea..ae0280a782 100644 --- a/client/file_names.h +++ b/client/file_names.h @@ -48,3 +48,4 @@ extern bool is_account_file(char*); #define STDERR_FILE_NAME "stderr.txt" #define STDOUT_FILE_NAME "stdout.txt" #define TIME_TESTS_FILE_NAME "time_tests.xml" +#define LOCK_FILE_NAME "lockfile" diff --git a/client/main.C b/client/main.C index 6777866d1b..29a2c62f7a 100644 --- a/client/main.C +++ b/client/main.C @@ -75,6 +75,10 @@ int main(int argc, char** argv) { int retval; setbuf(stdout, 0); + if (lock_file(LOCK_FILE_NAME)) { + fprintf(stderr, "Another copy of BOINC is already running\n"); + exit(1); + } read_log_flags(); gstate.parse_cmdline(argc, argv); retval = gstate.init(); diff --git a/configure b/configure index 982a13e44f..ff81b5d1c0 100755 --- a/configure +++ b/configure @@ -1888,8 +1888,6 @@ main() { r.ru_majflt = r.ru_minflt = 0; switch (fork()) { case 0: /* Child. */ - /* Unless we actually _do_ something, the kernel sometimes doesn't chalk up any system time to this process. */ - if(fork()) { i = 123; wait(NULL); } else { i = 234; exit(0); } sleep(1); /* Give up the CPU. */ _exit(0); case -1: _exit(0); /* What can we do? */ @@ -1901,7 +1899,7 @@ main() { } } EOF -if { (eval echo configure:1905: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1903: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_wait3_rusage=yes else @@ -1923,15 +1921,15 @@ EOF fi -for ac_func in gethostname gettimeofday mkdir select socket strstr uname +for ac_func in gethostname gettimeofday mkdir select socket strstr uname lockf flock do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:1930: checking for $ac_func" >&5 +echo "configure:1928: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1956: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else diff --git a/configure.in b/configure.in index 10d16f19ab..738237ca1b 100644 --- a/configure.in +++ b/configure.in @@ -40,6 +40,6 @@ dnl Checks for library functions. AC_PROG_GCC_TRADITIONAL AC_FUNC_VPRINTF AC_FUNC_WAIT3 -AC_CHECK_FUNCS(gethostname gettimeofday mkdir select socket strstr uname) +AC_CHECK_FUNCS(gethostname gettimeofday mkdir select socket strstr uname lockf flock) AC_OUTPUT(RSAEuro/source/Makefile apps/Makefile db/Makefile sched/Makefile lib/Makefile tools/Makefile Makefile api/Makefile) diff --git a/doc/boinc.gif b/doc/boinc.gif index 50cde0af9c..bbaa5c2d07 100644 Binary files a/doc/boinc.gif and b/doc/boinc.gif differ diff --git a/lib/util.C b/lib/util.C index 2968346366..7909c70682 100755 --- a/lib/util.C +++ b/lib/util.C @@ -20,6 +20,9 @@ #include #include #include +#include +#include +#include #ifdef _WIN32 #include @@ -147,3 +150,29 @@ int parse_command_line(char* p, char** argv) { return argc; } +int lock_file(char* filename) { + int retval; + + // some systems have both! +#ifdef HAVE_LOCKF + int lock = open(filename, O_WRONLY|O_CREAT, 0644); + retval = lockf(lock, F_TLOCK, 1); + // must leave fd open +#else +#ifdef HAVE_FLOCK + int lock = open(filename, O_WRONLY|O_CREAT, 0644); + retval = flock(lock, LOCK_EX|LOCK_NB); +#endif +#endif + +#ifdef _WIN32 + HANDLE hfile = CreateFile( + filename, GENERIC_WRITE, + 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 + ); + if (hfile == INVALID_HANDLE_VALUE) retval = 1; + else retval = 0; +#endif + return retval; +} + diff --git a/lib/util.h b/lib/util.h index 2997e8ae53..1bb264bc7c 100755 --- a/lib/util.h +++ b/lib/util.h @@ -23,6 +23,7 @@ extern int double_to_ydhms (double x, int smallest_timescale, char *buf); extern double dtime(); extern void boinc_sleep( int seconds ); extern int parse_command_line( char *, char ** ); +extern int lock_file(char*); #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) diff --git a/todo b/todo index 9fb5581684..90d632551f 100755 --- a/todo +++ b/todo @@ -1,3 +1,7 @@ +write garbage collector + +prevent 2 core clients from running at once + support for HTTP and SOCKS proxies make get_local_ip_addr() work in all cases est_time_to_completion doesn't work for non-running tasks