bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug-gnulib] FYI: utime.c: don't leak a file descriptor, don't clobber e


From: Jim Meyering
Subject: [Bug-gnulib] FYI: utime.c: don't leak a file descriptor, don't clobber errno
Date: Mon, 17 Nov 2003 17:19:50 +0100

I've just checked this in:

2003-11-17  Jim Meyering  <address@hidden>

        On systems without utime and without a utimes function capable of
        dealing with a NULL struct utimbuf* argument, this utime replacement
        could -- in unusual circumstances -- leak a file descriptor.
        * utime.c: Include <unistd.h> and <errno.h>.
        (utime_null): Be sure to close `fd' and to preserve errno.
        Reported by Geoff Collyer via Arnold Robbins.

Index: utime.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/utime.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -p -u -r1.10 -r1.11
--- utime.c     8 Sep 2003 22:32:00 -0000       1.10
+++ utime.c     17 Nov 2003 16:16:00 -0000      1.11
@@ -32,6 +32,12 @@
 # include <fcntl.h>
 #endif
 
+#include <unistd.h>
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+
 #include "full-write.h"
 #include "safe-read.h"
 
@@ -59,6 +65,7 @@ utime_null (const char *file)
   char c;
   int status = 0;
   struct stat st;
+  int saved_errno = 0;
 
   fd = open (file, O_RDWR);
   if (fd < 0
@@ -70,9 +77,23 @@ utime_null (const char *file)
         of patches, but that system doesn't use this code: it has utimes.
         || fsync (fd) < 0
       */
-      || (st.st_size == 0 && ftruncate (fd, st.st_size) < 0)
-      || close (fd) < 0)
-    status = -1;
+      || (st.st_size == 0 && ftruncate (fd, st.st_size) < 0))
+    {
+      saved_errno = errno;
+      status = -1;
+    }
+
+  if (0 <= fd)
+    {
+      if (close (fd) < 0)
+       status = -1;
+
+      /* If there was a prior failure, use the saved errno value.
+        But if the only failure was in the close, don't change errno.  */
+      if (saved_errno)
+       errno = saved_errno;
+    }
+
   return status;
 #endif
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]