diff options
| author | Markus Mittendrein <git@maxmitti.tk> | 2019-03-20 11:07:25 +0100 |
|---|---|---|
| committer | Markus Mittendrein <git@maxmitti.tk> | 2019-03-20 11:13:30 +0100 |
| commit | 32b339a155ebd2be47d0f6636031df92e0a5f7a0 (patch) | |
| tree | 14f1247731d9116c73789f10bb589bbba2e6802c /src | |
| parent | b1b4973e1e8163a24f0560c1fb8c83b901d05b66 (diff) | |
| download | cc4group-32b339a155ebd2be47d0f6636031df92e0a5f7a0.tar.gz cc4group-32b339a155ebd2be47d0f6636031df92e0a5f7a0.zip | |
Use mkstemp for creating the tmp file and fallback to unlink the tmp file after unmapping it if it fails immediately after opening (Mainly needed to fix tmp file on Windows)
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; } |
