commit - a615e0e7796ea1103a6e0d4b5dbb613459788666
commit + 6d5a9006ab2a400b488b9e93ec9647fb9b2a0930
blob - 9e816e247d7da758b11ef445bf1ee6274ee14726
blob + 58d890d3d6f831f42b34c8497b53e4dbaafb6eb3
--- include/got_repository.h
+++ include/got_repository.h
*/
const char *got_repo_get_path_git_dir(struct got_repository *);
+/* Obtain the file descriptor of the repository's .git directory. */
+int got_repo_get_fd(struct got_repository *);
+
/* Obtain the commit author name if parsed from gitconfig, else NULL. */
const char *got_repo_get_gitconfig_author_name(struct got_repository *);
blob - c56e16c42ed63d3e61347e0ae35d4eec972e82d5
blob + 39aa4333097646e6b90b09899df9869839a65c43
--- lib/got_lib_pack.h
+++ lib/got_lib_pack.h
const struct got_error *got_packidx_init_hdr(struct got_packidx *, int);
const struct got_error *got_packidx_open(struct got_packidx **,
- const char *, int);
+ int, const char *, int);
const struct got_error *got_packidx_close(struct got_packidx *);
int got_packidx_get_object_idx(struct got_packidx *, struct got_object_id *);
const struct got_error *got_packidx_match_id_str_prefix(
blob - d2a6b78c48d166aadf6645f719cb29e4663cd851
blob + 18d2953bb12aa27108f0941f598a0b1d40a0c1ab
--- lib/got_lib_repository.h
+++ lib/got_lib_repository.h
struct got_repository {
char *path;
char *path_git_dir;
+ int gitdir_fd;
/* The pack index cache speeds up search for packed objects. */
struct got_packidx *packidx_cache[GOT_PACKIDX_CACHE_SIZE];
blob - 71b5e073f220e543460f8542ee644483ce51b73d
blob + b46583a6e3ce2fe952e1c30726026d492c7f5734
--- lib/pack.c
+++ lib/pack.c
}
const struct got_error *
-got_packidx_open(struct got_packidx **packidx, const char *path, int verify)
+got_packidx_open(struct got_packidx **packidx,
+ int dir_fd, const char *relpath, int verify)
{
const struct got_error *err = NULL;
struct got_packidx *p;
if (p == NULL)
return got_error_from_errno("calloc");
- p->fd = open(path, O_RDONLY | O_NOFOLLOW);
+ p->fd = openat(dir_fd, relpath, O_RDONLY | O_NOFOLLOW);
if (p->fd == -1) {
- err = got_error_from_errno2("open", path);
+ err = got_error_from_errno2("openat", relpath);
free(p);
return err;
}
if (fstat(p->fd, &sb) != 0) {
- err = got_error_from_errno2("fstat", path);
+ err = got_error_from_errno2("fstat", relpath);
close(p->fd);
free(p);
return err;
return err;
}
- p->path_packidx = strdup(path);
+ p->path_packidx = strdup(relpath);
if (p->path_packidx == NULL) {
err = got_error_from_errno("strdup");
goto done;
blob - 4c8c8ac61ee774c04b4daf2fe2e46b0b82fed5ac
blob + 7a2d2999eee396614f65ab978214ffc035a1f4c2
--- lib/repository.c
+++ lib/repository.c
got_repo_get_path_git_dir(struct got_repository *repo)
{
return repo->path_git_dir;
+}
+
+int
+got_repo_get_fd(struct got_repository *repo)
+{
+ return repo->gitdir_fd;
}
const char *
{
const struct got_error *err = NULL;
+ repo->gitdir_fd = -1;
+
/* bare git repository? */
repo->path_git_dir = strdup(path);
if (repo->path_git_dir == NULL)
repo->path = strdup(repo->path_git_dir);
if (repo->path == NULL) {
err = got_error_from_errno("strdup");
+ goto done;
+ }
+ repo->gitdir_fd = open(repo->path_git_dir, O_DIRECTORY);
+ if (repo->gitdir_fd == -1) {
+ err = got_error_from_errno2("open",
+ repo->path_git_dir);
goto done;
}
return NULL;
err = got_error_from_errno("strdup");
goto done;
}
+ repo->gitdir_fd = open(repo->path_git_dir, O_DIRECTORY);
+ if (repo->gitdir_fd == -1) {
+ err = got_error_from_errno2("open",
+ repo->path_git_dir);
+ goto done;
+ }
return NULL;
}
repo->path = NULL;
free(repo->path_git_dir);
repo->path_git_dir = NULL;
+ if (repo->gitdir_fd != -1)
+ close(repo->gitdir_fd);
+ repo->gitdir_fd = -1;
+
}
return err;
}
struct got_repository *repo, struct got_object_id *id)
{
const struct got_error *err;
- char *path_packdir;
- DIR *packdir;
+ DIR *packdir = NULL;
struct dirent *dent;
char *path_packidx;
size_t i;
+ int packdir_fd;
/* Search pack index cache. */
for (i = 0; i < nitems(repo->packidx_cache); i++) {
}
/* No luck. Search the filesystem. */
- path_packdir = got_repo_get_path_objects_pack(repo);
- if (path_packdir == NULL)
- return got_error_from_errno("got_repo_get_path_objects_pack");
-
- packdir = opendir(path_packdir);
- if (packdir == NULL) {
+ packdir_fd = openat(got_repo_get_fd(repo),
+ GOT_OBJECTS_PACK_DIR, O_DIRECTORY);
+ if (packdir_fd == -1) {
if (errno == ENOENT)
err = got_error_no_obj(id);
else
- err = got_error_from_errno2("opendir", path_packdir);
+ err = got_error_from_errno_fmt("openat: %s/%s",
+ got_repo_get_path_git_dir(repo),
+ GOT_OBJECTS_PACK_DIR);
goto done;
}
+ packdir = fdopendir(packdir_fd);
+ if (packdir == NULL) {
+ err = got_error_from_errno("fdopendir");
+ goto done;
+ }
+
while ((dent = readdir(packdir)) != NULL) {
int is_cached = 0;
if (!is_packidx_filename(dent->d_name, dent->d_namlen))
continue;
- if (asprintf(&path_packidx, "%s/%s", path_packdir,
+ if (asprintf(&path_packidx, "%s/%s", GOT_OBJECTS_PACK_DIR,
dent->d_name) == -1) {
err = got_error_from_errno("asprintf");
goto done;
continue; /* already searched */
}
- err = got_packidx_open(packidx, path_packidx, 0);
+ err = got_packidx_open(packidx, got_repo_get_fd(repo),
+ path_packidx, 0);
if (err) {
free(path_packidx);
goto done;
err = got_error_no_obj(id);
done:
- free(path_packdir);
if (packdir && closedir(packdir) != 0 && err == NULL)
err = got_error_from_errno("closedir");
return err;
}
static const struct got_error *
-open_packfile(int *fd, const char *path_packfile, struct got_packidx *packidx)
+open_packfile(int *fd, struct got_repository *repo,
+ const char *relpath, struct got_packidx *packidx)
{
const struct got_error *err = NULL;
- *fd = open(path_packfile, O_RDONLY | O_NOFOLLOW);
+ *fd = openat(got_repo_get_fd(repo), relpath, O_RDONLY | O_NOFOLLOW);
if (*fd == -1)
- return got_error_from_errno2("open", path_packfile);
+ return got_error_from_errno_fmt("openat: %s/%s",
+ got_repo_get_path_git_dir(repo), relpath);
if (packidx) {
err = read_packfile_hdr(*fd, packidx);
goto done;
}
- err = open_packfile(&pack->fd, path_packfile, packidx);
+ err = open_packfile(&pack->fd, repo, path_packfile, packidx);
if (err)
goto done;
struct got_repository *repo, const char *id_str_prefix, int obj_type)
{
const struct got_error *err = NULL;
- char *path_packdir;
- DIR *packdir;
+ DIR *packdir = NULL;
struct dirent *dent;
char *path_packidx;
struct got_object_id_queue matched_ids;
+ int packdir_fd;
SIMPLEQ_INIT(&matched_ids);
- path_packdir = got_repo_get_path_objects_pack(repo);
- if (path_packdir == NULL)
- return got_error_from_errno("got_repo_get_path_objects_pack");
-
- packdir = opendir(path_packdir);
- if (packdir == NULL) {
+ packdir_fd = openat(got_repo_get_fd(repo),
+ GOT_OBJECTS_PACK_DIR, O_DIRECTORY);
+ if (packdir_fd == -1) {
if (errno != ENOENT)
- err = got_error_from_errno2("opendir", path_packdir);
+ err = got_error_from_errno2("openat", GOT_OBJECTS_PACK_DIR);
+ goto done;
+ }
+
+ packdir = fdopendir(packdir_fd);
+ if (packdir == NULL) {
+ err = got_error_from_errno("fdopendir");
goto done;
}
struct got_packidx *packidx;
struct got_object_qid *qid;
-
if (!is_packidx_filename(dent->d_name, dent->d_namlen))
continue;
- if (asprintf(&path_packidx, "%s/%s", path_packdir,
+ if (asprintf(&path_packidx, "%s/%s", GOT_OBJECTS_PACK_DIR,
dent->d_name) == -1) {
- err = got_error_from_errno("asprintf");
+ err = got_error_from_errno("strdup");
break;
}
- err = got_packidx_open(&packidx, path_packidx, 0);
+ err = got_packidx_open(&packidx, got_repo_get_fd(repo),
+ path_packidx, 0);
free(path_packidx);
if (err)
break;
}
done:
got_object_id_queue_free(&matched_ids);
- free(path_packdir);
if (packdir && closedir(packdir) != 0 && err == NULL)
err = got_error_from_errno("closedir");
if (err) {