Merge branch 'jc/git-open-cloexec'

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
This commit is contained in:
Junio C Hamano 2017-01-10 15:24:26 -08:00
Родитель e484bcbab1 b4d065df03
Коммит 02d0457eb4
3 изменённых файлов: 24 добавлений и 38 удалений

Просмотреть файл

@ -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);

Просмотреть файл

@ -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];

Просмотреть файл

@ -28,14 +28,6 @@
#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;
static int o_cloexec = O_CLOEXEC;
errno = 0;
fd = open(name, O_RDONLY | sha1_file_open_flag);
if (fd >= 0)
return fd;
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)