Fix bugs in update-game-score, on MS-Windows and elsewhere.
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.
This commit is contained in:
parent
5c0e57feb7
commit
98a428c15a
4 changed files with 60 additions and 28 deletions
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue