object-file: move `git_open_cloexec()` to "compat/open.c"

The `git_open_cloexec()` wrapper function provides the ability to open a
file with `O_CLOEXEC` in a platform-agnostic way. This function is
provided by "object-file.c" even though it is not specific to the object
subsystem at all.

Move the file into "compat/open.c". This file already exists before this
commit, but has only been compiled conditionally depending on whether or
not open(3p) may return EINTR. With this change we now unconditionally
compile the object, but wrap `git_open_with_retry()` in an ifdef.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
main
Patrick Steinhardt 2025-04-15 11:38:16 +02:00 committed by Junio C Hamano
parent 1a99fe8010
commit 97dc141fd6
11 changed files with 34 additions and 36 deletions

View File

@ -994,6 +994,7 @@ LIB_OBJS += common-exit.o
LIB_OBJS += common-init.o
LIB_OBJS += compat/nonblock.o
LIB_OBJS += compat/obstack.o
LIB_OBJS += compat/open.o
LIB_OBJS += compat/terminal.o
LIB_OBJS += compiler-tricks/not-constant.o
LIB_OBJS += config.o
@ -1812,7 +1813,6 @@ ifdef FREAD_READS_DIRECTORIES
endif
ifdef OPEN_RETURNS_EINTR
COMPAT_CFLAGS += -DOPEN_RETURNS_EINTR
COMPAT_OBJS += compat/open.o
endif
ifdef NO_SYMLINK_HEAD
BASIC_CFLAGS += -DNO_SYMLINK_HEAD

View File

@ -13,7 +13,6 @@
#include "refs.h"
#include "hash-lookup.h"
#include "commit-graph.h"
#include "object-file.h"
#include "object-store-ll.h"
#include "oid-array.h"
#include "path.h"

View File

@ -1,5 +1,6 @@
#include "git-compat-util.h"

#ifdef OPEN_RETURNS_EINTR
#undef open
int git_open_with_retry(const char *path, int flags, ...)
{
@ -23,3 +24,31 @@ int git_open_with_retry(const char *path, int flags, ...)

return ret;
}
#endif

int git_open_cloexec(const char *name, int flags)
{
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 */
o_cloexec &= ~O_CLOEXEC;
fd = open(name, flags | o_cloexec);
}

#if defined(F_GETFD) && defined(F_SETFD) && 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_GETFD);
if (fcntl(fd, F_SETFD, flags | fd_cloexec))
fd_cloexec = 0;
}
}
#endif
return fd;
}

View File

@ -1000,6 +1000,9 @@ int git_vsnprintf(char *str, size_t maxsize,
int git_open_with_retry(const char *path, int flag, ...);
#endif

int git_open_cloexec(const char *name, int flags);
#define git_open(name) git_open_cloexec(name, O_RDONLY)

#ifdef __GLIBC_PREREQ
#if __GLIBC_PREREQ(2, 1)
#define HAVE_STRCHRNUL

View File

@ -263,6 +263,7 @@ libgit_sources = [
'common-init.c',
'compat/nonblock.c',
'compat/obstack.c',
'compat/open.c',
'compat/terminal.c',
'compiler-tricks/not-constant.c',
'config.c',

1
midx.c
View File

@ -5,7 +5,6 @@
#include "dir.h"
#include "hex.h"
#include "packfile.h"
#include "object-file.h"
#include "hash-lookup.h"
#include "midx.h"
#include "progress.h"

View File

@ -833,33 +833,6 @@ int stream_object_signature(struct repository *r, const struct object_id *oid)
return !oideq(oid, &real_oid) ? -1 : 0;
}

int git_open_cloexec(const char *name, int flags)
{
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 */
o_cloexec &= ~O_CLOEXEC;
fd = open(name, flags | o_cloexec);
}

#if defined(F_GETFD) && defined(F_SETFD) && 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_GETFD);
if (fcntl(fd, F_SETFD, flags | fd_cloexec))
fd_cloexec = 0;
}
}
#endif
return fd;
}

/*
* Find "oid" as a loose object in the local repository or in an alternate.
* Returns 0 on success, negative on failure.

View File

@ -21,9 +21,6 @@ extern int fetch_if_missing;
int index_fd(struct index_state *istate, struct object_id *oid, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags);
int index_path(struct index_state *istate, struct object_id *oid, const char *path, struct stat *st, unsigned flags);

int git_open_cloexec(const char *name, int flags);
#define git_open(name) git_open_cloexec(name, O_RDONLY)

/**
* unpack_loose_header() initializes the data stream needed to unpack
* a loose object header.

View File

@ -17,7 +17,6 @@
#include "packfile.h"
#include "repository.h"
#include "trace2.h"
#include "object-file.h"
#include "object-store-ll.h"
#include "list-objects-filter-options.h"
#include "midx.h"

View File

@ -1,7 +1,6 @@
#include "git-compat-util.h"
#include "gettext.h"
#include "pack-mtimes.h"
#include "object-file.h"
#include "object-store-ll.h"
#include "packfile.h"
#include "strbuf.h"

View File

@ -1,7 +1,6 @@
#include "git-compat-util.h"
#include "gettext.h"
#include "pack-revindex.h"
#include "object-file.h"
#include "object-store-ll.h"
#include "packfile.h"
#include "strbuf.h"