]> code.delx.au - gnu-emacs/blobdiff - lib-src/movemail.c
* make-docfile.c (write_globals): Warn about duplicate function
[gnu-emacs] / lib-src / movemail.c
index 4cf97cbac186cf9ebde583628060faa117fbbb8a..3d994ec5a5e0865f1d557beb530ce18fab445c78 100644 (file)
@@ -1,7 +1,7 @@
 /* movemail foo bar -- move file foo to file bar,
    locking file foo the way /bin/mail respects.
 
-Copyright (C) 1986, 1992-1994, 1996, 1999, 2001-2011
+Copyright (C) 1986, 1992-1994, 1996, 1999, 2001-2012
   Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -68,9 +68,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #ifdef HAVE_FCNTL_H
 #include <fcntl.h>
 #endif
-#ifdef HAVE_STRING_H
 #include <string.h>
-#endif
 #include "syswait.h"
 #ifdef MAIL_USE_POP
 #include "pop.h"
@@ -139,10 +137,10 @@ static char *mail_spool_name (char *);
 char *strerror (int);
 #endif
 
-static void fatal (const char *s1, const char *s2, const char *s3) NO_RETURN;
+static _Noreturn void fatal (const char *s1, const char *s2, const char *s3);
 static void error (const char *s1, const char *s2, const char *s3);
-static void pfatal_with_name (char *name) NO_RETURN;
-static void pfatal_and_delete (char *name) NO_RETURN;
+static _Noreturn void pfatal_with_name (char *name);
+static _Noreturn void pfatal_and_delete (char *name);
 static char *concat (const char *s1, const char *s2, const char *s3);
 static long *xmalloc (unsigned int size);
 #ifdef MAIL_USE_POP
@@ -168,8 +166,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 */
 
@@ -184,8 +183,8 @@ main (int argc, char **argv)
 # define ARGSTR "p"
 #endif /* MAIL_USE_POP */
 
-  uid_t real_gid = getgid();
-  uid_t priv_gid = getegid();
+  uid_t real_gid = getgid ();
+  uid_t priv_gid = getegid ();
 
 #ifdef WINDOWSNT
   /* Ensure all file i/o is in binary mode. */
@@ -298,27 +297,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)
            {
-             char *message = (char *) xmalloc (strlen (tempname) + 50);
-             sprintf (message, "creating %s, which would become the lock file",
-                      tempname);
-             pfatal_with_name (message);
+             int mkstemp_errno = errno;
+             error ("error while creating what would become the lock file",
+                    0, 0);
+             errno = mkstemp_errno;
+             pfatal_with_name (tempname);
            }
          close (desc);