]> diplodocus.org Git - mdeliver/commitdiff
mdeliver/current/mdeliver.c:
authorepg <>
Sun, 19 Jan 2003 03:11:14 +0000 (03:11 +0000)
committerepg <>
Sun, 19 Jan 2003 03:11:14 +0000 (03:11 +0000)
    (deliver): In rev 1582 i changed this from using rename(2) to
    the recommended link(2) + unlink(2).  But in minc i was using
    open(2) + rename(2) instead, which is just as safe as link +
    unlink but with one advantage.  So switch to that model.

minc/current/minc:
    (store_message): Document the open + rename procedure and
    explain why it is used instead of link + unlink.

mdeliver.c

index f673597..93657dd 100644 (file)
@@ -227,7 +227,7 @@ static void
 deliver(char *maildir, char *newfn)
 {
     char fn[TMPNAMLEN];
 deliver(char *maildir, char *newfn)
 {
     char fn[TMPNAMLEN];
-    int fd;
+    int fd, tmpfd;
     char buf[BUFSIZ];           /* Allocated here only as an (early,
                                  * evil) space optimization. */
 
     char buf[BUFSIZ];           /* Allocated here only as an (early,
                                  * evil) space optimization. */
 
@@ -251,12 +251,18 @@ deliver(char *maildir, char *newfn)
     strcpy(newfn, fn);
     memcpy(newfn, "new", 3);
 
     strcpy(newfn, fn);
     memcpy(newfn, "new", 3);
 
-    if (link(fn, newfn) != 0) {
-        save_errno( unlink(fn) );
-        err(MDELIVER_EXITCODE, "Failed link(%s, new)", fn);
+    tmpfd = open(newfn, O_WRONLY | O_EXCL | O_CREAT, 0600);
+    if (tmpfd < 0) {
+        /* XXX: what error message to use? */
+        err(MDELIVER_EXITCODE, "Failed open(%s)", newfn);
     }
     }
+    close(tmpfd);
 
 
-    unlink(fn);
+    if (rename(fn, newfn) != 0) {
+        save_errno( unlink(newfn) );
+        save_errno( unlink(fn) );
+        err(MDELIVER_EXITCODE, "Failed rename(%s, new)", fn);
+    }
 }
 
 /* Run a program to process the new message. */
 }
 
 /* Run a program to process the new message. */