Browse Source

find: Implement support for multiple directories

Tim Schumacher 3 years ago
parent
commit
0ca63cfd6e
2 changed files with 23 additions and 18 deletions
  1. 3 3
      Base/usr/share/man/man1/find.md
  2. 20 15
      Userland/Utilities/find.cpp

+ 3 - 3
Base/usr/share/man/man1/find.md

@@ -5,13 +5,13 @@ find - recursively search for files
 ## Synopsis
 ## Synopsis
 
 
 ```**sh
 ```**sh
-$ find [-L] [root-path] [commands...]
+$ find [-L] [root-paths...] [commands...]
 ```
 ```
 
 
 ## Description
 ## Description
 
 
-`find` recursively traverses the file hierarchy starting at the given root path
-(or at the current working directory if the root path is not specified), and
+`find` recursively traverses the file hierarchy starting at the given root paths
+(or at the current working directory if no root paths have been specified), and
 evaluates the given commands for each found file. The commands can be used to
 evaluates the given commands for each found file. The commands can be used to
 both filter the set of files and to perform actions on them.
 both filter the set of files and to perform actions on them.
 
 

+ 20 - 15
Userland/Utilities/find.cpp

@@ -541,7 +541,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
     args.append(arguments.argv + 1, arguments.argc - 1);
     args.append(arguments.argv + 1, arguments.argc - 1);
 
 
     OwnPtr<Command> command;
     OwnPtr<Command> command;
-    LexicalPath root_path = LexicalPath(".");
+    Vector<LexicalPath> paths;
 
 
     while (!args.is_empty()) {
     while (!args.is_empty()) {
         char* raw_arg = args.take_first();
         char* raw_arg = args.take_first();
@@ -549,7 +549,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
         if (arg == "-L") {
         if (arg == "-L") {
             g_follow_symlinks = true;
             g_follow_symlinks = true;
         } else if (!arg.starts_with('-')) {
         } else if (!arg.starts_with('-')) {
-            root_path = LexicalPath(arg);
+            paths.append(LexicalPath(arg));
         } else {
         } else {
             // No special case, so add back the argument and try to parse a command.
             // No special case, so add back the argument and try to parse a command.
             args.prepend(raw_arg);
             args.prepend(raw_arg);
@@ -560,21 +560,26 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
     if (!command)
     if (!command)
         command = make<PrintCommand>();
         command = make<PrintCommand>();
 
 
-    String dirname = root_path.dirname();
-    String basename = root_path.basename();
+    if (paths.is_empty())
+        paths.append(LexicalPath("."));
 
 
-    int dirfd = TRY(Core::System::open(dirname, O_RDONLY | O_DIRECTORY | O_CLOEXEC));
+    for (auto& path : paths) {
+        String dirname = path.dirname();
+        String basename = path.basename();
 
 
-    FileData file_data {
-        root_path,
-        dirfd,
-        basename.characters(),
-        (struct stat) {},
-        false,
-        DT_UNKNOWN,
-    };
-    walk_tree(file_data, *command);
-    close(dirfd);
+        int dirfd = TRY(Core::System::open(dirname, O_RDONLY | O_DIRECTORY | O_CLOEXEC));
+
+        FileData file_data {
+            path,
+            dirfd,
+            basename.characters(),
+            (struct stat) {},
+            false,
+            DT_UNKNOWN,
+        };
+        walk_tree(file_data, *command);
+        close(dirfd);
+    }
 
 
     return g_there_was_an_error ? 1 : 0;
     return g_there_was_an_error ? 1 : 0;
 }
 }