Merge branch 'jc/git-open-cloexec'
authorJunio C Hamano <gitster@pobox.com>
Tue, 10 Jan 2017 23:24:26 +0000 (15:24 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 10 Jan 2017 23:24:26 +0000 (15:24 -0800)
The codeflow of setting NOATIME and CLOEXEC on file descriptors Git
opens has been simplified.
We may want to drop the tip one, but we'll see.

* jc/git-open-cloexec:
sha1_file: stop opening files with O_NOATIME
git_open_cloexec(): use fcntl(2) w/ FD_CLOEXEC fallback
git_open(): untangle possible NOATIME and CLOEXEC interactions

cache.h
read-cache.c
sha1_file.c
diff --git a/cache.h b/cache.h
index b14c0e8e38498f3d1dbb50f40cc5e3b484e96583..1b67f078ddf7473cbde1351dc11405ec239e1373 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -1125,7 +1125,8 @@ extern int write_sha1_file(const void *buf, unsigned long len, const char *type,
 extern int hash_sha1_file_literally(const void *buf, unsigned long len, const char *type, unsigned char *sha1, unsigned flags);
 extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);
 extern int force_object_loose(const unsigned char *sha1, time_t mtime);
-extern int git_open(const char *name);
+extern int git_open_cloexec(const char *name, int flags);
+#define git_open(name) git_open_cloexec(name, O_RDONLY)
 extern void *map_sha1_file(const unsigned char *sha1, unsigned long *size);
 extern int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz);
 extern int parse_sha1_header(const char *hdr, unsigned long *sizep);
index f92a912dcb224b3f6da9e9be07a33cfe3b08edcc..2eca639cce3a084286418d56f2b48a4303c18dd7 100644 (file)
@@ -156,14 +156,7 @@ void fill_stat_cache_info(struct cache_entry *ce, struct stat *st)
 static int ce_compare_data(const struct cache_entry *ce, struct stat *st)
 {
        int match = -1;
-       static int cloexec = O_CLOEXEC;
-       int fd = open(ce->name, O_RDONLY | cloexec);
-
-       if ((cloexec & O_CLOEXEC) && fd < 0 && errno == EINVAL) {
-               /* Try again w/o O_CLOEXEC: the kernel might not support it */
-               cloexec &= ~O_CLOEXEC;
-               fd = open(ce->name, O_RDONLY | cloexec);
-       }
+       int fd = git_open_cloexec(ce->name, O_RDONLY);
 
        if (fd >= 0) {
                unsigned char sha1[20];
index 1173071859dae68f72cc72efb20f816152d3eabc..1eb47f61131a81b587dc4fe80e1b175f37ba0540 100644 (file)
 #include "mergesort.h"
 #include "quote.h"
 
-#ifndef O_NOATIME
-#if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
-#define O_NOATIME 01000000
-#else
-#define O_NOATIME 0
-#endif
-#endif
-
 #define SZ_FMT PRIuMAX
 static inline uintmax_t sz_fmt(size_t s) { return s; }
 
@@ -1611,31 +1603,31 @@ int check_sha1_signature(const unsigned char *sha1, void *map,
        return hashcmp(sha1, real_sha1) ? -1 : 0;
 }
 
-int git_open(const char *name)
+int git_open_cloexec(const char *name, int flags)
 {
-       static int sha1_file_open_flag = O_NOATIME | O_CLOEXEC;
-
-       for (;;) {
-               int fd;
-
-               errno = 0;
-               fd = open(name, O_RDONLY | sha1_file_open_flag);
-               if (fd >= 0)
-                       return fd;
+       int fd;
+       static int o_cloexec = O_CLOEXEC;
 
+       fd = open(name, flags | o_cloexec);
+       if ((o_cloexec & O_CLOEXEC) && fd < 0 && errno == EINVAL) {
                /* Try again w/o O_CLOEXEC: the kernel might not support it */
-               if ((sha1_file_open_flag & O_CLOEXEC) && errno == EINVAL) {
-                       sha1_file_open_flag &= ~O_CLOEXEC;
-                       continue;
-               }
+               o_cloexec &= ~O_CLOEXEC;
+               fd = open(name, flags | o_cloexec);
+       }
 
-               /* Might the failure be due to O_NOATIME? */
-               if (errno != ENOENT && (sha1_file_open_flag & O_NOATIME)) {
-                       sha1_file_open_flag &= ~O_NOATIME;
-                       continue;
+#if defined(F_GETFL) && defined(F_SETFL) && defined(FD_CLOEXEC)
+       {
+               static int fd_cloexec = FD_CLOEXEC;
+
+               if (!o_cloexec && 0 <= fd && fd_cloexec) {
+                       /* Opened w/o O_CLOEXEC?  try with fcntl(2) to add it */
+                       int flags = fcntl(fd, F_GETFL);
+                       if (fcntl(fd, F_SETFL, flags | fd_cloexec))
+                               fd_cloexec = 0;
                }
-               return -1;
        }
+#endif
+       return fd;
 }
 
 static int stat_sha1_file(const unsigned char *sha1, struct stat *st)