From 780d7c53a8479b62fe8d90e16a3045187e347cc7 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sun, 2 Aug 2015 21:44:04 +0100 Subject: generates files with temporary name and only overwites on change --- src/utils.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 121 insertions(+), 28 deletions(-) (limited to 'src/utils.c') diff --git a/src/utils.c b/src/utils.c index 9e50a93..1e8ec23 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,3 +1,11 @@ +/* utility functions + * + * This file is part of nsgenbind. + * Published under the MIT License, + * http://www.opensource.org/licenses/mit-license.php + * Copyright 2015 Vincent Sanders + */ + #include #include #include @@ -10,34 +18,120 @@ /* exported function documented in utils.h */ char *genb_fpath(const char *fname) { - char *fpath; - int fpathl; + char *fpath; + int fpathl; + + fpathl = strlen(options->outdirname) + strlen(fname) + 2; + fpath = malloc(fpathl); + snprintf(fpath, fpathl, "%s/%s", options->outdirname, fname); + + return fpath; +} + +static char *genb_fpath_tmp(const char *fname) +{ + char *fpath; + int fpathl; - fpathl = strlen(options->outdirname) + strlen(fname) + 2; - fpath = malloc(fpathl); - snprintf(fpath, fpathl, "%s/%s", options->outdirname, fname); + fpathl = strlen(options->outdirname) + strlen(fname) + 3; + fpath = malloc(fpathl); + snprintf(fpath, fpathl, "%s/%s~", options->outdirname, fname); - return fpath; + return fpath; } /* exported function documented in utils.h */ FILE *genb_fopen(const char *fname, const char *mode) { - char *fpath; - FILE *filef; + char *fpath; + FILE *filef; + + fpath = genb_fpath(fname); + + filef = fopen(fpath, mode); + if (filef == NULL) { + fprintf(stderr, "Error: unable to open file %s (%s)\n", + fpath, strerror(errno)); + free(fpath); + return NULL; + } + free(fpath); + + return filef; +} + +/* exported function documented in utils.h */ +FILE *genb_fopen_tmp(const char *fname) +{ + char *fpath; + FILE *filef; + + fpath = genb_fpath_tmp(fname); + + filef = fopen(fpath, "w+"); + if (filef == NULL) { + fprintf(stderr, "Error: unable to open file %s (%s)\n", + fpath, strerror(errno)); + free(fpath); + return NULL; + } + free(fpath); - fpath = genb_fpath(fname); + return filef; +} - filef = fopen(fpath, mode); - if (filef == NULL) { - fprintf(stderr, "Error: unable to open file %s (%s)\n", - fpath, strerror(errno)); +int genb_fclose_tmp(FILE *filef_tmp, const char *fname) +{ + char *fpath; + char *tpath; + FILE *filef; + char tbuf[1024]; + char fbuf[1024]; + size_t trd; + size_t frd; + + fpath = genb_fpath(fname); + tpath = genb_fpath_tmp(fname); + + filef = fopen(fpath, "r"); + if (filef == NULL) { + /* unable to open target file for comparison */ + + fclose(filef_tmp); /* close tmpfile */ + + remove(fpath); + rename(tpath, fpath); + } else { + rewind(filef_tmp); + + frd = fread(fbuf, 1, 1024, filef); + while (frd != 0) { + trd = fread(tbuf, 1, frd, filef_tmp); + if ((trd != frd) || + (memcmp(tbuf, fbuf, trd) != 0)) { + /* file doesnt match */ + fclose(filef_tmp); + + remove(fpath); + rename(tpath, fpath); + + goto close_done; + } + + frd = fread(fbuf, 1, 1024, filef); + } + + /* was the same kill temporary file */ + fclose(filef_tmp); + fclose(filef); + remove(tpath); + } + +close_done: free(fpath); - return NULL; - } - free(fpath); + free(tpath); - return filef; + return 0; } @@ -45,20 +139,19 @@ FILE *genb_fopen(const char *fname, const char *mode) char *strndup(const char *s, size_t n) { - size_t len; - char *s2; + size_t len; + char *s2; - for (len = 0; len != n && s[len]; len++) - continue; + for (len = 0; len != n && s[len]; len++) + continue; - s2 = malloc(len + 1); - if (!s2) - return 0; + s2 = malloc(len + 1); + if (!s2) + return 0; - memcpy(s2, s, len); - s2[len] = 0; - return s2; + memcpy(s2, s, len); + s2[len] = 0; + return s2; } #endif - -- cgit v1.2.3