diff --git a/tempfile.c b/tempfile.c index 11bda824cf..f82a5f3676 100644 --- a/tempfile.c +++ b/tempfile.c @@ -42,8 +42,7 @@ * states in which this condition doesn't hold). Client code should * *not* rely on the filename being empty in this state. * - `fd` is -1 and `fp` is `NULL` - * - the object is left registered in the `tempfile_list`, and - * `on_list` is set. + * - the object is removed from `tempfile_list` (but could be used again) * * A temporary file is owned by the process that created it. The * `tempfile` has an `owner` field that records the owner's PID. This @@ -92,36 +91,30 @@ static void remove_tempfiles_on_signal(int signo) raise(signo); } -/* - * Initialize *tempfile if necessary and add it to tempfile_list. - */ static void prepare_tempfile_object(struct tempfile *tempfile) { - if (volatile_list_empty(&tempfile_list)) { - /* One-time initialization */ - sigchain_push_common(remove_tempfiles_on_signal); - atexit(remove_tempfiles_on_exit); - } - - if (is_tempfile_active(tempfile)) - BUG("prepare_tempfile_object called for active object"); - if (!tempfile->on_list) { - /* Initialize *tempfile and add it to tempfile_list: */ - tempfile->fd = -1; - tempfile->fp = NULL; - tempfile->active = 0; - tempfile->owner = 0; - strbuf_init(&tempfile->filename, 0); - 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. */ - BUG("prepare_tempfile_object called for improperly-reset object"); - } + tempfile->fd = -1; + tempfile->fp = NULL; + tempfile->active = 0; + tempfile->owner = 0; + INIT_LIST_HEAD(&tempfile->list); + strbuf_init(&tempfile->filename, 0); } static void activate_tempfile(struct tempfile *tempfile) { + static int initialized; + + if (is_tempfile_active(tempfile)) + BUG("activate_tempfile called for active object"); + + if (!initialized) { + sigchain_push_common(remove_tempfiles_on_signal); + atexit(remove_tempfiles_on_exit); + initialized = 1; + } + + volatile_list_add(&tempfile->list, &tempfile_list); tempfile->owner = getpid(); tempfile->active = 1; } @@ -130,6 +123,7 @@ static void deactivate_tempfile(struct tempfile *tempfile) { tempfile->active = 0; strbuf_release(&tempfile->filename); + volatile_list_del(&tempfile->list); } /* Make sure errno contains a meaningful value on error */ diff --git a/tempfile.h b/tempfile.h index 2ee24f4380..e32b4df092 100644 --- a/tempfile.h +++ b/tempfile.h @@ -17,12 +17,9 @@ * * The caller: * - * * Allocates a `struct tempfile` either as a static variable or on - * the heap, initialized to zeros. Once you use the structure to - * call `create_tempfile()`, it belongs to the tempfile subsystem - * and its storage must remain valid throughout the life of the - * program (i.e. you cannot use an on-stack variable to hold this - * structure). + * * Allocates a `struct tempfile`. Once the structure is passed to + * `create_tempfile()`, its storage must remain valid until + * `delete_tempfile()` or `rename_tempfile()` is called on it. * * * Attempts to create a temporary file by calling * `create_tempfile()`. @@ -52,9 +49,8 @@ * temporary file by calling `close_tempfile_gently()`, and later call * `delete_tempfile()` or `rename_tempfile()`. * - * Even after the temporary file is renamed or deleted, the `tempfile` - * object must not be freed or altered by the caller. However, it may - * be reused; just pass it to another call of `create_tempfile()`. + * After the temporary file is renamed or deleted, the `tempfile` + * object may be reused or freed. * * If the program exits before `rename_tempfile()` or * `delete_tempfile()` is called, an `atexit(3)` handler will close @@ -88,7 +84,6 @@ struct tempfile { volatile int fd; FILE *volatile fp; volatile pid_t owner; - char on_list; struct strbuf filename; };