diff -r 172146fe48a2 MoinMoin/user.py
--- a/MoinMoin/user.py	Tue May 11 23:08:11 2010 +0200
+++ b/MoinMoin/user.py	Sun May 16 19:01:30 2010 +0200
@@ -19,12 +19,12 @@
     @license: GNU GPL, see COPYING for details.
 """
 
-import os, time, codecs, base64
+import os, time, codecs, base64, tempfile
 
 from MoinMoin.support.python_compatibility import hash_new, hmac_new
 
 from MoinMoin import config, caching, wikiutil, i18n, events
-from MoinMoin.util import timefuncs, random_string
+from MoinMoin.util import filesys, timefuncs, random_string
 from MoinMoin.wikiutil import url_quote_plus
 
 
@@ -542,11 +542,8 @@
             os.makedirs(user_dir)
 
         self.last_saved = str(time.time())
-
-        # !!! should write to a temp file here to avoid race conditions,
-        # or even better, use locking
-
-        data = codecs.open(self.__filename(), "w", config.charset)
+        fd, _tmp_filename = tempfile.mkstemp('.tmp', self.__filename(), self._cfg.user_dir)
+        data = codecs.open(_tmp_filename, "w", config.charset)
         data.write("# Data saved '%s' for id '%s'\n" % (
             time.strftime(self._cfg.datetime_fmt, time.localtime(time.time())),
             self.id))
@@ -565,6 +562,7 @@
             line = line.replace('\n', ' ').replace('\r', ' ') # no lineseps
             data.write(line + '\n')
         data.close()
+        filesys.rename(_tmp_filename, self.__filename())
 
         arena = 'user'
         key = 'name2id'
