This commit is contained in:
parent
bf96705ac4
commit
13c98166d5
@ -1,3 +1,9 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Sat Oct 27 18:17:58 CEST 2007 - agruen@suse.de
|
||||||
|
|
||||||
|
- Don't exhaust the number of file descriptors in the path walking
|
||||||
|
code, and make sure each directory is only visited once.
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Fri Oct 26 02:34:02 CEST 2007 - agruen@suse.de
|
Fri Oct 26 02:34:02 CEST 2007 - agruen@suse.de
|
||||||
|
|
||||||
|
5
acl.spec
5
acl.spec
@ -16,7 +16,7 @@ Group: System/Filesystems
|
|||||||
AutoReqProv: on
|
AutoReqProv: on
|
||||||
Summary: Commands for Manipulating POSIX Access Control Lists
|
Summary: Commands for Manipulating POSIX Access Control Lists
|
||||||
Version: 2.2.45
|
Version: 2.2.45
|
||||||
Release: 1
|
Release: 3
|
||||||
Source: %name-%version.src.tar.bz2
|
Source: %name-%version.src.tar.bz2
|
||||||
Patch0: builddefs.in.diff
|
Patch0: builddefs.in.diff
|
||||||
Patch1: walk-acl.diff
|
Patch1: walk-acl.diff
|
||||||
@ -179,6 +179,9 @@ rm -f $RPM_BUILD_ROOT/%{_lib}/libacl.{a,la,so}
|
|||||||
%defattr(755,root,root,755)
|
%defattr(755,root,root,755)
|
||||||
/%{_lib}/libacl.so.1*
|
/%{_lib}/libacl.so.1*
|
||||||
%changelog
|
%changelog
|
||||||
|
* Sat Oct 27 2007 - agruen@suse.de
|
||||||
|
- Don't exhaust the number of file descriptors in the path walking
|
||||||
|
code, and make sure each directory is only visited once.
|
||||||
* Fri Oct 26 2007 - agruen@suse.de
|
* Fri Oct 26 2007 - agruen@suse.de
|
||||||
- A large jump to the current upstream version 2.2.45.
|
- A large jump to the current upstream version 2.2.45.
|
||||||
- Fix the upstream path walking code.
|
- Fix the upstream path walking code.
|
||||||
|
217
walk-acl.diff
217
walk-acl.diff
@ -80,7 +80,7 @@ Index: acl-2.2.45/getfacl/getfacl.c
|
|||||||
|
|
||||||
|
|
||||||
static const char *xquote(const char *str)
|
static const char *xquote(const char *str)
|
||||||
@@ -425,12 +423,18 @@ acl_get_file_mode(const char *path_p)
|
@@ -425,12 +423,23 @@ acl_get_file_mode(const char *path_p)
|
||||||
return acl_from_mode(st.st_mode);
|
return acl_from_mode(st.st_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,11 +96,16 @@ Index: acl-2.2.45/getfacl/getfacl.c
|
|||||||
+ strerror(errno));
|
+ strerror(errno));
|
||||||
+ return 1;
|
+ return 1;
|
||||||
+ }
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((walk_flags & WALK_TREE_SYMLINK) &&
|
||||||
|
+ ((walk_flags & WALK_TREE_PHYSICAL) ||
|
||||||
|
+ !(walk_flags & (WALK_TREE_TOPLEVEL | WALK_TREE_LOGICAL))))
|
||||||
|
+ return 0;
|
||||||
+
|
+
|
||||||
if (opt_print_acl) {
|
if (opt_print_acl) {
|
||||||
acl = acl_get_file(path_p, ACL_TYPE_ACCESS);
|
acl = acl_get_file(path_p, ACL_TYPE_ACCESS);
|
||||||
if (acl == NULL && (errno == ENOSYS || errno == ENOTSUP))
|
if (acl == NULL && (errno == ENOSYS || errno == ENOTSUP))
|
||||||
@@ -549,7 +553,7 @@ void help(void)
|
@@ -549,7 +558,7 @@ void help(void)
|
||||||
" --skip-base skip files that only have the base entries\n"
|
" --skip-base skip files that only have the base entries\n"
|
||||||
" -R, --recursive recurse into subdirectories\n"
|
" -R, --recursive recurse into subdirectories\n"
|
||||||
" -L, --logical logical walk, follow symbolic links\n"
|
" -L, --logical logical walk, follow symbolic links\n"
|
||||||
@ -109,7 +114,7 @@ Index: acl-2.2.45/getfacl/getfacl.c
|
|||||||
" --tabular use tabular output format\n"
|
" --tabular use tabular output format\n"
|
||||||
" --numeric print numeric user/group identifiers\n"
|
" --numeric print numeric user/group identifiers\n"
|
||||||
" --absolute-names don't strip leading '/' in pathnames\n"));
|
" --absolute-names don't strip leading '/' in pathnames\n"));
|
||||||
@@ -560,75 +564,6 @@ void help(void)
|
@@ -560,75 +569,6 @@ void help(void)
|
||||||
" --help this help text\n"));
|
" --help this help text\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +190,7 @@ Index: acl-2.2.45/getfacl/getfacl.c
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int opt;
|
int opt;
|
||||||
@@ -691,21 +626,21 @@ int main(int argc, char *argv[])
|
@@ -691,21 +631,21 @@ int main(int argc, char *argv[])
|
||||||
case 'R': /* recursive */
|
case 'R': /* recursive */
|
||||||
if (posixly_correct)
|
if (posixly_correct)
|
||||||
goto synopsis;
|
goto synopsis;
|
||||||
@ -212,21 +217,23 @@ Index: acl-2.2.45/getfacl/getfacl.c
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 's': /* skip files with only base entries */
|
case 's': /* skip files with only base entries */
|
||||||
@@ -762,7 +697,7 @@ int main(int argc, char *argv[])
|
@@ -762,7 +702,8 @@ int main(int argc, char *argv[])
|
||||||
if (*line == '\0')
|
if (*line == '\0')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
- had_errors += walk_tree(line);
|
- had_errors += walk_tree(line);
|
||||||
+ had_errors += walk_tree(line, walk_flags, do_print, NULL);
|
+ had_errors += walk_tree(line, walk_flags, 0,
|
||||||
|
+ do_print, NULL);
|
||||||
}
|
}
|
||||||
if (!feof(stdin)) {
|
if (!feof(stdin)) {
|
||||||
fprintf(stderr, _("%s: Standard input: %s\n"),
|
fprintf(stderr, _("%s: Standard input: %s\n"),
|
||||||
@@ -770,7 +705,7 @@ int main(int argc, char *argv[])
|
@@ -770,7 +711,8 @@ int main(int argc, char *argv[])
|
||||||
had_errors++;
|
had_errors++;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
- had_errors += walk_tree(argv[optind]);
|
- had_errors += walk_tree(argv[optind]);
|
||||||
+ had_errors += walk_tree(argv[optind], walk_flags, do_print, NULL);
|
+ had_errors += walk_tree(argv[optind], walk_flags, 0,
|
||||||
|
+ do_print, NULL);
|
||||||
optind++;
|
optind++;
|
||||||
} while (optind < argc);
|
} while (optind < argc);
|
||||||
|
|
||||||
@ -286,7 +293,7 @@ Index: acl-2.2.45/setfacl/do_set.c
|
|||||||
acl_t old_acl = NULL, old_default_acl = NULL;
|
acl_t old_acl = NULL, old_default_acl = NULL;
|
||||||
acl_t acl = NULL, default_acl = NULL;
|
acl_t acl = NULL, default_acl = NULL;
|
||||||
acl_t *xacl, *old_xacl;
|
acl_t *xacl, *old_xacl;
|
||||||
@@ -272,6 +274,11 @@ do_set(
|
@@ -272,6 +274,16 @@ do_set(
|
||||||
int acl_modified = 0, default_acl_modified = 0;
|
int acl_modified = 0, default_acl_modified = 0;
|
||||||
int acl_mask_provided = 0, default_acl_mask_provided = 0;
|
int acl_mask_provided = 0, default_acl_mask_provided = 0;
|
||||||
|
|
||||||
@ -294,11 +301,16 @@ Index: acl-2.2.45/setfacl/do_set.c
|
|||||||
+ fprintf(stderr, "%s: %s: %s\n", progname, path_p, strerror(errno));
|
+ fprintf(stderr, "%s: %s: %s\n", progname, path_p, strerror(errno));
|
||||||
+ return 1;
|
+ return 1;
|
||||||
+ }
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((walk_flags & WALK_TREE_SYMLINK) &&
|
||||||
|
+ ((walk_flags & WALK_TREE_PHYSICAL) ||
|
||||||
|
+ !(walk_flags & (WALK_TREE_TOPLEVEL | WALK_TREE_LOGICAL))))
|
||||||
|
+ return 0;
|
||||||
+
|
+
|
||||||
/* Execute the commands in seq (read ACLs on demand) */
|
/* Execute the commands in seq (read ACLs on demand) */
|
||||||
error = seq_get_cmd(seq, SEQ_FIRST_CMD, &cmd);
|
error = seq_get_cmd(seq, SEQ_FIRST_CMD, &cmd);
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
@@ -426,7 +433,7 @@ do_set(
|
@@ -426,7 +438,7 @@ do_set(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only directores can have default ACLs */
|
/* Only directores can have default ACLs */
|
||||||
@ -437,7 +449,7 @@ Index: acl-2.2.45/setfacl/setfacl.c
|
|||||||
if (strcmp(arg, "-") == 0) {
|
if (strcmp(arg, "-") == 0) {
|
||||||
while ((line = next_line(stdin)))
|
while ((line = next_line(stdin)))
|
||||||
- errors = walk_tree(line, seq);
|
- errors = walk_tree(line, seq);
|
||||||
+ errors = walk_tree(line, walk_flags, do_set, seq);
|
+ errors = walk_tree(line, walk_flags, 0, do_set, seq);
|
||||||
if (!feof(stdin)) {
|
if (!feof(stdin)) {
|
||||||
fprintf(stderr, _("%s: Standard input: %s\n"),
|
fprintf(stderr, _("%s: Standard input: %s\n"),
|
||||||
progname, strerror(errno));
|
progname, strerror(errno));
|
||||||
@ -445,7 +457,7 @@ Index: acl-2.2.45/setfacl/setfacl.c
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
- errors = walk_tree(arg, seq);
|
- errors = walk_tree(arg, seq);
|
||||||
+ errors = walk_tree(arg, walk_flags, do_set, seq);
|
+ errors = walk_tree(arg, walk_flags, 0, do_set, seq);
|
||||||
}
|
}
|
||||||
return errors ? 1 : 0;
|
return errors ? 1 : 0;
|
||||||
}
|
}
|
||||||
@ -476,7 +488,7 @@ Index: acl-2.2.45/include/walk_tree.h
|
|||||||
===================================================================
|
===================================================================
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ acl-2.2.45/include/walk_tree.h
|
+++ acl-2.2.45/include/walk_tree.h
|
||||||
@@ -0,0 +1,18 @@
|
@@ -0,0 +1,19 @@
|
||||||
+#ifndef __WALK_TREE_H
|
+#ifndef __WALK_TREE_H
|
||||||
+#define __WALK_TREE_H
|
+#define __WALK_TREE_H
|
||||||
+
|
+
|
||||||
@ -485,21 +497,22 @@ Index: acl-2.2.45/include/walk_tree.h
|
|||||||
+#define WALK_TREE_LOGICAL 0x4
|
+#define WALK_TREE_LOGICAL 0x4
|
||||||
+#define WALK_TREE_DEREFERENCE 0x8
|
+#define WALK_TREE_DEREFERENCE 0x8
|
||||||
+
|
+
|
||||||
+#define WALK_TREE_SYMLINK 0x10
|
+#define WALK_TREE_TOPLEVEL 0x100
|
||||||
+#define WALK_TREE_FAILED 0x20
|
+#define WALK_TREE_SYMLINK 0x200
|
||||||
|
+#define WALK_TREE_FAILED 0x400
|
||||||
+
|
+
|
||||||
+struct stat;
|
+struct stat;
|
||||||
+
|
+
|
||||||
+extern int walk_tree(const char *path, int walk_flags,
|
+extern int walk_tree(const char *path, int walk_flags, unsigned int num,
|
||||||
+ int (*func)(const char *, const struct stat *, int, void *),
|
+ int (*func)(const char *, const struct stat *, int,
|
||||||
+ void *arg);
|
+ void *), void *arg);
|
||||||
+
|
+
|
||||||
+#endif
|
+#endif
|
||||||
Index: acl-2.2.45/libmisc/walk_tree.c
|
Index: acl-2.2.45/libmisc/walk_tree.c
|
||||||
===================================================================
|
===================================================================
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ acl-2.2.45/libmisc/walk_tree.c
|
+++ acl-2.2.45/libmisc/walk_tree.c
|
||||||
@@ -0,0 +1,100 @@
|
@@ -0,0 +1,188 @@
|
||||||
+/*
|
+/*
|
||||||
+ File: walk_tree.c
|
+ File: walk_tree.c
|
||||||
+
|
+
|
||||||
@ -523,6 +536,8 @@ Index: acl-2.2.45/libmisc/walk_tree.c
|
|||||||
+#include <sys/types.h>
|
+#include <sys/types.h>
|
||||||
+#include <sys/stat.h>
|
+#include <sys/stat.h>
|
||||||
+#include <unistd.h>
|
+#include <unistd.h>
|
||||||
|
+#include <sys/time.h>
|
||||||
|
+#include <sys/resource.h>
|
||||||
+#include <dirent.h>
|
+#include <dirent.h>
|
||||||
+#include <stdio.h>
|
+#include <stdio.h>
|
||||||
+#include <string.h>
|
+#include <string.h>
|
||||||
@ -530,73 +545,159 @@ Index: acl-2.2.45/libmisc/walk_tree.c
|
|||||||
+
|
+
|
||||||
+#include "walk_tree.h"
|
+#include "walk_tree.h"
|
||||||
+
|
+
|
||||||
|
+struct entry_handle {
|
||||||
|
+ struct entry_handle *prev, *next;
|
||||||
|
+ struct stat st;
|
||||||
|
+ DIR *stream;
|
||||||
|
+ off_t pos;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct entry_handle head = {
|
||||||
|
+ .next = &head,
|
||||||
|
+ .prev = &head,
|
||||||
|
+ /* The other fields are unused. */
|
||||||
|
+};
|
||||||
|
+struct entry_handle *closed = &head;
|
||||||
|
+unsigned int num_dir_handles;
|
||||||
|
+
|
||||||
+static int walk_tree_rec(const char *path, int walk_flags,
|
+static int walk_tree_rec(const char *path, int walk_flags,
|
||||||
+ int (*func)(const char *, const struct stat *, int, void *),
|
+ int (*func)(const char *, const struct stat *, int,
|
||||||
+ void *arg, int depth)
|
+ void *), void *arg, int depth)
|
||||||
+{
|
+{
|
||||||
+ int (*xstat)(const char *, struct stat *) = lstat;
|
+ int (*xstat)(const char *, struct stat *) = lstat;
|
||||||
+ struct stat st;
|
+ int flags = walk_flags, err;
|
||||||
+ int local_walk_flags = walk_flags, err;
|
+ struct entry_handle dir;
|
||||||
+
|
+
|
||||||
+ /* Default to traversing symlinks on the command line, traverse all symlinks
|
+ /*
|
||||||
+ * with -L, and do not traverse symlinks with -P. (This is similar to chown.)
|
+ * If (walk_flags & WALK_TREE_PHYSICAL), do not traverse symlinks.
|
||||||
|
+ * If (walk_flags & WALK_TREE_LOGICAL), traverse all symlinks.
|
||||||
|
+ * Otherwise, traverse only top-level symlinks.
|
||||||
+ */
|
+ */
|
||||||
|
+ if (depth == 0)
|
||||||
|
+ flags |= WALK_TREE_TOPLEVEL;
|
||||||
+
|
+
|
||||||
+follow_symlink:
|
+follow_symlink:
|
||||||
+ if (xstat(path, &st) != 0)
|
+ if (xstat(path, &dir.st) != 0)
|
||||||
+ return func(path, NULL, local_walk_flags | WALK_TREE_FAILED, arg);
|
+ return func(path, NULL, flags | WALK_TREE_FAILED, arg);
|
||||||
+ if (S_ISLNK(st.st_mode)) {
|
+ if (S_ISLNK(dir.st.st_mode)) {
|
||||||
+ if ((local_walk_flags & WALK_TREE_PHYSICAL) ||
|
+ flags |= WALK_TREE_SYMLINK;
|
||||||
+ (!(local_walk_flags & WALK_TREE_LOGICAL) && depth > 1))
|
+ if (flags & WALK_TREE_DEREFERENCE) {
|
||||||
+ return 0;
|
+ xstat = stat;
|
||||||
+ local_walk_flags |= WALK_TREE_SYMLINK;
|
|
||||||
+ xstat = stat;
|
|
||||||
+ if (local_walk_flags & WALK_TREE_DEREFERENCE)
|
|
||||||
+ goto follow_symlink;
|
+ goto follow_symlink;
|
||||||
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+ err = func(path, &st, local_walk_flags, arg);
|
+ err = func(path, &dir.st, flags, arg);
|
||||||
+ if ((local_walk_flags & WALK_TREE_RECURSIVE) &&
|
+ if ((flags & WALK_TREE_RECURSIVE) &&
|
||||||
+ (S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode))) {
|
+ (S_ISDIR(dir.st.st_mode) || (S_ISLNK(dir.st.st_mode))) &&
|
||||||
+ char path2[FILENAME_MAX];
|
+ (!(flags & WALK_TREE_PHYSICAL) || !(flags & WALK_TREE_SYMLINK)) &&
|
||||||
+ DIR *dir;
|
+ (flags & (WALK_TREE_LOGICAL | WALK_TREE_TOPLEVEL))) {
|
||||||
|
+ struct entry_handle *i;
|
||||||
+ struct dirent *entry;
|
+ struct dirent *entry;
|
||||||
+ int err2;
|
|
||||||
+
|
+
|
||||||
+ dir = opendir(path);
|
+ /* Check if we have already visited this directory. */
|
||||||
+ if (!dir) {
|
+ for (i = head.next; i != &head; i = i->next)
|
||||||
+ /* PATH may be a symlink to a regular file or a dead symlink
|
+ if (i->st.st_dev == dir.st.st_dev &&
|
||||||
+ * which we didn't follow above.
|
+ i->st.st_ino == dir.st.st_ino)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ if (num_dir_handles == 0 && closed->prev != &head) {
|
||||||
|
+close_another_dir:
|
||||||
|
+ /* Close the topmost directory handle still open. */
|
||||||
|
+ closed = closed->prev;
|
||||||
|
+ closed->pos = telldir(closed->stream);
|
||||||
|
+ closedir(closed->stream);
|
||||||
|
+ closed->stream = NULL;
|
||||||
|
+ num_dir_handles++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dir.stream = opendir(path);
|
||||||
|
+ if (!dir.stream) {
|
||||||
|
+ if (errno == ENFILE && closed->prev != &head) {
|
||||||
|
+ /* Ran out of file descriptors. */
|
||||||
|
+ num_dir_handles = 0;
|
||||||
|
+ goto close_another_dir;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * PATH may be a symlink to a regular file, or a dead
|
||||||
|
+ * symlink which we didn't follow above.
|
||||||
+ */
|
+ */
|
||||||
+ if (errno != ENOTDIR && errno != ENOENT)
|
+ if (errno != ENOTDIR && errno != ENOENT)
|
||||||
+ err += func(path, &st,
|
+ err += func(path, &dir.st,
|
||||||
+ local_walk_flags | WALK_TREE_FAILED, arg);
|
+ flags | WALK_TREE_FAILED, arg);
|
||||||
+ return err;
|
+ return err;
|
||||||
+ }
|
+ }
|
||||||
+ while ((entry = readdir(dir)) != NULL) {
|
+
|
||||||
+ if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
|
+ /* Insert into the list of handles. */
|
||||||
|
+ dir.next = head.next;
|
||||||
|
+ dir.prev = &head;
|
||||||
|
+ dir.prev->next = &dir;
|
||||||
|
+ dir.next->prev = &dir;
|
||||||
|
+ num_dir_handles--;
|
||||||
|
+
|
||||||
|
+ while ((entry = readdir(dir.stream)) != NULL) {
|
||||||
|
+ char *path_end;
|
||||||
|
+
|
||||||
|
+ if (!strcmp(entry->d_name, ".") ||
|
||||||
|
+ !strcmp(entry->d_name, ".."))
|
||||||
+ continue;
|
+ continue;
|
||||||
+ err2 = snprintf(path2, sizeof(path2), "%s/%s", path,
|
+ path_end = strchr(path, 0);
|
||||||
+ entry->d_name);
|
+ if ((path_end - path) + strlen(entry->d_name) + 1 >=
|
||||||
+ if (err2 < 0 || err2 > FILENAME_MAX) {
|
+ FILENAME_MAX) {
|
||||||
+ errno = ENAMETOOLONG;
|
+ errno = ENAMETOOLONG;
|
||||||
+ err += func(path, NULL,
|
+ err += func(path, NULL,
|
||||||
+ local_walk_flags | WALK_TREE_FAILED, arg);
|
+ flags | WALK_TREE_FAILED, arg);
|
||||||
+ continue;
|
+ continue;
|
||||||
+ }
|
+ }
|
||||||
+ err += walk_tree_rec(path2, walk_flags, func, arg, depth + 1);
|
+ *path_end++ = '/';
|
||||||
|
+ strcpy(path_end, entry->d_name);
|
||||||
|
+ err += walk_tree_rec(path, walk_flags, func, arg,
|
||||||
|
+ depth + 1);
|
||||||
|
+ *--path_end = 0;
|
||||||
|
+ if (!dir.stream) {
|
||||||
|
+ /* Reopen the directory handle. */
|
||||||
|
+ dir.stream = opendir(path);
|
||||||
|
+ if (!dir.stream)
|
||||||
|
+ return err + func(path, &dir.st, flags |
|
||||||
|
+ WALK_TREE_FAILED, arg);
|
||||||
|
+ seekdir(dir.stream, dir.pos);
|
||||||
|
+
|
||||||
|
+ closed = closed->next;
|
||||||
|
+ num_dir_handles--;
|
||||||
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+ if (closedir(dir) != 0)
|
+
|
||||||
+ err += func(path, &st, local_walk_flags | WALK_TREE_FAILED, arg);
|
+ if (closedir(dir.stream) != 0)
|
||||||
|
+ err += func(path, &dir.st, flags | WALK_TREE_FAILED,
|
||||||
|
+ arg);
|
||||||
|
+
|
||||||
|
+ /* Remove from the list of handles. */
|
||||||
|
+ dir.prev->next = dir.next;
|
||||||
|
+ dir.next->prev = dir.prev;
|
||||||
|
+ num_dir_handles++;
|
||||||
+ }
|
+ }
|
||||||
+ return err;
|
+ return err;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+int walk_tree(const char *path, int walk_flags,
|
+int walk_tree(const char *path, int walk_flags, unsigned int num,
|
||||||
+ int (*func)(const char *, const struct stat *, int, void *), void *arg)
|
+ int (*func)(const char *, const struct stat *, int, void *),
|
||||||
|
+ void *arg)
|
||||||
+{
|
+{
|
||||||
|
+ char path_copy[FILENAME_MAX];
|
||||||
|
+
|
||||||
|
+ num_dir_handles = num;
|
||||||
|
+ if (num_dir_handles < 1) {
|
||||||
|
+ struct rlimit rlimit;
|
||||||
|
+
|
||||||
|
+ num_dir_handles = 1;
|
||||||
|
+ if (getrlimit(RLIMIT_NOFILE, &rlimit) == 0 &&
|
||||||
|
+ rlimit.rlim_cur >= 2)
|
||||||
|
+ num_dir_handles = rlimit.rlim_cur / 2;
|
||||||
|
+ }
|
||||||
+ if (strlen(path) >= FILENAME_MAX) {
|
+ if (strlen(path) >= FILENAME_MAX) {
|
||||||
+ errno = ENAMETOOLONG;
|
+ errno = ENAMETOOLONG;
|
||||||
+ return func(path, NULL, WALK_TREE_FAILED, arg);
|
+ return func(path, NULL, WALK_TREE_FAILED, arg);
|
||||||
+ }
|
+ }
|
||||||
+ return walk_tree_rec(path, walk_flags, func, arg, 1);
|
+ strcpy(path_copy, path);
|
||||||
|
+ return walk_tree_rec(path_copy, walk_flags, func, arg, 0);
|
||||||
+}
|
+}
|
||||||
|
Loading…
Reference in New Issue
Block a user