Skip to content
Snippets Groups Projects

fsearch: keep track of stdout offset if needed

Closed Florian Fischer requested to merge aj46ezos/emper:fsearch-track-outfile-offset into master
+ 29
7
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright © 2021-2022 Florian Fischer, Florian Schmaus
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <array>
#include <atomic>
#include <boost/program_options.hpp>
#include <climits>
#include <cstdlib>
@@ -26,13 +28,30 @@ namespace po = boost::program_options;
#define EMPER_RIPGREP_BUFSIZE 4096
const char* needle;
size_t needle_len;
static const char* needle;
static size_t needle_len;
emper::Semaphore* max_running;
static emper::Semaphore* max_running;
static bool stdoutNeedsOffset = false;
static std::atomic<off_t> stdoutOffset = 0;
static enum emper::StealingMode stealingMode;
static void writeFoundPath(const std::string& path) {
std::array<char, PATH_MAX + 1> outBuf;
memcpy(outBuf.data(), path.c_str(), path.length());
outBuf[path.length()] = '\n';
const size_t outLen = path.length() + 1;
off_t offset = -1;
if (stdoutNeedsOffset)
offset = stdoutOffset.fetch_add(static_cast<off_t>(outLen), std::memory_order_relaxed);
emper::io::writeFileAndWait(STDOUT_FILENO, outBuf.data(), outLen, offset);
}
void search(const std::string& path) {
if (max_running) {
max_running->acquire();
@@ -48,10 +67,7 @@ void search(const std::string& path) {
ssize_t bytes_read = emper::io::readFileAndWait(fd, buf.data(), buf.size(), 0);
while (bytes_read > 0) {
if (memmem(&buf[0], bytes_read, needle, needle_len)) {
std::array<char, PATH_MAX + 1> outBuf;
memcpy(outBuf.data(), path.c_str(), path.length());
outBuf[path.length()] = '\n';
emper::io::writeFileAndWait(STDOUT_FILENO, outBuf.data(), path.length() + 1, -1);
writeFoundPath(path);
goto out;
}
@@ -105,6 +121,12 @@ static auto fssearch(const po::variables_map& vm) -> int {
Runtime runtime;
struct stat statBuf;
int res = fstat(STDOUT_FILENO, &statBuf);
if (res) DIE_MSG_ERRNO("fstat(STDOUT_FILENO) failed");
stdoutNeedsOffset = S_ISREG(statBuf.st_mode);
std::cerr << "Starting fsearch with stealingMode=" << stealingMode;
if (max_running) std::cerr << " and " << max_running->getCount() << " file fibers";
std::cerr << std::endl;
Loading