Skip to content

Commit

Permalink
hardlinks: use vector instead of linked list
Browse files Browse the repository at this point in the history
  • Loading branch information
bapt committed Dec 30, 2024
1 parent 74ec596 commit 49cabe5
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 21 deletions.
22 changes: 12 additions & 10 deletions libpkg/pkg_add.c
Original file line number Diff line number Diff line change
Expand Up @@ -1652,7 +1652,7 @@ pkg_add_fromdir(struct pkg *pkg, const char *src)
struct group *gr, grent;
int err, fd, fromfd;
int retcode;
hardlinks_t hardlinks = tll_init();
hardlinks_t hardlinks;
const char *path;
char buffer[1024];
size_t link_len;
Expand All @@ -1661,6 +1661,7 @@ pkg_add_fromdir(struct pkg *pkg, const char *src)
stringlist_t symlinks_allowed = tll_init();
tll_push_back(symlinks_allowed, pkg->prefix);

pkgvec_init(&hardlinks);
install_as_user = (getenv("INSTALL_AS_USER") != NULL);

fromfd = open(src, O_DIRECTORY);
Expand Down Expand Up @@ -1728,7 +1729,7 @@ pkg_add_fromdir(struct pkg *pkg, const char *src)
continue;
if (fstatat(fromfd, RELATIVE_PATH(f->path), &st,
AT_SYMLINK_NOFOLLOW) == -1) {
tll_free_and_free(hardlinks, free);
pkgvec_free_and_free(&hardlinks, free);
close(fromfd);
pkg_fatal_errno("%s%s", src, f->path);
}
Expand Down Expand Up @@ -1781,7 +1782,7 @@ pkg_add_fromdir(struct pkg *pkg, const char *src)
if ((link_len = readlinkat(fromfd,
RELATIVE_PATH(f->path), target,
sizeof(target))) == -1) {
tll_free_and_free(hardlinks, free);
pkgvec_free_and_free(&hardlinks, free);
close(fromfd);
pkg_fatal_errno("Impossible to read symlinks "
"'%s'", f->path);
Expand All @@ -1794,16 +1795,17 @@ pkg_add_fromdir(struct pkg *pkg, const char *src)
} else if (S_ISREG(st.st_mode)) {
if ((fd = openat(fromfd, RELATIVE_PATH(f->path),
O_RDONLY)) == -1) {
tll_free_and_free(hardlinks, free);
pkgvec_free_and_free(&hardlinks, free);
close(fromfd);
pkg_fatal_errno("Impossible to open source file"
" '%s'", RELATIVE_PATH(f->path));
}
path = NULL;
tll_foreach(hardlinks, hit) {
if (hit->item->ino == st.st_ino &&
hit->item->dev == st.st_dev) {
path = hit->item->path;
for (size_t i = 0; i < hardlinks.len; i++) {
struct hardlink *hit = hardlinks.d[i];
if (hit->ino == st.st_ino &&
hit->dev == st.st_dev) {
path = hit->path;
break;
}
}
Expand All @@ -1823,7 +1825,7 @@ pkg_add_fromdir(struct pkg *pkg, const char *src)
h->ino = st.st_ino;
h->dev = st.st_dev;
h->path = f->path;
tll_push_back(hardlinks, h);
pkgvec_push(&hardlinks, h);
}
close(fd);
} else {
Expand All @@ -1837,7 +1839,7 @@ pkg_add_fromdir(struct pkg *pkg, const char *src)

cleanup:
tll_free(symlinks_allowed);
tll_free_and_free(hardlinks, free);
pkgvec_free_and_free(&hardlinks, free);
close(fromfd);
return (retcode);
}
Expand Down
11 changes: 6 additions & 5 deletions libpkg/pkg_create.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ pkg_create_from_dir(struct pkg *pkg, const char *root,
const char *relocation;
char *manifest;
ucl_object_t *obj;
hardlinks_t hardlinks = tll_init();
hardlinks_t hardlinks;

pkgvec_init(&hardlinks);
if (pkg_is_valid(pkg) != EPKG_OK) {
pkg_emit_error("the package is not valid");
return (EPKG_FATAL);
Expand All @@ -95,13 +96,13 @@ pkg_create_from_dir(struct pkg *pkg, const char *root,

if (lstat(fpath, &st) == -1) {
pkg_emit_error("file '%s' is missing", fpath);
tll_free_and_free(hardlinks, free);
pkgvec_free_and_free(&hardlinks, free);
return (EPKG_FATAL);
}

if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))) {
pkg_emit_error("file '%s' is not a regular file or symlink", fpath);
tll_free_and_free(hardlinks, free);
pkgvec_free_and_free(&hardlinks, free);
return (EPKG_FATAL);
}

Expand All @@ -116,13 +117,13 @@ pkg_create_from_dir(struct pkg *pkg, const char *root,
file->sum = pkg_checksum_generate_file(fpath,
PKG_HASH_TYPE_SHA256_HEX);
if (file->sum == NULL) {
tll_free_and_free(hardlinks, free);
pkgvec_free_and_free(&hardlinks, free);
return (EPKG_FATAL);
}

counter_count();
}
tll_free_and_free(hardlinks, free);
pkgvec_free_and_free(&hardlinks, free);

counter_end();

Expand Down
3 changes: 2 additions & 1 deletion libpkg/pkg_ports.c
Original file line number Diff line number Diff line change
Expand Up @@ -1046,6 +1046,7 @@ plist_new(struct pkg *pkg, const char *stage)
p->post_install_buf = xstring_new();
p->pre_deinstall_buf = xstring_new();
p->post_deinstall_buf = xstring_new();
pkgvec_init(&p->hardlinks);

populate_keywords(p);

Expand All @@ -1071,7 +1072,7 @@ plist_free(struct plist *p)

free(p->uname);
free(p->gname);
tll_free_and_free(p->hardlinks, free);
pkgvec_free_and_free(&p->hardlinks, free);

xstring_free(p->post_deinstall_buf);
xstring_free(p->post_install_buf);
Expand Down
2 changes: 1 addition & 1 deletion libpkg/private/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ typedef tll(char *) stringlist_t;
__FILE__, __LINE__, sqlite3_errmsg(db)); \
} while (0)

typedef tll(struct hardlink *) hardlinks_t;
struct hardlink {
ino_t ino;
dev_t dev;
const char *path;
};
typedef pkgvec_t(struct hardlink *) hardlinks_t;

struct tempdir {
char name[PATH_MAX];
Expand Down
9 changes: 5 additions & 4 deletions libpkg/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,15 +323,16 @@ check_for_hardlink(hardlinks_t *hl, struct stat *st)
{
struct hardlink *h;

tll_foreach(*hl, it) {
if (it->item->ino == st->st_ino &&
it->item->dev == st->st_dev)
for (size_t i = 0; i < hl->len; i++) {
h = hl->d[i];
if (h->ino == st->st_ino &&
h->dev == st->st_dev)
return (true);
}
h = xcalloc(1, sizeof(*h));
h->ino = st->st_ino;
h->dev = st->st_dev;
tll_push_back(*hl, h);
pkgvec_push(hl, h);

return (false);
}
Expand Down

0 comments on commit 49cabe5

Please sign in to comment.