tHigh score file now locked properly (at least on Unix systems) - vaccinewars -… | |
git clone git://src.adamsgaard.dk/vaccinewars | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit efe95b4aeddbb4032dc58dea10042eb47d7ef6f2 | |
parent dce44c4d5f93daa2fee494d82233ad03ce10fd94 | |
Author: Ben Webb <[email protected]> | |
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 <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) { | |
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 | |
diff --git a/src/serverside.c b/src/serverside.c | |
t@@ -903,10 +903,11 @@ int HighScoreRead(struct HISCORE *MultiScore,struct HISC… | |
/* 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 HISC… | |
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; | |
} |