summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main.c58
1 files changed, 54 insertions, 4 deletions
diff --git a/main.c b/main.c
index f9e9f41..b52e32d 100644
--- a/main.c
+++ b/main.c
@@ -56,7 +56,7 @@ typedef struct {
LIST_AUTO(C4GroupEntryData, GroupEntryList)
#define ForeachGroupEntry(list) LIST_FOREACH(GroupEntryList, list, entry)
-__off_t fileSizeFd(int fd)
+off_t fileSizeFd(int fd)
{
struct stat st;
@@ -292,8 +292,52 @@ int main(int argc, char* argv[])
size_t uncompressedSize = last->Offset + last->Size;
currentSize += uncompressedSize;
- header = realloc(header, currentSize);
- uint8_t* data = (void*)(header) + sizeof(C4GroupHeader) + sizeof(C4GroupEntryCore) * header->Entries;
+
+#define TMP_FILE "cc4group.tmp"
+ int tmpFile = open(TMP_FILE, O_CREAT | O_RDWR | O_TRUNC | O_EXCL, 0600);
+ if(tmpFile == -1)
+ {
+ fprintf(stderr, "ERROR: Opening tmp file \"%s\": %s\n", "cc4group.tmp", strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ if(unlink(TMP_FILE) == -1)
+ {
+ fprintf(stderr, "ERROR: Deleting tmp file \"%s\". Manual deletion is required: %s\n", TMP_FILE, strerror(errno));
+ }
+#undef TMP_FILE
+
+ // allocate file size
+ // https://gist.github.com/marcetcheverry/991042
+ if(lseek(tmpFile, currentSize - 1, SEEK_SET) == -1)
+ {
+ fprintf(stderr, "ERROR: Seeking the tmp file to the end: %s\n", strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ if(write(tmpFile, "", 1) == -1)
+ {
+ fprintf(stderr, "ERROR: Writing to the tmp file's end: %s\n", strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ uint8_t* mmappedHeader = mmap(NULL, currentSize, PROT_READ | PROT_WRITE, MAP_SHARED, tmpFile, 0);
+ if(mmappedHeader == MAP_FAILED)
+ {
+ fprintf(stderr, "ERROR: Mapping tmp file: %s\n", strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ if(close(tmpFile) == -1)
+ {
+ fprintf(stderr, "ERROR: Closing tmp file \"cc4group.tmp\": %s\n", strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ uint8_t* data = (void*)(mmappedHeader) + sizeof(C4GroupHeader) + sizeof(C4GroupEntryCore) * header->Entries;
+
+ // write alredy decompressed header and cores into the file
+ memcpy(mmappedHeader, header, data - mmappedHeader);
strm.next_out = data;
strm.avail_out = uncompressedSize;
@@ -313,7 +357,7 @@ int main(int argc, char* argv[])
return EXIT_FAILURE;
}
- C4GroupEntryData root = {.data = (uint8_t*)header, .children = NULL};
+ C4GroupEntryData root = {.data = (uint8_t*)mmappedHeader, .children = NULL};
buildChildren(&root);
handleChildren(root.children, 0, argv[2]);
@@ -322,5 +366,11 @@ int main(int argc, char* argv[])
free(header);
+ if(munmap(mmappedHeader, size) == -1)
+ {
+ fprintf(stderr, "ERROR: Unmapping tmp file: %s\n", strerror(errno));
+ return EXIT_FAILURE;
+ }
+
return EXIT_SUCCESS;
}