diff --git a/apps/fsearch/fsearch.cpp b/apps/fsearch/fsearch.cpp new file mode 100644 index 0000000000000000000000000000000000000000..238d26ec1b0b5668aa6891239399203e078a0e4a --- /dev/null +++ b/apps/fsearch/fsearch.cpp @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright © 2021 Florian Fischer +#include <fcntl.h> +#include <sys/types.h> + +#include <array> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <filesystem> +#include <iostream> +#include <string> + +#include "Common.hpp" +#include "CountingPrivateSemaphore.hpp" +#include "Fiber.hpp" +#include "Runtime.hpp" +#include "emper.hpp" +#include "io.hpp" + +namespace fs = std::filesystem; + +#define EMPER_RIPGREP_BUFSIZE 4096 + +const char* needle; +size_t needle_len; + +void search(const std::string& path) { + int fd = emper::io::openAndWait(path.c_str(), O_RDONLY); + if (fd < 0) { + DIE_MSG_ERRNO("open failed"); + } + + std::array<char, EMPER_RIPGREP_BUFSIZE> buf; + size_t bytes_searched = 0; + + ssize_t bytes_read = emper::io::readFileAndWait(fd, buf.data(), buf.size(), bytes_searched); + while (bytes_read > 0) { + if (memmem(&buf[0], bytes_read, needle, needle_len)) { + printf("%s\n", path.c_str()); + return; + } + + bytes_searched += static_cast<size_t>(bytes_read); + bytes_read = emper::io::readFileAndWait(fd, buf.data(), buf.size(), -1); + } + + if (bytes_read < 0) { + DIE_MSG_ERRNO("read failed"); + } +} + +void walk_dir() { + CPS cps; + for (const auto& p : fs::recursive_directory_iterator(".")) { + if (p.is_regular_file()) { + spawn([=] { search(p.path()); }, cps); + } + } + + cps.wait(); + exit(EXIT_SUCCESS); +} + +auto main(int argc, char* argv[]) -> int { + if (argc < 2) { + std::cerr << "Usage: " << argv[0] << " <needle>" << std::endl; + return EXIT_FAILURE; + } + + needle = argv[1]; + needle_len = strlen(needle); + + Runtime runtime; + + auto* dirWalker = Fiber::from(walk_dir); + runtime.scheduleFromAnywhere(*dirWalker); + + runtime.waitUntilFinished(); +} diff --git a/apps/fsearch/meson.build b/apps/fsearch/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..b5b548e034a13e215ea5dc24bd25bcb384ecc27c --- /dev/null +++ b/apps/fsearch/meson.build @@ -0,0 +1,5 @@ +fsearch_exe = executable( + 'fsearch', + 'fsearch.cpp', + dependencies: emper_dep, +) diff --git a/apps/meson.build b/apps/meson.build index 5075128a54a7118400b8d1d1965615331c7dd69d..015a15df3ff1713f0c0f818ad41c2c33a71f0af0 100644 --- a/apps/meson.build +++ b/apps/meson.build @@ -21,3 +21,5 @@ echoclient_exe = executable( 'EchoClient.cpp', dependencies: emper_dep, ) + +subdir('fsearch') diff --git a/iwyu-mappings.imp b/iwyu-mappings.imp index 834dff5a2aa9852fe93e269215c318a7f8a0e9ee..9f1e941b74a6e151c1b6dbb4feeecc115167c746 100644 --- a/iwyu-mappings.imp +++ b/iwyu-mappings.imp @@ -3,5 +3,7 @@ { include: ["@<gtest/.*>", "private", "<gtest/gtest.h>", "public"] }, { include: ["<urcu/map/urcu-memb.h>", "private", "<urcu.h>", "public"] }, { include: ["<bits/cxxabi_forced.h>", "private", "<ctime>", "public" ] }, + { symbol: ["__kernel_timespec", "private", "<liburing.h>", "public" ] }, + { symbol: ["std::filesystem", "private", "<filesystem>", "public" ] }, ]