tempfile: use list.h for linked list
[gitweb.git] / tempfile.c
index 0e6c6b9c18f1b43d273eba5c7b9d1e03c301477c..11bda824cf77d87eb6d4718465497098721db9d5 100644 (file)
 #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;
        }
 }
 
@@ -89,7 +97,7 @@ static void remove_tempfiles_on_signal(int signo)
  */
 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);
@@ -104,8 +112,7 @@ static void prepare_tempfile_object(struct tempfile *tempfile)
                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. */
@@ -119,6 +126,12 @@ static void activate_tempfile(struct tempfile *tempfile)
        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)
 {
@@ -132,7 +145,7 @@ 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);
@@ -161,7 +174,7 @@ int mks_tempfile_sm(struct 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);
@@ -182,7 +195,7 @@ int mks_tempfile_tsm(struct 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);
@@ -291,8 +304,7 @@ int rename_tempfile(struct tempfile *tempfile, const char *path)
                return -1;
        }
 
-       tempfile->active = 0;
-       strbuf_reset(&tempfile->filename);
+       deactivate_tempfile(tempfile);
        return 0;
 }
 
@@ -303,6 +315,5 @@ void delete_tempfile(struct tempfile *tempfile)
 
        close_tempfile_gently(tempfile);
        unlink_or_warn(tempfile->filename.buf);
-       tempfile->active = 0;
-       strbuf_reset(&tempfile->filename);
+       deactivate_tempfile(tempfile);
 }