diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cc4group.c | 70 |
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; } |
