summaryrefslogtreecommitdiffstats
path: root/blkseekr.c
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-06-06 12:19:28 +0200
committerMattias Andrée <m@maandree.se>2026-06-06 12:19:28 +0200
commit82110edd4f6c1a4460b4e5b42de9d413acf1bfd2 (patch)
tree1078a7a12265d6fb14f8bce78cdfe46cf5618a0e /blkseekr.c
parentThird commit (diff)
downloadblkseekr-82110edd4f6c1a4460b4e5b42de9d413acf1bfd2.tar.gz
blkseekr-82110edd4f6c1a4460b4e5b42de9d413acf1bfd2.tar.bz2
blkseekr-82110edd4f6c1a4460b4e5b42de9d413acf1bfd2.tar.xz
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'blkseekr.c')
-rw-r--r--blkseekr.c63
1 files changed, 45 insertions, 18 deletions
diff --git a/blkseekr.c b/blkseekr.c
index aa55f0b..94d4369 100644
--- a/blkseekr.c
+++ b/blkseekr.c
@@ -1,7 +1,7 @@
/* See LICENSE file for copyright and license details. */
-#include <libsimple-arg.h>
-#include <libsimple.h>
#include <regex.h>
+#include <libsimple.h>
+#include <libsimple-arg.h>
#include <libautomata.h>
USAGE("[-b block-size] [-B buffer-size] [-h] "
@@ -9,14 +9,6 @@ USAGE("[-b block-size] [-B buffer-size] [-h] "
"file [first-block [last-block]]");
-/*
- * TODO on SIGINT stop and print last completed block
- * TODO show progress
- * TODO make program that extracts (binary) or displays (hex + text) the blocks
- * TODO add support for NUL support in regex (once supported in libautomata)
- */
-
-
enum automata_type {
FIXED,
FIXED_ICASE,
@@ -49,6 +41,8 @@ static char *blkmarks;
static size_t nblkmarks;
static size_t low_mark;
static size_t high_mark;
+static int stdout_is_a_tty;
+static int stderr_is_a_tty;
static void
@@ -146,8 +140,10 @@ analyse_block(char *block, size_t start_end, size_t available)
}
for (i = 0u; i < nblkmarks; i++) {
- printf("Found expression beginning in block %ju\n", (uintmax_t)position / blksize + i);
- fflush(stdout);
+ if (blkmarks[i]) {
+ printf("%ju%s\n", (uintmax_t)position / blksize + i, stdout_is_a_tty ? "\033[K" : "");
+ fflush(stdout);
+ }
}
}
@@ -272,7 +268,7 @@ parse_uint_arg(const char *s, uintmax_t min, uintmax_t max)
d = (uintmax_t)(*s++ - '0');
if (d > 9u || v > (max - d) / 10u) /* we know that max>d */
usage();
- v = v * 10u + v;
+ v = v * 10u + d;
}
if (*s || v < min)
usage();
@@ -402,7 +398,17 @@ main(int argc, char *argv[])
if (argc < 1 || argc > 3 || have_unused_flags || !nautomata)
usage();
+ stderr_is_a_tty = isatty(STDERR_FILENO);
+ if (!stderr_is_a_tty && errno == EBADF)
+ exit(1);
+
+ stdout_is_a_tty = isatty(STDOUT_FILENO);
+ if (!stdout_is_a_tty && errno == EBADF)
+ eprintf("isatty STDOUT_FILENO:");
+
path = argv[0];
+ if (!*path)
+ usage();
if (argc >= 2)
first_block = (off_t)parse_uint_arg(argv[1], 1u, (uintmax_t)OFF_MAX);
@@ -427,11 +433,11 @@ main(int argc, char *argv[])
/* Open file to analyse */
fd = open(path, O_RDONLY);
if (fd < 0)
- eprintf("open %s O_RDONLY", path);
+ eprintf("open %s O_RDONLY:", path);
/* Advise the kernel about the access pattern */
posix_fadvise(fd, 0, first_block, POSIX_FADV_DONTNEED);
- if (last_block >= 0) {
+ if (last_block > 0) {
posix_fadvise(fd, last_block, 0, POSIX_FADV_DONTNEED);
posix_fadvise(fd, first_block, last_block, POSIX_FADV_SEQUENTIAL);
posix_fadvise(fd, first_block, last_block, POSIX_FADV_NOREUSE);
@@ -449,6 +455,11 @@ main(int argc, char *argv[])
/* Skip to first block to analyse */
if (first_block && lseek(fd, first_block, SEEK_SET) == (off_t)-1) {
off_t remaining = first_block;
+ if (stderr_is_a_tty) {
+ /* TODO show progress */
+ fprintf(stderr, "Skipping...\n\033[A");
+ fflush(stderr);
+ }
while (remaining) {
uintmax_t n = MIN((uintmax_t)remaining, (uintmax_t)bufsize);
ssize_t r = read(fd, text, (size_t)n);
@@ -466,6 +477,12 @@ main(int argc, char *argv[])
/* Analyse to last block (to end of file if last_block < 0) */
for (; last_block < 0 || first_block < last_block; first_block = data) {
+ if (stderr_is_a_tty) {
+ /* TODO improve output */
+ fprintf(stderr, "Reading at %ju\033[K\n\033[A", (uintmax_t)position + available);
+ fflush(stderr);
+ }
+
/* Seek to data to find end of hole, and analyse the hole */
if (skip_holes) {
data = lseek(fd, first_block, SEEK_DATA);
@@ -474,7 +491,7 @@ main(int argc, char *argv[])
if (errno != EBADF)
skip_holes = 0;
else
- eprintf("lseek %s %ji SEEK_DATA", path, (intmax_t)first_block);
+ eprintf("lseek %s %ji SEEK_DATA:", path, (intmax_t)first_block);
} else {
available = encountered_hole(text, available, data - first_block);
}
@@ -489,10 +506,10 @@ main(int argc, char *argv[])
if (errno != EBADF)
skip_holes = 0;
else
- eprintf("lseek %s %ji SEEK_HOLE", path, (intmax_t)data);
+ eprintf("lseek %s %ji SEEK_HOLE:", path, (intmax_t)data);
} else {
if (lseek(fd, data, SEEK_SET) == (off_t)-1)
- eprintf("lseek %s %ji SEEK_SET", path, (intmax_t)data);
+ eprintf("lseek %s %ji SEEK_SET:", path, (intmax_t)data);
}
} else {
hole = (off_t)-1;
@@ -513,6 +530,11 @@ main(int argc, char *argv[])
} else {
break;
}
+ if (stderr_is_a_tty) {
+ /* TODO improve output */
+ fprintf(stderr, "Reading at %ju\033[K\n\033[A", (uintmax_t)position + available);
+ fflush(stderr);
+ }
r = read(fd, &text[available], n);
if (r <= 0) {
if (!r)
@@ -535,6 +557,11 @@ eof:
encountered_eof(text, available);
out:
+ if (stderr_is_a_tty) {
+ fprintf(stderr, "\033[K");
+ fflush(stderr);
+ }
+
close(fd);
while (nautomata--) {