size = buf.len;
}
if (write_in_full(fd, blob, size) != size ||
- close_tempfile(&temp->tempfile))
+ close_tempfile_gently(&temp->tempfile))
die_errno("unable to write temp-file");
temp->name = get_tempfile_path(&temp->tempfile);
oid_to_hex_r(temp->hex, oid);
if (fd < 0)
return error_errno(_("could not create temporary file"));
if (write_in_full(fd, signature, signature_size) < 0 ||
- close_tempfile(&temp) < 0) {
+ close_tempfile_gently(&temp) < 0) {
error_errno(_("failed writing detached signature to '%s'"),
temp.filename.buf);
delete_tempfile(&temp);
*/
static inline int close_lock_file(struct lock_file *lk)
{
- return close_tempfile(&lk->tempfile);
+ int ret = close_tempfile_gently(&lk->tempfile);
+ if (ret) {
+ int saved_errno = errno;
+ delete_tempfile(&lk->tempfile);
+ errno = saved_errno;
+ }
+ return ret;
}
/*
if (ce_flush(&c, newfd, istate->sha1))
return -1;
- if (close_tempfile(tempfile))
- return error(_("could not close '%s'"), tempfile->filename.buf);
+ if (close_tempfile_gently(tempfile)) {
+ error(_("could not close '%s'"), tempfile->filename.buf);
+ delete_tempfile(tempfile);
+ return -1;
+ }
if (stat(tempfile->filename.buf, &st))
return -1;
istate->timestamp.sec = (unsigned int)st.st_mtime;
fd = xmks_tempfile(&temp, git_path("shallow_XXXXXX"));
if (write_in_full(fd, sb.buf, sb.len) != sb.len ||
- close_tempfile(&temp) < 0)
+ close_tempfile_gently(&temp) < 0)
die_errno("failed to write to %s",
get_tempfile_path(&temp));
strbuf_release(&sb);
* `fdopen_tempfile()` has been called on the object
* - `owner` holds the PID of the process that created the file
*
- * - Active, file closed (after successful `close_tempfile()`). Same
+ * - Active, file closed (after `close_tempfile_gently()`). Same
* as the previous state, except that the temporary file is closed,
* `fd` is -1, and `fp` is `NULL`.
*
- * - Inactive (after `delete_tempfile()`, `rename_tempfile()`, a
- * failed attempt to create a temporary file, or a failed
- * `close_tempfile()`). In this state:
+ * - Inactive (after `delete_tempfile()`, `rename_tempfile()`, or a
+ * failed attempt to create a temporary file). In this state:
*
* - `active` is unset
* - `filename` is empty (usually, though there are transitory
return tempfile->fp;
}
-int close_tempfile(struct tempfile *tempfile)
+int close_tempfile_gently(struct tempfile *tempfile)
{
int fd = tempfile->fd;
FILE *fp = tempfile->fp;
err = close(fd);
}
- if (err) {
- int save_errno = errno;
- delete_tempfile(tempfile);
- errno = save_errno;
- return -1;
- }
-
- return 0;
+ return err ? -1 : 0;
}
int reopen_tempfile(struct tempfile *tempfile)
if (!tempfile->active)
die("BUG: rename_tempfile called for inactive object");
- if (close_tempfile(tempfile))
+ if (close_tempfile_gently(tempfile)) {
+ delete_tempfile(tempfile);
return -1;
+ }
if (rename(tempfile->filename.buf, path)) {
int save_errno = errno;
if (!tempfile->active)
return;
- if (!close_tempfile(tempfile)) {
- unlink_or_warn(tempfile->filename.buf);
- tempfile->active = 0;
- strbuf_reset(&tempfile->filename);
- }
+ close_tempfile_gently(tempfile);
+ unlink_or_warn(tempfile->filename.buf);
+ tempfile->active = 0;
+ strbuf_reset(&tempfile->filename);
}
* control of the file.
*
* * Close the file descriptor without removing or renaming the
- * temporary file by calling `close_tempfile()`, and later call
+ * 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`
* and remove the temporary file.
*
* If you need to close the file descriptor yourself, do so by calling
- * `close_tempfile()`. You should never call `close(2)` or `fclose(3)`
+ * `close_tempfile_gently()`. You should never call `close(2)` or `fclose(3)`
* yourself, otherwise the `struct tempfile` structure would still
* think that the file descriptor needs to be closed, and a later
* cleanup would result in duplicate calls to `close(2)`. Worse yet,
* `create_tempfile()` returns a file descriptor on success or -1 on
* failure. On errors, `errno` describes the reason for failure.
*
- * `delete_tempfile()`, `rename_tempfile()`, and `close_tempfile()`
- * return 0 on success. On failure they set `errno` appropriately, do
- * their best to delete the temporary file, and return -1.
+ * `delete_tempfile()`, `rename_tempfile()`, and `close_tempfile_gently()`
+ * return 0 on success. On failure they set `errno` appropriately and return
+ * -1. `delete` and `rename` (but not `close`) do their best to delete the
+ * temporary file before returning.
*/
struct tempfile {
/*
* Associate a stdio stream with the temporary file (which must still
* be open). Return `NULL` (*without* deleting the file) on error. The
- * stream is closed automatically when `close_tempfile()` is called or
+ * stream is closed automatically when `close_tempfile_gently()` is called or
* when the file is deleted or renamed.
*/
extern FILE *fdopen_tempfile(struct tempfile *tempfile, const char *mode);
* If the temporary file is still open, close it (and the file pointer
* too, if it has been opened using `fdopen_tempfile()`) without
* deleting the file. Return 0 upon success. On failure to `close(2)`,
- * return a negative value and delete the file. Usually
- * `delete_tempfile()` or `rename_tempfile()` should eventually be
- * called if `close_tempfile()` succeeds.
+ * return a negative value. Usually `delete_tempfile()` or `rename_tempfile()`
+ * should eventually be called regardless of whether `close_tempfile_gently()`
+ * succeeds.
*/
-extern int close_tempfile(struct tempfile *tempfile);
+extern int close_tempfile_gently(struct tempfile *tempfile);
/*
* Re-open a temporary file that has been closed using
- * `close_tempfile()` but not yet deleted or renamed. This can be used
+ * `close_tempfile_gently()` but not yet deleted or renamed. This can be used
* to implement a sequence of operations like the following:
*
* * Create temporary file.
*
- * * Write new contents to file, then `close_tempfile()` to cause the
+ * * Write new contents to file, then `close_tempfile_gently()` to cause the
* contents to be written to disk.
*
* * Pass the name of the temporary file to another program to allow