Merge branch 'ls/git-open-cloexec'
Git generally does not explicitly close file descriptors that were open in the parent process when spawning a child process, but most of the time the child does not want to access them. As Windows does not allow removing or renaming a file that has a file descriptor open, a slow-to-exit child can even break the parent process by holding onto them. Use O_CLOEXEC flag to open files in various codepaths. * ls/git-open-cloexec: read-cache: make sure file handles are not inherited by child processes sha1_file: open window into packfiles with O_CLOEXEC sha1_file: rename git_open_noatime() to git_open()maint
commit
906d6906fb
|
@ -720,7 +720,7 @@ static off_t write_reused_pack(struct sha1file *f)
|
|||
if (!is_pack_valid(reuse_packfile))
|
||||
die("packfile is invalid: %s", reuse_packfile->pack_name);
|
||||
|
||||
fd = git_open_noatime(reuse_packfile->pack_name);
|
||||
fd = git_open(reuse_packfile->pack_name);
|
||||
if (fd < 0)
|
||||
die_errno("unable to open packfile for reuse: %s",
|
||||
reuse_packfile->pack_name);
|
||||
|
|
2
cache.h
2
cache.h
|
@ -1125,7 +1125,7 @@ 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_noatime(const char *name);
|
||||
extern int git_open(const char *name);
|
||||
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);
|
||||
|
|
|
@ -266,7 +266,7 @@ static int open_pack_bitmap_1(struct packed_git *packfile)
|
|||
return -1;
|
||||
|
||||
idx_name = pack_bitmap_filename(packfile);
|
||||
fd = git_open_noatime(idx_name);
|
||||
fd = git_open(idx_name);
|
||||
free(idx_name);
|
||||
|
||||
if (fd < 0)
|
||||
|
|
|
@ -156,7 +156,14 @@ 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;
|
||||
int fd = open(ce->name, O_RDONLY);
|
||||
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);
|
||||
}
|
||||
|
||||
if (fd >= 0) {
|
||||
unsigned char sha1[20];
|
||||
|
|
25
sha1_file.c
25
sha1_file.c
|
@ -370,7 +370,7 @@ void read_info_alternates(const char * relative_base, int depth)
|
|||
int fd;
|
||||
|
||||
path = xstrfmt("%s/info/alternates", relative_base);
|
||||
fd = git_open_noatime(path);
|
||||
fd = git_open(path);
|
||||
free(path);
|
||||
if (fd < 0)
|
||||
return;
|
||||
|
@ -663,7 +663,7 @@ static int check_packed_git_idx(const char *path, struct packed_git *p)
|
|||
struct pack_idx_header *hdr;
|
||||
size_t idx_size;
|
||||
uint32_t version, nr, i, *index;
|
||||
int fd = git_open_noatime(path);
|
||||
int fd = git_open(path);
|
||||
struct stat st;
|
||||
|
||||
if (fd < 0)
|
||||
|
@ -1069,7 +1069,7 @@ static int open_packed_git_1(struct packed_git *p)
|
|||
while (pack_max_fds <= pack_open_fds && close_one_pack())
|
||||
; /* nothing */
|
||||
|
||||
p->pack_fd = git_open_noatime(p->pack_name);
|
||||
p->pack_fd = git_open(p->pack_name);
|
||||
if (p->pack_fd < 0 || fstat(p->pack_fd, &st))
|
||||
return -1;
|
||||
pack_open_fds++;
|
||||
|
@ -1586,9 +1586,9 @@ int check_sha1_signature(const unsigned char *sha1, void *map,
|
|||
return hashcmp(sha1, real_sha1) ? -1 : 0;
|
||||
}
|
||||
|
||||
int git_open_noatime(const char *name)
|
||||
int git_open(const char *name)
|
||||
{
|
||||
static int sha1_file_open_flag = O_NOATIME;
|
||||
static int sha1_file_open_flag = O_NOATIME | O_CLOEXEC;
|
||||
|
||||
for (;;) {
|
||||
int fd;
|
||||
|
@ -1598,12 +1598,17 @@ int git_open_noatime(const char *name)
|
|||
if (fd >= 0)
|
||||
return fd;
|
||||
|
||||
/* Might the failure be due to O_NOATIME? */
|
||||
if (errno != ENOENT && sha1_file_open_flag) {
|
||||
sha1_file_open_flag = 0;
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Might the failure be due to O_NOATIME? */
|
||||
if (errno != ENOENT && (sha1_file_open_flag & O_NOATIME)) {
|
||||
sha1_file_open_flag &= ~O_NOATIME;
|
||||
continue;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -1632,7 +1637,7 @@ static int open_sha1_file(const unsigned char *sha1)
|
|||
struct alternate_object_database *alt;
|
||||
int most_interesting_errno;
|
||||
|
||||
fd = git_open_noatime(sha1_file_name(sha1));
|
||||
fd = git_open(sha1_file_name(sha1));
|
||||
if (fd >= 0)
|
||||
return fd;
|
||||
most_interesting_errno = errno;
|
||||
|
@ -1640,7 +1645,7 @@ static int open_sha1_file(const unsigned char *sha1)
|
|||
prepare_alt_odb();
|
||||
for (alt = alt_odb_list; alt; alt = alt->next) {
|
||||
const char *path = alt_sha1_path(alt, sha1);
|
||||
fd = git_open_noatime(path);
|
||||
fd = git_open(path);
|
||||
if (fd >= 0)
|
||||
return fd;
|
||||
if (most_interesting_errno == ENOENT)
|
||||
|
|
Loading…
Reference in New Issue