From 531e70eca4c3bcd44942a67f5ea1a8bb1cb41dad Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 27 Feb 2013 20:37:31 +0200 Subject: [PATCH] Fix race conditions with MS-Windows lock files by using _sopen. src/filelock.c (create_lock_file) [WINDOWSNT]: Use _sopen with _SH_DENYRW flag, instead of emacs_open, to deny any other process access to the lock file until it is written and closed. Fixes: debbugs:13807 --- src/ChangeLog | 7 +++++++ src/filelock.c | 14 ++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index f5617487fd..4135dadf28 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2013-02-27 Eli Zaretskii + + * filelock.c (create_lock_file) [WINDOWSNT]: Use _sopen with + _SH_DENYRW flag, instead of emacs_open, to deny any other process + access to the lock file until it is written and closed. + (Bug#13807) + 2013-02-27 Paul Eggert * callint.c (Qcall_interactively): diff --git a/src/filelock.c b/src/filelock.c index 4d556de245..78cd60a12e 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -44,6 +44,7 @@ along with GNU Emacs. If not, see . */ #include "coding.h" #include "systime.h" #ifdef WINDOWSNT +#include #include "w32.h" /* for dostounix_filename */ #endif @@ -353,12 +354,17 @@ create_lock_file (char *lfname, char *lock_info_str, bool force) create a regular file with the lock info written as its contents. */ { - int fd = emacs_open (lfname, O_WRONLY | O_BINARY | O_CREAT | O_EXCL, - S_IREAD | S_IWRITE); + /* Deny everybody else any kind of access to the file until we are + done writing it and close the handle. This makes the entire + open/write/close operation atomic, as far as other processes + are concerned. */ + int fd = _sopen (lfname, + _O_WRONLY | _O_BINARY | _O_CREAT | _O_EXCL | _O_NOINHERIT, + _SH_DENYRW, S_IREAD | S_IWRITE); if (fd < 0 && errno == EEXIST && force) - fd = emacs_open (lfname, O_WRONLY | O_BINARY | O_TRUNC, - S_IREAD | S_IWRITE); + fd = _sopen (lfname, _O_WRONLY | _O_BINARY | _O_TRUNC |_O_NOINHERIT, + _SH_DENYRW, S_IREAD | S_IWRITE); if (fd >= 0) { ssize_t lock_info_len = strlen (lock_info_str); -- 2.39.2