diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2011-06-10 10:50:07 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2011-06-10 10:50:07 -0700 |
commit | 529a133c390049085db38e7c8f745d650a2626ee (patch) | |
tree | aaecf1090380ee50e0f15a102dd3be76dad9af10 /lib-src/movemail.c | |
parent | 2547adb13e24bcb6aa855b8e107a16bc0205002e (diff) | |
download | emacs-529a133c390049085db38e7c8f745d650a2626ee.tar.gz |
* movemail.c: Fix race condition and related bugs (Bug#8836).
(main) [!MAIL_USE_SYSTEM_LOCK]: Prefer mkstemp to mktemp, as this
fixes some race conditions. Report mkstemp/mktemp errno rather
than a possibly-garbage errno. Reinitialize the template each
time through the loop, as earlier mkstemp/mktemp calls could have
trashed it. Pass 0600 (not 0666) to mktemp, for consistency
with mkstemp; the permissions don't matter anyway.
Diffstat (limited to 'lib-src/movemail.c')
-rw-r--r-- | lib-src/movemail.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/lib-src/movemail.c b/lib-src/movemail.c index 4cf97cbac18..e8c09f090f3 100644 --- a/lib-src/movemail.c +++ b/lib-src/movemail.c @@ -168,8 +168,9 @@ main (int argc, char **argv) #ifndef MAIL_USE_SYSTEM_LOCK struct stat st; int tem; - char *lockname, *p; + char *lockname; char *tempname; + size_t inname_dirlen; int desc; #endif /* not MAIL_USE_SYSTEM_LOCK */ @@ -298,26 +299,38 @@ main (int argc, char **argv) to bug-gnu-emacs@prep.ai.mit.edu so we can fix it. */ lockname = concat (inname, ".lock", ""); - tempname = (char *) xmalloc (strlen (inname) + strlen ("EXXXXXX") + 1); - strcpy (tempname, inname); - p = tempname + strlen (tempname); - while (p != tempname && !IS_DIRECTORY_SEP (p[-1])) - p--; - *p = 0; - strcpy (p, "EXXXXXX"); - mktemp (tempname); - unlink (tempname); + for (inname_dirlen = strlen (inname); + inname_dirlen && !IS_DIRECTORY_SEP (inname[inname_dirlen - 1]); + inname_dirlen--) + continue; + tempname = (char *) xmalloc (inname_dirlen + sizeof "EXXXXXX"); while (1) { /* Create the lock file, but not under the lock file name. */ /* Give up if cannot do that. */ - desc = open (tempname, O_WRONLY | O_CREAT | O_EXCL, 0666); + + memcpy (tempname, inname, inname_dirlen); + strcpy (tempname + inname_dirlen, "EXXXXXX"); +#ifdef HAVE_MKSTEMP + desc = mkstemp (tempname); +#else + mktemp (tempname); + if (!*tempname) + desc = -1; + else + { + unlink (tempname); + desc = open (tempname, O_WRONLY | O_CREAT | O_EXCL, 0600); + } +#endif if (desc < 0) { + int mkstemp_errno = errno; char *message = (char *) xmalloc (strlen (tempname) + 50); sprintf (message, "creating %s, which would become the lock file", tempname); + errno = mkstemp_errno; pfatal_with_name (message); } close (desc); |