From: Robert Pengelly Date: Tue, 9 Jun 2026 06:39:40 +0000 (+0100) Subject: Track and clean up temp files X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;p=sar.git Track and clean up temp files --- diff --git a/Makefile.unix b/Makefile.unix index 14d855d..46f6d67 100644 --- a/Makefile.unix +++ b/Makefile.unix @@ -7,7 +7,7 @@ VPATH := $(SRCDIR) CC := gcc CFLAGS := -D_FILE_OFFSET_BITS=64 -O2 -Wall -Werror -Wextra -ansi -pedantic -std=c90 -CSRC := append.c ar.c conv.c delete.c display.c extract.c lib.c ranlib.c replace.c report.c +CSRC := append.c ar.c conv.c delete.c display.c extract.c hashtab.c lib.c ranlib.c replace.c report.c ifeq ($(OS), Windows_NT) all: sar.exe diff --git a/Makefile.w32 b/Makefile.w32 index 26d499a..73b11b1 100644 --- a/Makefile.w32 +++ b/Makefile.w32 @@ -7,7 +7,7 @@ VPATH := $(SRCDIR) CC := gcc CFLAGS := -D_FILE_OFFSET_BITS=64 -O2 -Wall -Werror -Wextra -CSRC := append.c ar.c conv.c delete.c display.c extract.c lib.c ranlib.c replace.c report.c +CSRC := append.c ar.c conv.c delete.c display.c extract.c hashtab.c lib.c ranlib.c replace.c report.c all: sar.exe diff --git a/Makefile.wat b/Makefile.wat index dfc1286..0923602 100644 --- a/Makefile.wat +++ b/Makefile.wat @@ -4,7 +4,7 @@ SRCDIR ?= $(CURDIR) VPATH := $(SRCDIR) -SRC := append.c ar.c conv.c delete.c display.c extract.c lib.c ranlib.c replace.c report.c +SRC := append.c ar.c conv.c delete.c display.c extract.c hashtab.c lib.c ranlib.c replace.c report.c all: sar.exe diff --git a/ar.c b/ar.c index 868abda..ad5e1a1 100644 --- a/ar.c +++ b/ar.c @@ -25,6 +25,8 @@ static void cleanup (void) { } } + + cleanup_tempfiles (); } diff --git a/delete.c b/delete.c index 3649ff2..acbaab3 100644 --- a/delete.c +++ b/delete.c @@ -11,17 +11,25 @@ void delete (FILE *arfp, const char *fname) { - FILE *tfp = get_temp_file (); long bytes, len, read; const char *name; char temp[17], *p, *contents; + FILE *tfp; + + if (!(tfp = sar_tmpfile ())) { + + report_at (program_name, 0, REPORT_ERROR, "failed to create temp file"); + return; + + } + if (fwrite ("!\n", 8, 1, tfp) != 1) { - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed whilst writing ar header"); + + sar_close (tfp); return; } @@ -78,7 +86,7 @@ void delete (FILE *arfp, const char *fname) { if (fwrite (&hdr, sizeof (hdr), 1, tfp) != 1) { - fclose (tfp); + sar_close (tfp); report_at (program_name, 0, REPORT_ERROR, "failed whilst writing header"); exit (EXIT_FAILURE); @@ -99,10 +107,11 @@ void delete (FILE *arfp, const char *fname) { if (fread (contents, read, 1, arfp) != 1) { + report_at (program_name, 0, REPORT_ERROR, "failed to read %ld bytes from %s", bytes, state->outfile); + + sar_close (tfp); free (contents); - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed to read %ld bytes from %s", bytes, state->outfile); exit (EXIT_FAILURE); } @@ -111,10 +120,11 @@ void delete (FILE *arfp, const char *fname) { if (fwrite (contents, read, 1, tfp) != 1) { + report_at (program_name, 0, REPORT_ERROR, "failed to write temp file"); + + sar_close (tfp); free (contents); - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed to write temp file"); exit (EXIT_FAILURE); } @@ -130,9 +140,9 @@ void delete (FILE *arfp, const char *fname) { if ((arfp = fopen (state->outfile, "w+b")) == NULL) { - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed to open %s for writing", state->outfile); + + sar_close (tfp); exit (EXIT_FAILURE); } @@ -155,10 +165,11 @@ void delete (FILE *arfp, const char *fname) { if (fread (contents, read, 1, tfp) != 1) { + report_at (program_name, 0, REPORT_ERROR, "failed whilst reading temp file"); + + sar_close (tfp); free (contents); - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed whilst reading temp file"); return; } @@ -167,17 +178,18 @@ void delete (FILE *arfp, const char *fname) { if (fwrite (contents, read, 1, arfp) != 1) { + report_at (program_name, 0, REPORT_ERROR, "failed whilst writing %s", state->outfile); + + sar_close (tfp); free (contents); - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed whilst writing %s", state->outfile); exit (EXIT_FAILURE); } } + sar_close (tfp); free (contents); - fclose (tfp); } diff --git a/hashtab.c b/hashtab.c new file mode 100755 index 0000000..78b3d6c --- /dev/null +++ b/hashtab.c @@ -0,0 +1,222 @@ +/****************************************************************************** + * @file hashtab.c + *****************************************************************************/ +#include +#include +#include + +#include "hashtab.h" + +static struct hashtab_entry *find_entry (struct hashtab_entry *entries, unsigned long capacity, struct hashtab_name *key); + +static int adjust_capacity (struct hashtab *table, unsigned long new_capacity) { + + struct hashtab_entry *new_entries, *old_entries; + unsigned long i, new_count, old_capacity; + + if ((new_entries = malloc (sizeof (*new_entries) * new_capacity)) == NULL) { + return -2; + } + + for (i = 0; i < new_capacity; i++) { + + struct hashtab_entry *entry = &new_entries[i]; + + entry->key = NULL; + entry->value = NULL; + + } + + old_entries = table->entries; + old_capacity = table->capacity; + + new_count = 0; + + for (i = 0; i < old_capacity; i++) { + + struct hashtab_entry *entry = &old_entries[i], *dest; + + if (entry->key == NULL) { + continue; + } + + dest = find_entry (new_entries, new_capacity, entry->key); + + dest->key = entry->key; + dest->value = entry->value; + + new_count++; + + } + + free (old_entries); + + table->capacity = new_capacity; + table->count = new_count; + table->entries = new_entries; + table->used = new_count; + + return 0; + +} + +static struct hashtab_entry *find_entry (struct hashtab_entry *entries, unsigned long capacity, struct hashtab_name *key) { + + struct hashtab_entry *tombstone = NULL; + unsigned long index; + + for (index = key->hash % capacity; ; index = (index + 1) % capacity) { + + struct hashtab_entry *entry = &entries[index]; + + if (entry->key == NULL) { + + if (entry->value == NULL) { + + if (tombstone == NULL) { + return entry; + } + + return tombstone; + + } else if (tombstone == NULL) { + tombstone = entry; + } + + } else if (entry->key->bytes == key->bytes) { + + if (memcmp (entry->key->chars, key->chars, key->bytes) == 0 && entry->key->hash == key->hash) { + return entry; + } + + } + + } + +} + +static unsigned long hash_string (const void *p, unsigned long length) { + + unsigned char *str = (unsigned char *) p; + unsigned long i; + + unsigned long result = 0; + + for (i = 0; i < length; i++) { + result = (((unsigned short) str[i]) << 4) + (result >> 9) + result + (result >> 3) + (((unsigned short) str[i]) << 2) - (result << 12); + } + + return result; + +} + +struct hashtab_name *hashtab_alloc_name (const char *str) { + + unsigned long bytes = strlen (str), hash = hash_string (str, bytes); + struct hashtab_name *name; + + if (!(name = malloc (sizeof (*name)))) { + return 0; + } + + name->bytes = bytes; + name->chars = str; + name->hash = hash; + + return name; + +} + +struct hashtab_name *hashtab_get_key (struct hashtab *table, const char *name) { + + struct hashtab_name *key; + struct hashtab_entry *entry; + + if (!table || table->count == 0 || !(key = hashtab_alloc_name (name))) { + return 0; + } + + entry = find_entry (table->entries, table->capacity, key); + free (key); + + return entry->key; + +} + +void *hashtab_get (struct hashtab *table, struct hashtab_name *key) { + + struct hashtab_entry *entry; + + if (!table || table->count == 0) { + return 0; + } + + entry = find_entry (table->entries, table->capacity, key); + + if (!entry->key) { + return 0; + } + + return entry->value; + +} + +int hashtab_put (struct hashtab *table, struct hashtab_name *key, void *value) { + + const int MIN_CAPACITY = 15; + + struct hashtab_entry *entry; + int ret = 0; + + if (table->used >= table->capacity / 2) { + + long capacity = table->capacity * 2 - 1; + + if (capacity < MIN_CAPACITY) { + capacity = MIN_CAPACITY; + } + + if ((ret = adjust_capacity (table, capacity))) { + return ret; + } + + } + + entry = find_entry (table->entries, table->capacity, key); + + if (!entry->key) { + + table->count++; + + if (!entry->value) { + table->used++; + } + + } + + entry->key = key; + entry->value = value; + + return 0; + +} + +void hashtab_remove (struct hashtab *table, struct hashtab_name *key) { + + struct hashtab_entry *entry; + + if (!table || table->count == 0) { + return; + } + + entry = find_entry (table->entries, table->capacity, key); + + if (!entry->key) { + return; + } + + entry->value = HASHTAB_TOMBSTONE; + entry->key = 0; + + --table->count; +} diff --git a/hashtab.h b/hashtab.h new file mode 100755 index 0000000..1959593 --- /dev/null +++ b/hashtab.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * @file hashtab.h + *****************************************************************************/ +#ifndef _HASHTAB_H +#define _HASHTAB_H + +struct hashtab_name { + + const char *chars; + unsigned long bytes, hash; + +}; + +struct hashtab_entry { + + struct hashtab_name *key; + void *value; + +}; + +struct hashtab { + + struct hashtab_entry *entries; + int capacity, count, used; + +}; + +#define HASHTAB_TOMBSTONE ((void *) -1) +struct hashtab_name *hashtab_alloc_name (const char *str); + +struct hashtab_name *hashtab_get_key (struct hashtab *table, const char *name); +void *hashtab_get (struct hashtab *table, struct hashtab_name *key); + +int hashtab_put (struct hashtab *table, struct hashtab_name *key, void *value); +void hashtab_remove (struct hashtab *table, struct hashtab_name *key); + +#endif /* _HASHTAB_H */ diff --git a/lib.c b/lib.c index af41105..2eea95d 100644 --- a/lib.c +++ b/lib.c @@ -271,9 +271,26 @@ void *xrealloc (void *__ptr, unsigned long __size) { #if defined (unix) || defined (__unix) || defined (__unix__) || defined (__APPLE__) -FILE *get_temp_file (void) { +# include +# include "hashtab.h" - char *temp_path, *template; +struct temp_file { + + char *name, *path; + FILE *fp; + +}; + +static struct hashtab hashtab_tmpfiles = { 0 }; + +FILE *sar_tmpfile (void) { + + char *temp_path, *template, *name, *p; + + struct hashtab_name *key; + struct temp_file *tmp; + + FILE *fp; int fd; if (!(temp_path = getenv ("TMPDIR"))) { @@ -281,40 +298,434 @@ FILE *get_temp_file (void) { } template = xmalloc (strlen (temp_path) + 1 + 10 + 1); + +again: + sprintf (template, "%s/sarXXXXXX", temp_path); - if (!(fd = mkstemp (template))) { + if ((fd = mkstemp (template)) < 0) { return 0; } - return fdopen (fd, "w+b"); + if ((p = strrchr (template, '/'))) { + name = xstrdup (p + 1); + } else { + name = xstrdup (template); + } + + if ((key = hashtab_get_key (&hashtab_tmpfiles, name))) { + + close (fd); + + remove (template); + free (name); + + goto again; + + } + + if (!((key = hashtab_alloc_name (name)))) { + + report_at (program_name, 0, REPORT_ERROR, "failed to allocate memory for key"); + exit (EXIT_FAILURE); + + } + + if ((fp = fdopen (fd, "w+b"))) { + + tmp = xmalloc (sizeof (*tmp)); + tmp->fp = fp; + + tmp->path = xstrdup (template); + tmp->name = name; + + hashtab_put (&hashtab_tmpfiles, key, tmp); + + free (template); + return fp; + + } + + free (name); + free (key); + + close (fd); + + remove (template); + free (template); + + return 0; + +} + +int sar_close (FILE *fp) { + + struct hashtab_entry *entry; + struct temp_file *tmp; + + int ret, i; + + for (i = 0; i < hashtab_tmpfiles.capacity; i++) { + + if (!(entry = &hashtab_tmpfiles.entries[i])) { + continue; + } + + if (!entry->key || !entry->value || entry->value == HASHTAB_TOMBSTONE) { + continue; + } + + tmp = (struct temp_file *) entry->value; + + if (tmp->fp == fp) { + + if ((ret = fclose (fp))) { + return ret; + } + + hashtab_remove (&hashtab_tmpfiles, entry->key); + remove (tmp->path); + + free (tmp->path); + free (tmp->name); + + free (tmp); + return 0; + + } + + } + + return 0; + +} + +void cleanup_tempfiles (void) { + + struct hashtab_entry *entry; + struct temp_file *tmp; + + int ret, i; + + for (i = 0; i < hashtab_tmpfiles.capacity; i++) { + + if (!(entry = &hashtab_tmpfiles.entries[i])) { + continue; + } + + if (!entry->key || !entry->value || entry->value == HASHTAB_TOMBSTONE) { + continue; + } + + tmp = (struct temp_file *) entry->value; + + if ((ret = fclose (tmp->fp))) { + continue; + } + + remove (tmp->path); + + } } -#elif defined (_WIN32) -# include +#elif defined (_WIN32) +# include # ifndef MAX_PATH # define MAX_PATH 206 # endif -FILE *get_temp_file (void) { +# include "hashtab.h" + +struct temp_file { + + char *name, *path; + FILE *fp; + +}; + +static struct hashtab hashtab_tmpfiles = { 0 }; + +FILE *sar_tmpfile (void) { char temp_path[MAX_PATH + 1] = { 0 }; char full_path[MAX_PATH + 1] = { 0 }; + struct hashtab_name *key; + struct temp_file *tmp; + + char *name, *p; + FILE *fp; + if (!GetTempPath (MAX_PATH + 1, temp_path)) { return 0; } +again: + if (!GetTempFileName (temp_path, "sar", 0, full_path)) { return 0; } - return fopen (full_path, "w+b"); + if ((p = strrchr (full_path, '\\'))) { + name = xstrdup (p + 1); + } else { + name = xstrdup (full_path); + } + + if ((key = hashtab_get_key (&hashtab_tmpfiles, name))) { + + free (name); + goto again; + + } + + if (!((key = hashtab_alloc_name (name)))) { + + report_at (program_name, 0, REPORT_ERROR, "failed to allocate memory for key"); + exit (EXIT_FAILURE); + + } + + if ((fp = fopen (full_path, "w+b"))) { + + tmp = xmalloc (sizeof (*tmp)); + tmp->fp = fp; + + tmp->path = xstrdup (full_path); + tmp->name = name; + + hashtab_put (&hashtab_tmpfiles, key, tmp); + return fp; + + } + + free (name); + free (key); + + return 0; + +} + +int sar_close (FILE *fp) { + + struct hashtab_entry *entry; + struct temp_file *tmp; + + int ret, i; + + for (i = 0; i < hashtab_tmpfiles.capacity; i++) { + + if (!(entry = &hashtab_tmpfiles.entries[i])) { + continue; + } + + if (!entry->key || !entry->value || entry->value == HASHTAB_TOMBSTONE) { + continue; + } + + tmp = (struct temp_file *) entry->value; + + if (tmp->fp == fp) { + + if ((ret = fclose (fp))) { + return ret; + } + + hashtab_remove (&hashtab_tmpfiles, entry->key); + remove (tmp->path); + + free (tmp->path); + free (tmp->name); + + free (tmp); + return 0; + + } + + } + + return 0; + +} + +void cleanup_tempfiles (void) { + + struct hashtab_entry *entry; + struct temp_file *tmp; + + int ret, i; + + for (i = 0; i < hashtab_tmpfiles.capacity; i++) { + + if (!(entry = &hashtab_tmpfiles.entries[i])) { + continue; + } + + if (!entry->key || !entry->value || entry->value == HASHTAB_TOMBSTONE) { + continue; + } + + tmp = (struct temp_file *) entry->value; + + if ((ret = fclose (tmp->fp))) { + continue; + } + + remove (tmp->path); + + } } #else -FILE *get_temp_file (void) { - return tmpfile (); +# include "hashtab.h" + +struct temp_file { + + char *name; + FILE *fp; + +}; + +FILE *sar_tmpfile (void) { + + static char name[64] = { 0 }; + + char *temp; + unsigned long index, i, j; + + struct hashtab_name *key; + struct temp_file *tmp; + + FILE *fp; + + for (i = 0; i < 456976; i++) { + + sprintf (name, "sar_AAAA.tmp"); + + index = 7; + j = i; + + do { + + name[index] = (j % 26) + 'A'; + index--; + + } while ((j /= 26) > 0); + + temp = xstrdup (name); + + if ((key = hashtab_get_key (&hashtab_tmpfiles, temp))) { + + free (temp); + continue; + + } + + if ((fp = fopen (temp, "rb"))) { + + fclose (fp); + + free (temp); + continue; + + } + + if (!((key = hashtab_alloc_name (temp)))) { + + report_at (program_name, 0, REPORT_ERROR, "failed to allocate memory for key"); + exit (EXIT_FAILURE); + + } + + if ((fp = fopen (temp, "w+b"))) { + + tmp = xmalloc (sizeof (*tmp)); + + tmp->name = temp; + tmp->fp = fp; + + hashtab_put (&hashtab_tmpfiles, key, tmp); + return fp; + + } + + free (temp); + free (key); + + } + + return 0; + +} + +int sar_close (FILE *fp) { + + struct hashtab_entry *entry; + struct temp_file *tmp; + + int ret, i; + + for (i = 0; i < hashtab_tmpfiles.capacity; i++) { + + if (!(entry = &hashtab_tmpfiles.entries[i])) { + continue; + } + + if (!entry->key || !entry->value || entry->value == HASHTAB_TOMBSTONE) { + continue; + } + + tmp = (struct temp_file *) entry->value; + + if (tmp->fp == fp) { + + if ((ret = fclose (fp))) { + return ret; + } + + hashtab_remove (&hashtab_tmpfiles, entry->key); + remove (tmp->name); + + free (tmp->name); + free (tmp); + + return 0; + + } + + } + + return 0; + +} + +void cleanup_tempfiles (void) { + + struct hashtab_entry *entry; + struct temp_file *tmp; + + int ret, i; + + for (i = 0; i < hashtab_tmpfiles.capacity; i++) { + + if (!(entry = &hashtab_tmpfiles.entries[i])) { + continue; + } + + if (!entry->key || !entry->value || entry->value == HASHTAB_TOMBSTONE) { + continue; + } + + tmp = (struct temp_file *) entry->value; + + if ((ret = fclose (tmp->fp))) { + continue; + } + + remove (tmp->name); + + } + } #endif diff --git a/lib.h b/lib.h index 52f1f48..d9f51ca 100644 --- a/lib.h +++ b/lib.h @@ -16,6 +16,10 @@ void *xmalloc (unsigned long __size); void *xrealloc (void *__ptr, unsigned long __size); #include -FILE *get_temp_file (void); + +FILE *sar_tmpfile (void); +int sar_close (FILE *fp); + +void cleanup_tempfiles (void); #endif /* _LIB_H */ diff --git a/ranlib.c b/ranlib.c index 7b26ca5..9cd53f8 100644 --- a/ranlib.c +++ b/ranlib.c @@ -715,8 +715,6 @@ static void omf_get_symbols (void *object, char *filename, uint64_t bytes, int64 void ranlib (FILE *arfp) { - FILE *tfp = get_temp_file (); - struct ar_header header; long i, j, len, read, val; @@ -726,12 +724,21 @@ void ranlib (FILE *arfp) { char temp[16]; long offset = 0; + FILE *tfp; + #if UINT_MAX == 65535 long bytes; #else int bytes; #endif + if (!(tfp = sar_tmpfile ())) { + + report_at (program_name, 0, REPORT_ERROR, "failed to create temp file"); + return; + + } + for (;;) { struct ar_header hdr; @@ -765,9 +772,9 @@ void ranlib (FILE *arfp) { if (fread (object, bytes, 1, arfp) != 1) { - free (object); - report_at (program_name, 0, REPORT_ERROR, "failed to read %ld bytes from %s", bytes, state->outfile); + + free (object); exit (EXIT_FAILURE); @@ -836,9 +843,9 @@ void ranlib (FILE *arfp) { if (fwrite ("!\n", 8, 1, tfp) != 1) { - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed whilst writing ar header"); + + sar_close (tfp); return; } @@ -872,9 +879,9 @@ void ranlib (FILE *arfp) { if (fwrite (&header, sizeof (header), 1, tfp) != 1) { - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed whilst writing header"); + + sar_close (tfp); return; } @@ -960,9 +967,9 @@ void ranlib (FILE *arfp) { if (fwrite (&hdr, sizeof (hdr), 1, tfp) != 1) { - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed whilst writing header"); + + sar_close (tfp); exit (EXIT_FAILURE); } @@ -981,10 +988,11 @@ void ranlib (FILE *arfp) { if (fread (contents, read, 1, arfp) != 1) { + report_at (program_name, 0, REPORT_ERROR, "failed to read %ld bytes from %s", bytes, state->outfile); + + sar_close (tfp); free (contents); - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed to read %ld bytes from %s", bytes, state->outfile); exit (EXIT_FAILURE); } @@ -993,10 +1001,11 @@ void ranlib (FILE *arfp) { if (fwrite (contents, read, 1, tfp) != 1) { + report_at (program_name, 0, REPORT_ERROR, "failed to write temp file"); + + sar_close (tfp); free (contents); - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed to write temp file"); exit (EXIT_FAILURE); } @@ -1012,9 +1021,9 @@ void ranlib (FILE *arfp) { if ((arfp = fopen (state->outfile, "w+b")) == NULL) { - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed to open %s for writing", state->outfile); + + sar_close (tfp); exit (EXIT_FAILURE); } @@ -1037,10 +1046,11 @@ void ranlib (FILE *arfp) { if (fread (contents, read, 1, tfp) != 1) { + report_at (program_name, 0, REPORT_ERROR, "failed whilst reading temp file"); + + sar_close (tfp); free (contents); - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed whilst reading temp file"); return; } @@ -1049,17 +1059,18 @@ void ranlib (FILE *arfp) { if (fwrite (contents, read, 1, arfp) != 1) { + report_at (program_name, 0, REPORT_ERROR, "failed whilst writing %s", state->outfile); + + sar_close (tfp); free (contents); - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed whilst writing %s", state->outfile); exit (EXIT_FAILURE); } } + sar_close (tfp); free (contents); - fclose (tfp); } diff --git a/replace.c b/replace.c index 876df8a..d0e9ad7 100644 --- a/replace.c +++ b/replace.c @@ -11,17 +11,25 @@ void replace (FILE *arfp, const char *fname) { - FILE *tfp = get_temp_file (); long bytes, len, read; const char *name; char temp[17], *p, *contents; + FILE *tfp; + + if (!(tfp = sar_tmpfile ())) { + + report_at (program_name, 0, REPORT_ERROR, "failed to create temp file"); + return; + + } + if (fwrite ("!\n", 8, 1, tfp) != 1) { - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed whilst writing ar header"); + + sar_close (tfp); return; } @@ -83,9 +91,9 @@ void replace (FILE *arfp, const char *fname) { if (fwrite (&hdr, sizeof (hdr), 1, tfp) != 1) { - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed whilst writing header"); + + sar_close (tfp); exit (EXIT_FAILURE); } @@ -104,9 +112,9 @@ void replace (FILE *arfp, const char *fname) { if (fread (contents, read, 1, arfp) != 1) { - free (contents); - report_at (program_name, 0, REPORT_ERROR, "failed to read %ld bytes from %s", bytes, state->outfile); + + free (contents); exit (EXIT_FAILURE); } @@ -114,10 +122,10 @@ void replace (FILE *arfp, const char *fname) { bytes -= read; if (fwrite (contents, read, 1, tfp) != 1) { - - free (contents); report_at (program_name, 0, REPORT_ERROR, "failed to write temp file"); + + free (contents); exit (EXIT_FAILURE); } @@ -140,9 +148,9 @@ void replace (FILE *arfp, const char *fname) { if ((arfp = fopen (state->outfile, "w+b")) == NULL) { - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed to open %s", state->outfile); + + sar_close (tfp); exit (EXIT_FAILURE); } @@ -165,10 +173,11 @@ void replace (FILE *arfp, const char *fname) { if (fread (contents, read, 1, tfp) != 1) { + report_at (program_name, 0, REPORT_ERROR, "failed whilst reading temp file"); + + sar_close (tfp); free (contents); - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed whilst reading temp file"); return; } @@ -177,17 +186,18 @@ void replace (FILE *arfp, const char *fname) { if (fwrite (contents, read, 1, arfp) != 1) { + report_at (program_name, 0, REPORT_ERROR, "failed whilst writing %s", state->outfile); + + sar_close (tfp); free (contents); - fclose (tfp); - report_at (program_name, 0, REPORT_ERROR, "failed whilst writing %s", state->outfile); exit (EXIT_FAILURE); } } + sar_close (tfp); free (contents); - fclose (tfp); }