use mmap to read files
This commit is contained in:
parent
fdad895a96
commit
f07c2ef73a
48
searchword.c
48
searchword.c
@ -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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user