tHigh score file now locked properly (at least on Unix systems) - vaccinewars - be a doctor and try to vaccinate the world
git clone git://src.adamsgaard.dk/vaccinewars
Log
Files
Refs
README
LICENSE
---
commit efe95b4aeddbb4032dc58dea10042eb47d7ef6f2
parent dce44c4d5f93daa2fee494d82233ad03ce10fd94
Author: Ben Webb 
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(-)
---
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 
 #endif
 
+#ifdef HAVE_FCNTL_H
+#include 
+#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) {
diff --git a/src/dopeos.h b/src/dopeos.h
t@@ -128,6 +128,8 @@ void SetReuse(SOCKET sock);
 
 #include 
 
+#include 
+
 #ifdef NETWORKING
 #include 
 #include 
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
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;
 }