]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix bugs in update-game-score, on MS-Windows and elsewhere.
authorEli Zaretskii <eliz@gnu.org>
Mon, 5 Aug 2013 17:09:28 +0000 (20:09 +0300)
committerEli Zaretskii <eliz@gnu.org>
Mon, 5 Aug 2013 17:09:28 +0000 (20:09 +0300)
 lib-src/update-game-score.c (read_score): Try reading a character before
 probing the stream for EOF.  Initialize score->score to zero,
 before reading and accumulating the score.
 (read_scores): Fix logic that determines which value to return.
 Close the input stream when finished reading the scores (avoids
 failures in overwriting the file with a new one on MS-Windows,
 since a file that is open cannot be deleted).
 lib-src/ntlib.h (rename): Don't undefine.
 lib-src/ntlib.c (sys_rename): New function, needed for
 update-game-score.

lib-src/ChangeLog
lib-src/ntlib.c
lib-src/ntlib.h
lib-src/update-game-score.c

index ace62d9d8f7bcd6abd07b13b29f09fc38f5c98e2..0336eae0981663cf8695ae73519701f6ecd56d6b 100644 (file)
@@ -1,3 +1,18 @@
+2013-08-05  Eli Zaretskii  <eliz@gnu.org>
+
+       * update-game-score.c (read_score): Try reading a character before
+       probing the stream for EOF.  Initialize score->score to zero,
+       before reading and accumulating the score.
+       (read_scores): Fix logic that determines which value to return.
+       Close the input stream when finished reading the scores (avoids
+       failures in overwriting the file with a new one on MS-Windows,
+       since a file that is open cannot be deleted).
+
+       * ntlib.h (rename): Don't undefine.
+
+       * ntlib.c (sys_rename): New function, needed for
+       update-game-score.
+
 2013-08-04  Eli Zaretskii  <eliz@gnu.org>
 
        * ntlib.h: Include fcntl.h.
index 0d0642d1bf225ed05044715054dc93a21c87440f..ab7d8b590df7fa59a05deb4d2fdcd13d311e75c6 100644 (file)
@@ -424,14 +424,14 @@ lstat (const char * path, struct stat * buf)
 }
 
 /* Implementation of mkostemp for MS-Windows, to avoid race conditions
-   when using mktemp.
+   when using mktemp.  Copied from w32.c.
 
-   Standard algorithm for generating a temporary file name seems to be
-   use pid or tid with a letter on the front (in place of the 6 X's)
-   and cycle through the letters to find a unique name.  We extend
-   that to allow any reasonable character as the first of the 6 X's,
-   so that the number of simultaneously used temporary files will be
-   greater.  */
+   This is used only in update-game-score.c.  It is overkill for that
+   use case, since update-game-score renames the temporary file into
+   the game score file, which isn't atomic on MS-Windows anyway, when
+   the game score already existed before running the program, which it
+   almost always does.  But using a simpler implementation just to
+   make a point is uneconomical...  */
 
 int
 mkostemp (char * template, int flags)
@@ -477,3 +477,17 @@ mkostemp (char * template, int flags)
   /* Template is badly formed or else we can't generate a unique name.  */
   return -1;
 }
+
+/* On Windows, you cannot rename into an existing file.  */
+int
+sys_rename (const char *from, const char *to)
+{
+  int retval = rename (from, to);
+
+  if (retval < 0 && errno == EEXIST)
+    {
+      if (unlink (to) == 0)
+       retval = rename (from, to);
+    }
+  return retval;
+}
index c30958365ca599eae498e9f6041a93f9950b6242..ab5f5ea3b890493edd64ce6ce86803eae152236c 100644 (file)
@@ -69,7 +69,6 @@ int mkostemp (char * template, int flags);
 #define pipe    _pipe
 #undef read
 #define read    _read
-#undef rename
 #undef rmdir
 #define rmdir   _rmdir
 #undef unlink
index 1699e305c8d57433a1e7832b4e088c6fea4e8d86..92c1663f6585fb0bfcb1bbcf3ff4b171492d3a7e 100644 (file)
@@ -228,10 +228,11 @@ static int
 read_score (FILE *f, struct score_entry *score)
 {
   int c;
+  if ((c = getc (f)) != EOF)
+    ungetc (c, f);
   if (feof (f))
     return 1;
-  while ((c = getc (f)) != EOF
-        && isdigit (c))
+  for (score->score = 0; (c = getc (f)) != EOF && isdigit (c); )
     {
       score->score *= 10;
       score->score += (c-48);
@@ -311,34 +312,38 @@ read_score (FILE *f, struct score_entry *score)
 static int
 read_scores (const char *filename, struct score_entry **scores, int *count)
 {
-  int readval, scorecount, cursize;
+  int readval = -1, scorecount, cursize;
   struct score_entry *ret;
   FILE *f = fopen (filename, "r");
+  int retval = -1;
   if (!f)
     return -1;
   scorecount = 0;
   cursize = 16;
   ret = (struct score_entry *) malloc (sizeof (struct score_entry) * cursize);
-  if (!ret)
-    return -1;
-  while ((readval = read_score (f, &ret[scorecount])) == 0)
+  if (ret)
     {
-      /* We encountered an error.  */
-      if (readval < 0)
-       return -1;
-      scorecount++;
-      if (scorecount >= cursize)
+      while ((readval = read_score (f, &ret[scorecount])) == 0)
        {
-         cursize *= 2;
-         ret = (struct score_entry *)
-           realloc (ret, (sizeof (struct score_entry) * cursize));
-         if (!ret)
-           return -1;
+         scorecount++;
+         if (scorecount >= cursize)
+           {
+             cursize *= 2;
+             ret = (struct score_entry *)
+               realloc (ret, (sizeof (struct score_entry) * cursize));
+             if (!ret)
+               break;
+           }
        }
     }
-  *count = scorecount;
-  *scores = ret;
-  return 0;
+  if (readval > 0)
+    {
+      *count = scorecount;
+      *scores = ret;
+      retval = 0;
+    }
+  fclose (f);
+  return retval;
 }
 
 static int
@@ -461,5 +466,4 @@ unlock_file (const char *filename, void *state)
   return ret;
 }
 
-
 /* update-game-score.c ends here */