aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-04-10 17:35:24 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-04-12 20:41:34 +0200
commit426d2d521ccd44ff8c41d2577fbace6f1726dbd2 (patch)
tree0ca6bf21fad43d8fad6e8ec1ed85974c01031650
parent8059c42315a3ed3726b9b0a4e6293b1cccbaacc0 (diff)
Copy the dir scan pattern from the Windows implementation
If we look at a sub directory, piece totether the full path and open that instead. This allows us to move the directory open into the scan function and get rid of the dirfd trickery. Also pull the recusion step out into the parent function. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--bin/gensquashfs/src/fstree_from_dir.c104
1 files changed, 52 insertions, 52 deletions
diff --git a/bin/gensquashfs/src/fstree_from_dir.c b/bin/gensquashfs/src/fstree_from_dir.c
index 21c4b78..8923603 100644
--- a/bin/gensquashfs/src/fstree_from_dir.c
+++ b/bin/gensquashfs/src/fstree_from_dir.c
@@ -220,27 +220,30 @@ static char *read_link(const struct stat *sb, int dir_fd, const char *name)
return out;
}
-static int populate_dir(int dir_fd, fstree_t *fs, tree_node_t *root,
- dev_t devstart, scan_node_callback cb,
- void *user, unsigned int flags)
+static int populate_dir(const char *path, fstree_t *fs, tree_node_t *root,
+ scan_node_callback cb, void *user, unsigned int flags)
{
char *extra = NULL;
+ dev_t devstart = 0;
struct dirent *ent;
- int ret, childfd;
struct stat sb;
tree_node_t *n;
DIR *dir;
+ int ret;
- dir = fdopendir(dir_fd);
+ dir = opendir(path);
if (dir == NULL) {
- perror("fdopendir");
- close(dir_fd);
+ perror(path);
return -1;
}
- /* XXX: fdopendir can dup and close dir_fd internally
- and still be compliant with the spec. */
- dir_fd = dirfd(dir);
+ if (flags & DIR_SCAN_ONE_FILESYSTEM) {
+ if (fstat(dirfd(dir), &sb)) {
+ perror(path);
+ goto fail;
+ }
+ devstart = sb.st_dev;
+ }
for (;;) {
errno = 0;
@@ -254,7 +257,8 @@ static int populate_dir(int dir_fd, fstree_t *fs, tree_node_t *root,
break;
}
- if (fstatat(dir_fd, ent->d_name, &sb, AT_SYMLINK_NOFOLLOW)) {
+ if (fstatat(dirfd(dir), ent->d_name,
+ &sb, AT_SYMLINK_NOFOLLOW)) {
perror(ent->d_name);
goto fail;
}
@@ -266,7 +270,7 @@ static int populate_dir(int dir_fd, fstree_t *fs, tree_node_t *root,
continue;
if (S_ISLNK(sb.st_mode)) {
- extra = read_link(&sb, dir_fd, ent->d_name);
+ extra = read_link(&sb, dirfd(dir), ent->d_name);
if (extra == NULL) {
perror("readlink");
goto fail;
@@ -300,24 +304,8 @@ static int populate_dir(int dir_fd, fstree_t *fs, tree_node_t *root,
if (ret < 0)
goto fail;
- if (ret > 0) {
+ if (ret > 0)
discard_node(root, n);
- continue;
- }
-
- if (S_ISDIR(n->mode) && !(flags & DIR_SCAN_NO_RECURSION)) {
- childfd = openat(dir_fd, n->name, O_DIRECTORY |
- O_RDONLY | O_CLOEXEC);
- if (childfd < 0) {
- perror(n->name);
- goto fail;
- }
-
- if (populate_dir(childfd, fs, n, devstart,
- cb, user, flags)) {
- goto fail;
- }
- }
}
closedir(dir);
@@ -333,8 +321,9 @@ int fstree_from_subdir(fstree_t *fs, tree_node_t *root,
scan_node_callback cb, void *user,
unsigned int flags)
{
- struct stat sb;
- int fd, subfd;
+ size_t plen, slen;
+ char *temp = NULL;
+ tree_node_t *n;
if (!S_ISDIR(root->mode)) {
fprintf(stderr,
@@ -343,35 +332,46 @@ int fstree_from_subdir(fstree_t *fs, tree_node_t *root,
return -1;
}
- fd = open(path, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
- if (fd < 0) {
- perror(path);
- return -1;
- }
-
- if (subdir != NULL) {
- subfd = openat(fd, subdir, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
+ plen = strlen(path);
+ slen = subdir == NULL ? 0 : strlen(subdir);
- if (subfd < 0) {
- fprintf(stderr, "%s/%s: %s\n", path, subdir,
- strerror(errno));
- close(fd);
+ if (slen > 0) {
+ temp = calloc(1, plen + 1 + slen + 1);
+ if (temp == NULL) {
+ fprintf(stderr, "%s/%s: allocation failure.\n",
+ path, subdir);
return -1;
}
- close(fd);
- fd = subfd;
+ memcpy(temp, path, plen);
+ temp[plen] = '/';
+ memcpy(temp + plen + 1, subdir, slen);
+ temp[plen + 1 + slen] = '\0';
+
+ path = temp;
}
- if (fstat(fd, &sb)) {
- fprintf(stderr, "%s/%s: %s\n", path,
- subdir == NULL ? "" : subdir,
- strerror(errno));
- close(fd);
- return -1;
+ if (populate_dir(path, fs, root, cb, user, flags))
+ goto fail;
+
+ if (flags & DIR_SCAN_NO_RECURSION) {
+ free(temp);
+ return 0;
}
- return populate_dir(fd, fs, root, sb.st_dev, cb, user, flags);
+ for (n = root->data.dir.children; n != NULL; n = n->next) {
+ if (!S_ISDIR(n->mode))
+ continue;
+
+ if (fstree_from_subdir(fs, n, path, n->name, cb, user, flags))
+ goto fail;
+ }
+
+ free(temp);
+ return 0;
+fail:
+ free(temp);
+ return -1;
}
#endif