commit 3658a844965efb9e09b173a9e39a2dbabda74a74
parent c0264acab8d04ef4b1721a8522fe99101d959254
Author: Frederic Cambus <fred@statdns.com>
Date: Fri, 29 Jun 2018 20:45:30 +0200
Use mmap(2) to map the input file into memory
Diffstat:
2 files changed, 16 insertions(+), 24 deletions(-)
diff --git a/TODO b/TODO
@@ -2,7 +2,6 @@
- Display mode information in summary
- Use include-what-you-use to remove unnecessary headers
- Use OpenBSD style(9) for function prototypes and declarations?
-- Avoid reading the whole file in memory before parsing?
- Allow reading from stdin?
- Fix Travis CI build, need to install libansilove before building
- Update documention to mention libansilove and drop GD from requirements
diff --git a/src/main.c b/src/main.c
@@ -12,11 +12,13 @@
#define _GNU_SOURCE
#include <ansilove.h>
#include <err.h>
+#include <fcntl.h>
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -127,6 +129,9 @@ int main(int argc, char *argv[]) {
char *input = NULL, *output = NULL;
+ int fd;
+ struct stat st;
+
struct input inputFile;
struct output outputFile;
@@ -272,48 +277,32 @@ int main(int argc, char *argv[]) {
inputFile.fext = fext;
// load input file
- FILE *input_file = fopen(input, "r");
- if (input_file == NULL) {
+ if ((fd = open(input, O_RDONLY)) == -1) {
perror("File error");
return 1;
}
// get the file size (bytes)
- struct stat input_file_stat;
-
- if (fstat(fileno(input_file), &input_file_stat)) {
+ if (fstat(fd, &st) == -1) {
perror("Can't stat file");
return 1;
}
- inputFile.size = input_file_stat.st_size;
-
- // next up is loading our file into a dynamically allocated memory buffer
+ inputFile.size = st.st_size;
- // allocate memory to contain the whole file
- inputFile.data = (unsigned char *)malloc(sizeof (unsigned char)*inputFile.size + 1);
- if (inputFile.data == NULL) {
+ // mmap input file into memory
+ inputFile.data = mmap(NULL, inputFile.size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (inputFile.data== MAP_FAILED) {
perror("Memory error");
return 2;
}
- // copy the file into the buffer
- if (fread(inputFile.data, 1, inputFile.size, input_file) != inputFile.size) {
- perror("Reading error haha");
- return 3;
- } // whole file is now loaded into inputFileBuffer
-
- inputFile.data[inputFile.size] = '\0';
-
// adjust the file size if file contains a SAUCE record
if (fileHasSAUCE) {
- sauce *saucerec = sauceReadFile(input_file);
+ sauce *saucerec = sauceReadFileName(input);
inputFile.size -= 129 - (saucerec->comments > 0 ? 5 + 64 * saucerec->comments : 0);
}
- // close input file, we don't need it anymore
- fclose(input_file);
-
// create the output file by invoking the appropiate function
if (!strcmp(fext, ".pcb")) {
// params: input, output, font, bits, icecolors
@@ -353,6 +342,10 @@ int main(int argc, char *argv[]) {
if (fileIsBinary) {
fprintf(stderr, "Columns: %d\n", inputFile.columns);
}
+
+ // close input file, we don't need it anymore
+ // TODO: munmap, with original inputFileSize
+ close(fd);
}
// either display SAUCE or tell us if there is no record