Fixed a potential race condition when writing scores.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1911 c06c8d41-db1a-0410-9941-cceddc491573
OTHTO2GQ6S7DWMZ5BT7CB2OEK54XLL4NMH4G4DNCHEBGGCY6Y2XQC
RISMOCQM6BKK4XSIRKYLOBB2UPDYJNDAL6OGIIR5GGNZQAK5YSZAC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
Z3RI4XAN7J2GUABAQ5G6YIOQYMBOAEQFFGRBWHMUEB2A2QYXO5MQC
SVFEYUMU7YSZYB3B33RJYJZRRELJ2PJFJXX6NRUV3NSWKMBT56EQC
GR6ZABTGAAQTKZBVA7PTOYQG6G3ACF62ITT5COLHTRN2HGIPRG2AC
// open highscore file (reading) -- note that NULL is not fatal!
scores = hs_open("r", score_file_name());
// open highscore file (reading) -- NULL is fatal!
//
// Opening as a+ instead of r+ to force an exclusive lock (see
// hs_open) and to create the file if it's not there already.
scores = hs_open("a+", score_file_name());
if (scores == NULL)
end(1, true, "failed to open score file for writing");
// open highscore file (writing) -- NULL *is* fatal here.
scores = hs_open("w", score_file_name());
if (scores == NULL)
// If we've still not inserted it, it's not a highscore.
if (!inserted)
// The old code closed and reopened the score file, leading to a
// race condition where one Crawl process could overwrite the
// other's highscore. Now we truncate and rewrite the file without
// closing it.
if (ftruncate(fileno(scores), 0))
end(1, true, "unable to truncate scorefile");
rewind(scores);