Last active
February 27, 2024 07:20
-
-
Save Inndy/7fc4323bc4326763ba90354dd6699467 to your computer and use it in GitHub Desktop.
Use mmap to read file and output strings to stdout
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
gcc mystrings.c -O3 -o mystrings | |
gcc -DSTRING_LENGTH 99 -DBUFFER_SIZE 0x10000 mystrings.c -O3 -o mystrings | |
*/ | |
#include <string.h> | |
#include <fcntl.h> | |
#include <sys/stat.h> | |
#include <unistd.h> | |
#include <sys/mman.h> | |
#ifndef STRING_LENGTH | |
#define STRING_LENGTH 8 | |
#endif | |
#ifndef BUFFER_SIZE | |
#define BUFFER_SIZE 4096 | |
#endif | |
char buffer[BUFFER_SIZE]; | |
size_t buff_used = 0; | |
void flush_buffer() | |
{ | |
if(buff_used != 0) { | |
write(1, buffer, buff_used); | |
} | |
buff_used = 0; | |
} | |
void report_string(const char *str, size_t len) | |
{ | |
if(len >= sizeof(buffer)) { | |
flush_buffer(); | |
write(1, str, len); | |
buffer[0] = '\n'; | |
buff_used = 1; | |
return; | |
} | |
if(len + buff_used + 1 > sizeof(buffer)) { | |
flush_buffer(); | |
} | |
memcpy(buffer + buff_used, str, len); | |
buffer[buff_used + len] = '\n'; | |
buff_used += len + 1; | |
} | |
void error(const char *s) | |
{ | |
write(2, s, strlen(s)); | |
write(2, "\n", 1); | |
_exit(1); | |
} | |
int main(int argc, char const *argv[]) | |
{ | |
if(argc < 2) { | |
error("usage: ./mystrings file-to-read.bin"); | |
} | |
int fd = open(argv[1], O_RDONLY); | |
if(fd < 0) | |
{ | |
error("error: can not open file"); | |
} | |
struct stat s; | |
int status = fstat(fd, &s); | |
size_t size = s.st_size; | |
const char *mapped = (const char *)mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0); | |
if(mapped == NULL) { | |
error("error: can not mmap file"); | |
} | |
size_t begin = 0, length = 0; | |
for (size_t i = 0; i < size; i++) { | |
if((0x20 <= mapped[i] && mapped[i] <= 0x7e) || mapped[i] == '\r' || mapped[i] == '\n' || mapped[i] == '\t') { | |
if(begin == 0) { | |
begin = i; | |
length = 1; | |
} else { | |
++length; | |
} | |
} else { | |
if(begin != 0) { | |
if(length >= STRING_LENGTH) { | |
report_string(mapped + begin, length); | |
} | |
begin = 0; | |
} | |
} | |
} | |
if(length >= STRING_LENGTH) { | |
report_string(mapped + begin, length); | |
} | |
flush_buffer(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment