tHigh score file now locked properly (at least on Unix systems) - vaccinewars - be a doctor and try to vaccinate the world
 (HTM) git clone git://src.adamsgaard.dk/vaccinewars
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit efe95b4aeddbb4032dc58dea10042eb47d7ef6f2
 (DIR) parent dce44c4d5f93daa2fee494d82233ad03ce10fd94
 (HTM) Author: Ben Webb <ben@salilab.org>
       Date:   Wed, 11 Apr 2001 21:33:24 +0000
       
       High score file now locked properly (at least on Unix systems)
       
       
       Diffstat:
         M src/dopeos.c                        |      30 +++++++++++++++++++++++++++++-
         M src/dopeos.h                        |       6 ++++++
         M src/serverside.c                    |       6 ++++--
       
       3 files changed, 39 insertions(+), 3 deletions(-)
       ---
 (DIR) diff --git a/src/dopeos.c b/src/dopeos.c
       t@@ -310,8 +310,14 @@ void SetReuse(SOCKET sock) {
           if (setsockopt(sock,SOL_SOCKET,
                          SO_REUSEADDR,(char *)(&tmp),sizeof(tmp))==-1) {
              perror("setsockopt"); exit(1);
       +   }
        }
       -}
       +
       +/* We don't do locking under Win32 right now */
       +int ReadLock(FILE *fp) { return 0; }
       +int WriteLock(FILE *fp) { return 0; }
       +void ReleaseLock(FILE *fp) { }
       +
        #endif /* NETWORKING */
        
        #else /* Code for Unix build */
       t@@ -324,6 +330,10 @@ void SetReuse(SOCKET sock) {
        #include <stdlib.h>
        #endif
        
       +#ifdef HAVE_FCNTL_H
       +#include <fcntl.h>
       +#endif
       +
        int Width,Depth;
        
        #ifdef CURSES_CLIENT
       t@@ -355,6 +365,24 @@ void SetReuse(int sock) {
        }
        #endif /* NETWORKING */
        
       +static int DoLock(FILE *fp,int l_type) {
       +   struct flock lk;
       +
       +   lk.l_type = l_type;
       +   lk.l_whence = lk.l_start = lk.l_len = 0;
       +   lk.l_pid = 0;
       +
       +   while(1) {
       +      if (fcntl(fileno(fp),F_SETLKW,&lk)==0) return 0;
       +      else if (errno!=EINTR) return 1;
       +   }
       +   return 1;
       +}
       +
       +int ReadLock(FILE *fp) { return DoLock(fp,F_RDLCK); }
       +int WriteLock(FILE *fp) { return DoLock(fp,F_WRLCK); }
       +void ReleaseLock(FILE *fp) { DoLock(fp,F_UNLCK); }
       +
        #endif /* CYGWIN */
        
        void MicroSleep(int microsec) {
 (DIR) diff --git a/src/dopeos.h b/src/dopeos.h
       t@@ -128,6 +128,8 @@ void SetReuse(SOCKET sock);
        
        #include <sys/types.h>
        
       +#include <stdio.h>
       +
        #ifdef NETWORKING
        #include <sys/socket.h>
        #include <netinet/in.h>
       t@@ -184,6 +186,10 @@ void SetReuse(int sock);
        
        void MicroSleep(int microsec);
        
       +int ReadLock(FILE *fp); 
       +int WriteLock(FILE *fp); 
       +void ReleaseLock(FILE *fp);
       +
        #ifndef SOCKET_ERROR
        #define SOCKET_ERROR -1
        #endif
 (DIR) diff --git a/src/serverside.c b/src/serverside.c
       t@@ -903,10 +903,11 @@ int HighScoreRead(struct HISCORE *MultiScore,struct HISCORE *AntiqueScore) {
        /* AntiqueScore (antique mode scores). Returns 1 on success, 0 on failure. */
           memset(MultiScore,0,sizeof(struct HISCORE)*NUMHISCORE);
           memset(AntiqueScore,0,sizeof(struct HISCORE)*NUMHISCORE);
       -   if (ScoreFP) {
       +   if (ScoreFP && ReadLock(ScoreFP)==0) {
              rewind(ScoreFP);
              HighScoreTypeRead(AntiqueScore,ScoreFP);
              HighScoreTypeRead(MultiScore,ScoreFP);
       +      ReleaseLock(ScoreFP);
           } else return 0;
           return 1;
        }
       t@@ -914,11 +915,12 @@ int HighScoreRead(struct HISCORE *MultiScore,struct HISCORE *AntiqueScore) {
        int HighScoreWrite(struct HISCORE *MultiScore,struct HISCORE *AntiqueScore) {
        /* Writes out all the high scores from MultiScore and AntiqueScore; returns */
        /* 1 on success, 0 on failure.                                              */
       -   if (ScoreFP) {
       +   if (ScoreFP && WriteLock(ScoreFP)==0) {
              ftruncate(fileno(ScoreFP),0);
              rewind(ScoreFP);
              HighScoreTypeWrite(AntiqueScore,ScoreFP);
              HighScoreTypeWrite(MultiScore,ScoreFP);
       +      ReleaseLock(ScoreFP);
           } else return 0;
           return 1;
        }