summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/cc4group.c70
1 files changed, 45 insertions, 25 deletions
diff --git a/src/cc4group.c b/src/cc4group.c
index 56f4175..c30e878 100644
--- a/src/cc4group.c
+++ b/src/cc4group.c
@@ -293,11 +293,23 @@ static void* cc4group_mapSizedWriteFd(CC4Group* const this, int fd, size_t size)
return cc4group_mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
}
+static const char tmpFileTemplate[] = "cc4grouptmpXXXXXX";
+
typedef struct {
void* addr;
size_t size;
+ char fileName[sizeof(tmpFileTemplate) / sizeof(tmpFileTemplate[0])];
+ bool unlinkLater;
} MunmapData;
+static void cc4group_tryWarnUnlink(const char* const fileName)
+{
+ if(unlink(fileName) == -1)
+ {
+ fprintf(stderr, "WARNING: Removing file \"%s\" failed. Manual deletion is required", fileName);
+ }
+}
+
static void cc4group_unmapTmpMemoryFile(MunmapData* data)
{
if(cc4group_munmap(data->addr, data->size) == -1)
@@ -305,20 +317,37 @@ static void cc4group_unmapTmpMemoryFile(MunmapData* data)
fprintf(stderr, "WARNING: munmap: Unmapping tempory file failed: %s\n", strerror(errno));
}
+ if(data->unlinkLater)
+ {
+ cc4group_tryWarnUnlink(data->fileName);
+ }
+
free(data);
}
static void* cc4group_createTmpMemoryFile(CC4Group* const this, const size_t size, CC4Group_CleanupJob* cleanupJob)
{
- void* ret;
-#define TMP_FILE "cc4group.tmp"
- int tmpFile = open(TMP_FILE, O_CREAT | O_BINARY | O_RDWR | O_EXCL, 0600);
- if(tmpFile == -1)
+ MunmapData* unmapData = malloc(sizeof(MunmapData));
+
+ if(unmapData == NULL)
{
- SET_ERRNO_ERROR("open: Opening tmp file \"" TMP_FILE "\"");
+ SET_ERRNO_ERROR("malloc: allocating memory for cleanup data");
return NULL;
}
+ strncpy(unmapData->fileName, tmpFileTemplate, sizeof(unmapData->fileName) / sizeof(unmapData->fileName[0]));
+
+ void* ret = NULL;
+ int tmpFile = mkstemp(unmapData->fileName);
+ if(tmpFile == -1)
+ {
+ SET_ERRNO_ERROR("mkstemp: Creating and opening the tmp file");
+ unmapData->fileName[0] = '\0';
+ goto ret;
+ }
+
+ unmapData->unlinkLater = unlink(unmapData->fileName) == -1; // in case it can't be deleted now (Windows -.-), delete it when cleaning up
+
ret = cc4group_mapSizedWriteFd(this, tmpFile, size);
if(ret == MAP_FAILED)
{
@@ -327,35 +356,26 @@ static void* cc4group_createTmpMemoryFile(CC4Group* const this, const size_t siz
}
else
{
- MunmapData* unmapData = malloc(sizeof(MunmapData));
-
- if(unmapData == NULL)
- {
- SET_ERRNO_ERROR("malloc: allocating memory for cleanup data");
+ unmapData->addr = ret;
+ unmapData->size = size;
- if(cc4group_munmap(ret, size) == -1)
- {
- SET_ERRNO_ERROR("malloc: allocating memory for cleanup data; additionally munmap: unmapping the mapped file failed");
- }
- ret = NULL;
- }
- else
- {
- *unmapData = (MunmapData){ret, size};
- *cleanupJob = (CC4Group_CleanupJob){(CC4Group_CleanupFunc)cc4group_unmapTmpMemoryFile, unmapData};
- }
+ *cleanupJob = (CC4Group_CleanupJob){.func = (CC4Group_CleanupFunc)cc4group_unmapTmpMemoryFile, .data = unmapData};
}
- if(close(tmpFile) == -1)
+ret:
+ if(tmpFile != -1 && close(tmpFile) == -1)
{
fprintf(stderr, "WARNING: close: Closing tmp file failed: %s\n", strerror(errno));
}
- if(unlink(TMP_FILE) == -1)
+ if(ret == NULL)
{
- fprintf(stderr, "WARNING: unlink: Failed to delete tmp file \"" TMP_FILE "\". Manual deletion is required: %s\n", strerror(errno));
+ if(unmapData->fileName[0] != '\0' && unmapData->unlinkLater)
+ {
+ cc4group_tryWarnUnlink(unmapData->fileName);
+ }
+ free(unmapData);
}
-#undef TMP_FILE
return ret;
}