#include "tempfile.h"
#include "sigchain.h"
-static struct tempfile *volatile tempfile_list;
+static VOLATILE_LIST_HEAD(tempfile_list);
-static void remove_tempfiles(int skip_fclose)
+static void remove_tempfiles(int in_signal_handler)
{
pid_t me = getpid();
+ volatile struct volatile_list_head *pos;
- while (tempfile_list) {
- if (tempfile_list->owner == me) {
- /* fclose() is not safe to call in a signal handler */
- if (skip_fclose)
- tempfile_list->fp = NULL;
- delete_tempfile(tempfile_list);
- }
- tempfile_list = tempfile_list->next;
+ list_for_each(pos, &tempfile_list) {
+ struct tempfile *p = list_entry(pos, struct tempfile, list);
+
+ if (!is_tempfile_active(p) || p->owner != me)
+ continue;
+
+ if (p->fd >= 0)
+ close(p->fd);
+
+ if (in_signal_handler)
+ unlink(p->filename.buf);
+ else
+ unlink_or_warn(p->filename.buf);
+
+ p->active = 0;
}
}
*/
static void prepare_tempfile_object(struct tempfile *tempfile)
{
- if (!tempfile_list) {
+ if (volatile_list_empty(&tempfile_list)) {
/* One-time initialization */
sigchain_push_common(remove_tempfiles_on_signal);
atexit(remove_tempfiles_on_exit);
tempfile->active = 0;
tempfile->owner = 0;
strbuf_init(&tempfile->filename, 0);
- tempfile->next = tempfile_list;
- tempfile_list = tempfile;
+ volatile_list_add(&tempfile->list, &tempfile_list);
tempfile->on_list = 1;
} else if (tempfile->filename.len) {
/* This shouldn't happen, but better safe than sorry. */
tempfile->active = 1;
}
+static void deactivate_tempfile(struct tempfile *tempfile)
+{
+ tempfile->active = 0;
+ strbuf_release(&tempfile->filename);
+}
+
/* Make sure errno contains a meaningful value on error */
int create_tempfile(struct tempfile *tempfile, const char *path)
{
tempfile->fd = open(tempfile->filename.buf,
O_RDWR | O_CREAT | O_EXCL, 0666);
if (tempfile->fd < 0) {
- strbuf_reset(&tempfile->filename);
+ deactivate_tempfile(tempfile);
return -1;
}
activate_tempfile(tempfile);
strbuf_add_absolute_path(&tempfile->filename, template);
tempfile->fd = git_mkstemps_mode(tempfile->filename.buf, suffixlen, mode);
if (tempfile->fd < 0) {
- strbuf_reset(&tempfile->filename);
+ deactivate_tempfile(tempfile);
return -1;
}
activate_tempfile(tempfile);
strbuf_addf(&tempfile->filename, "%s/%s", tmpdir, template);
tempfile->fd = git_mkstemps_mode(tempfile->filename.buf, suffixlen, mode);
if (tempfile->fd < 0) {
- strbuf_reset(&tempfile->filename);
+ deactivate_tempfile(tempfile);
return -1;
}
activate_tempfile(tempfile);
return -1;
}
- tempfile->active = 0;
- strbuf_reset(&tempfile->filename);
+ deactivate_tempfile(tempfile);
return 0;
}
close_tempfile_gently(tempfile);
unlink_or_warn(tempfile->filename.buf);
- tempfile->active = 0;
- strbuf_reset(&tempfile->filename);
+ deactivate_tempfile(tempfile);
}