use mmap to read files
This commit is contained in:
1 file changed
+36
-12
+36
-12
@@ -4,18 +4,21 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#define LINE_BUF_SIZE 8192
|
#define LINE_BUF_SIZE 8192
|
||||||
|
|
||||||
static const char *search_word;
|
static const char *search_word;
|
||||||
static int ignore_case = 0;
|
static int ignore_case = 0;
|
||||||
|
|
||||||
// Проверка вхождения подстроки с учётом регистра
|
// Поиск подстроки с учётом регистра
|
||||||
char *find_substr(const char *haystack, const char *needle) {
|
char *find_substr(const char *haystack, const char *needle) {
|
||||||
if (!ignore_case)
|
if (!ignore_case)
|
||||||
return strstr(haystack, needle);
|
return strstr(haystack, needle);
|
||||||
// Игнорирование регистра
|
|
||||||
size_t nl = strlen(needle);
|
size_t nl = strlen(needle);
|
||||||
for (const char *p = haystack; *p; ++p) {
|
for (const char *p = haystack; *p; ++p) {
|
||||||
size_t i;
|
size_t i;
|
||||||
@@ -30,17 +33,38 @@ char *find_substr(const char *haystack, const char *needle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void search_file(const char *filepath) {
|
void search_file(const char *filepath) {
|
||||||
FILE *f = fopen(filepath, "r");
|
int fd = open(filepath, O_RDONLY);
|
||||||
if (!f) return; // не удалось открыть — пропустить
|
if (fd < 0) return;
|
||||||
char line[LINE_BUF_SIZE];
|
struct stat st;
|
||||||
unsigned long lineno = 0;
|
if (fstat(fd, &st) < 0 || st.st_size == 0) {
|
||||||
while (fgets(line, sizeof(line), f)) {
|
close(fd);
|
||||||
lineno++;
|
return;
|
||||||
if (find_substr(line, search_word)) {
|
}
|
||||||
printf("%s:%lu: %s", filepath, lineno, line);
|
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) {
|
void process_dir(const char *path) {
|
||||||
@@ -79,7 +103,7 @@ int main(int argc, char *argv[]) {
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
static char default_dir[PATH_MAX];
|
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;
|
dir = default_dir;
|
||||||
}
|
}
|
||||||
if (argi < argc)
|
if (argi < argc)
|
||||||
|
|||||||
Reference in new issue
Block a user