use mmap to read files

This commit is contained in:
gandc 2025-04-25 10:12:55 +03:00
parent fdad895a96
commit f07c2ef73a
Signed by: gandc
GPG Key ID: 9F77B03D43C42CB4

View File

@ -4,18 +4,21 @@
#include <ctype.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#define LINE_BUF_SIZE 8192
static const char *search_word;
static int ignore_case = 0;
// Проверка вхождения подстроки с учётом регистра
// Поиск подстроки с учётом регистра
char *find_substr(const char *haystack, const char *needle) {
if (!ignore_case)
return strstr(haystack, needle);
// Игнорирование регистра
size_t nl = strlen(needle);
for (const char *p = haystack; *p; ++p) {
size_t i;
@ -30,17 +33,38 @@ char *find_substr(const char *haystack, const char *needle) {
}
void search_file(const char *filepath) {
FILE *f = fopen(filepath, "r");
if (!f) return; // не удалось открыть — пропустить
char line[LINE_BUF_SIZE];
unsigned long lineno = 0;
while (fgets(line, sizeof(line), f)) {
lineno++;
if (find_substr(line, search_word)) {
printf("%s:%lu: %s", filepath, lineno, line);
int fd = open(filepath, O_RDONLY);
if (fd < 0) return;
struct stat st;
if (fstat(fd, &st) < 0 || st.st_size == 0) {
close(fd);
return;
}
char *data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (data == MAP_FAILED) {
close(fd);
return;
}
unsigned long lineno = 1;
size_t line_start = 0;
for (size_t i = 0; i <= (size_t)st.st_size; ++i) {
if (i == (size_t)st.st_size || data[i] == '\n') {
size_t line_len = i - line_start;
char *line = malloc(line_len + 1);
memcpy(line, data + line_start, line_len);
line[line_len] = '\0';
if (find_substr(line, search_word)) {
printf("%s:%lu: %s\n", filepath, lineno, line);
}
free(line);
line_start = i + 1;
lineno++;
}
}
fclose(f);
munmap(data, st.st_size);
close(fd);
}
void process_dir(const char *path) {
@ -79,7 +103,7 @@ int main(int argc, char *argv[]) {
return EXIT_FAILURE;
}
static char default_dir[PATH_MAX];
snprintf(default_dir, sizeof(default_dir), "%s/", home);
snprintf(default_dir, sizeof(default_dir), "%s/files", home);
dir = default_dir;
}
if (argi < argc)