Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 1 | #ifndef TEMPFILE_H |
| 2 | #define TEMPFILE_H |
| 3 | |
Jeff King | 24d8218 | 2017-09-05 08:15:00 -0400 | [diff] [blame] | 4 | #include "list.h" |
Elijah Newren | ef3ca95 | 2018-08-15 10:54:05 -0700 | [diff] [blame] | 5 | #include "strbuf.h" |
Jeff King | 24d8218 | 2017-09-05 08:15:00 -0400 | [diff] [blame] | 6 | |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 7 | /* |
| 8 | * Handle temporary files. |
| 9 | * |
| 10 | * The tempfile API allows temporary files to be created, deleted, and |
| 11 | * atomically renamed. Temporary files that are still active when the |
| 12 | * program ends are cleaned up automatically. Lockfiles (see |
| 13 | * "lockfile.h") are built on top of this API. |
| 14 | * |
| 15 | * |
| 16 | * Calling sequence |
| 17 | * ---------------- |
| 18 | * |
| 19 | * The caller: |
| 20 | * |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 21 | * * Attempts to create a temporary file by calling |
Jeff King | 076aa2c | 2017-09-05 08:15:08 -0400 | [diff] [blame] | 22 | * `create_tempfile()`. The resources used for the temporary file are |
| 23 | * managed by the tempfile API. |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 24 | * |
| 25 | * * Writes new content to the file by either: |
| 26 | * |
Jeff King | 076aa2c | 2017-09-05 08:15:08 -0400 | [diff] [blame] | 27 | * * writing to the `tempfile->fd` file descriptor |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 28 | * |
| 29 | * * calling `fdopen_tempfile()` to get a `FILE` pointer for the |
| 30 | * open file and writing to the file using stdio. |
| 31 | * |
Jeff King | 076aa2c | 2017-09-05 08:15:08 -0400 | [diff] [blame] | 32 | * Note that the file descriptor created by create_tempfile() |
Ben Wijen | 05d1ed6 | 2016-08-22 14:47:55 +0200 | [diff] [blame] | 33 | * is marked O_CLOEXEC, so the new contents must be written by |
| 34 | * the current process, not any spawned one. |
| 35 | * |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 36 | * When finished writing, the caller can: |
| 37 | * |
| 38 | * * Close the file descriptor and remove the temporary file by |
| 39 | * calling `delete_tempfile()`. |
| 40 | * |
| 41 | * * Close the temporary file and rename it atomically to a specified |
| 42 | * filename by calling `rename_tempfile()`. This relinquishes |
| 43 | * control of the file. |
| 44 | * |
| 45 | * * Close the file descriptor without removing or renaming the |
Jeff King | 49bd0fc | 2017-09-05 08:14:30 -0400 | [diff] [blame] | 46 | * temporary file by calling `close_tempfile_gently()`, and later call |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 47 | * `delete_tempfile()` or `rename_tempfile()`. |
| 48 | * |
Jeff King | 422a21c | 2017-09-05 08:15:04 -0400 | [diff] [blame] | 49 | * After the temporary file is renamed or deleted, the `tempfile` |
Jeff King | 076aa2c | 2017-09-05 08:15:08 -0400 | [diff] [blame] | 50 | * object is no longer valid and should not be reused. |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 51 | * |
| 52 | * If the program exits before `rename_tempfile()` or |
| 53 | * `delete_tempfile()` is called, an `atexit(3)` handler will close |
| 54 | * and remove the temporary file. |
| 55 | * |
| 56 | * If you need to close the file descriptor yourself, do so by calling |
Jeff King | 49bd0fc | 2017-09-05 08:14:30 -0400 | [diff] [blame] | 57 | * `close_tempfile_gently()`. You should never call `close(2)` or `fclose(3)` |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 58 | * yourself, otherwise the `struct tempfile` structure would still |
| 59 | * think that the file descriptor needs to be closed, and a later |
| 60 | * cleanup would result in duplicate calls to `close(2)`. Worse yet, |
| 61 | * if you close and then later open another file descriptor for a |
| 62 | * completely different purpose, then the unrelated file descriptor |
| 63 | * might get closed. |
| 64 | * |
| 65 | * |
| 66 | * Error handling |
| 67 | * -------------- |
| 68 | * |
Jeff King | 076aa2c | 2017-09-05 08:15:08 -0400 | [diff] [blame] | 69 | * `create_tempfile()` returns an allocated tempfile on success or NULL |
| 70 | * on failure. On errors, `errno` describes the reason for failure. |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 71 | * |
Martin Ågren | 5de134c | 2017-10-05 22:32:06 +0200 | [diff] [blame] | 72 | * `rename_tempfile()` and `close_tempfile_gently()` return 0 on success. |
| 73 | * On failure they set `errno` appropriately and return -1. |
| 74 | * `delete_tempfile()` and `rename` (but not `close`) do their best to |
| 75 | * delete the temporary file before returning. |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 76 | */ |
| 77 | |
| 78 | struct tempfile { |
Jeff King | 24d8218 | 2017-09-05 08:15:00 -0400 | [diff] [blame] | 79 | volatile struct volatile_list_head list; |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 80 | volatile int fd; |
| 81 | FILE *volatile fp; |
| 82 | volatile pid_t owner; |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 83 | struct strbuf filename; |
René Scharfe | babe2e0 | 2022-08-27 00:46:29 +0200 | [diff] [blame] | 84 | char *directory; |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 85 | }; |
| 86 | |
| 87 | /* |
| 88 | * Attempt to create a temporary file at the specified `path`. Return |
Jeff King | 076aa2c | 2017-09-05 08:15:08 -0400 | [diff] [blame] | 89 | * a tempfile (whose "fd" member can be used for writing to it), or |
| 90 | * NULL on error. It is an error if a file already exists at that path. |
Taylor Blau | bef0413 | 2020-04-27 10:27:54 -0600 | [diff] [blame] | 91 | * Note that `mode` will be further modified by the umask, and possibly |
| 92 | * `core.sharedRepository`, so it is not guaranteed to have the given |
| 93 | * mode. |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 94 | */ |
Taylor Blau | bef0413 | 2020-04-27 10:27:54 -0600 | [diff] [blame] | 95 | struct tempfile *create_tempfile_mode(const char *path, int mode); |
| 96 | |
| 97 | static inline struct tempfile *create_tempfile(const char *path) |
| 98 | { |
| 99 | return create_tempfile_mode(path, 0666); |
| 100 | } |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 101 | |
Michael Haggerty | 9939715 | 2015-08-10 11:47:44 +0200 | [diff] [blame] | 102 | /* |
| 103 | * Register an existing file as a tempfile, meaning that it will be |
| 104 | * deleted when the program exits. The tempfile is considered closed, |
| 105 | * but it can be worked with like any other closed tempfile (for |
| 106 | * example, it can be opened using reopen_tempfile()). |
| 107 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 108 | struct tempfile *register_tempfile(const char *path); |
Michael Haggerty | 9939715 | 2015-08-10 11:47:44 +0200 | [diff] [blame] | 109 | |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 110 | |
| 111 | /* |
| 112 | * mks_tempfile functions |
| 113 | * |
| 114 | * The following functions attempt to create and open temporary files |
| 115 | * with names derived automatically from a template, in the manner of |
| 116 | * mkstemps(), and arrange for them to be deleted if the program ends |
| 117 | * before they are deleted explicitly. There is a whole family of such |
| 118 | * functions, named according to the following pattern: |
| 119 | * |
| 120 | * x?mks_tempfile_t?s?m?() |
| 121 | * |
| 122 | * The optional letters have the following meanings: |
| 123 | * |
| 124 | * x - die if the temporary file cannot be created. |
| 125 | * |
| 126 | * t - create the temporary file under $TMPDIR (as opposed to |
| 127 | * relative to the current directory). When these variants are |
| 128 | * used, template should be the pattern for the filename alone, |
| 129 | * without a path. |
| 130 | * |
| 131 | * s - template includes a suffix that is suffixlen characters long. |
| 132 | * |
| 133 | * m - the temporary file should be created with the specified mode |
| 134 | * (otherwise, the mode is set to 0600). |
| 135 | * |
| 136 | * None of these functions modify template. If the caller wants to |
| 137 | * know the (absolute) path of the file that was created, it can be |
| 138 | * read from tempfile->filename. |
| 139 | * |
Jeff King | 076aa2c | 2017-09-05 08:15:08 -0400 | [diff] [blame] | 140 | * On success, the functions return a tempfile whose "fd" member is open |
| 141 | * for writing the temporary file. On errors, they return NULL and set |
| 142 | * errno appropriately (except for the "x" variants, which die() on |
| 143 | * errors). |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 144 | */ |
| 145 | |
| 146 | /* See "mks_tempfile functions" above. */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 147 | struct tempfile *mks_tempfile_sm(const char *filename_template, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 148 | int suffixlen, int mode); |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 149 | |
| 150 | /* See "mks_tempfile functions" above. */ |
Brandon Williams | ea8ace4 | 2018-02-14 10:59:57 -0800 | [diff] [blame] | 151 | static inline struct tempfile *mks_tempfile_s(const char *filename_template, |
Jeff King | 076aa2c | 2017-09-05 08:15:08 -0400 | [diff] [blame] | 152 | int suffixlen) |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 153 | { |
Brandon Williams | ea8ace4 | 2018-02-14 10:59:57 -0800 | [diff] [blame] | 154 | return mks_tempfile_sm(filename_template, suffixlen, 0600); |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 155 | } |
| 156 | |
| 157 | /* See "mks_tempfile functions" above. */ |
Brandon Williams | ea8ace4 | 2018-02-14 10:59:57 -0800 | [diff] [blame] | 158 | static inline struct tempfile *mks_tempfile_m(const char *filename_template, int mode) |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 159 | { |
Brandon Williams | ea8ace4 | 2018-02-14 10:59:57 -0800 | [diff] [blame] | 160 | return mks_tempfile_sm(filename_template, 0, mode); |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 161 | } |
| 162 | |
| 163 | /* See "mks_tempfile functions" above. */ |
Brandon Williams | ea8ace4 | 2018-02-14 10:59:57 -0800 | [diff] [blame] | 164 | static inline struct tempfile *mks_tempfile(const char *filename_template) |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 165 | { |
Brandon Williams | ea8ace4 | 2018-02-14 10:59:57 -0800 | [diff] [blame] | 166 | return mks_tempfile_sm(filename_template, 0, 0600); |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 167 | } |
| 168 | |
| 169 | /* See "mks_tempfile functions" above. */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 170 | struct tempfile *mks_tempfile_tsm(const char *filename_template, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 171 | int suffixlen, int mode); |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 172 | |
| 173 | /* See "mks_tempfile functions" above. */ |
Brandon Williams | ea8ace4 | 2018-02-14 10:59:57 -0800 | [diff] [blame] | 174 | static inline struct tempfile *mks_tempfile_ts(const char *filename_template, |
Jeff King | 076aa2c | 2017-09-05 08:15:08 -0400 | [diff] [blame] | 175 | int suffixlen) |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 176 | { |
Brandon Williams | ea8ace4 | 2018-02-14 10:59:57 -0800 | [diff] [blame] | 177 | return mks_tempfile_tsm(filename_template, suffixlen, 0600); |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 178 | } |
| 179 | |
| 180 | /* See "mks_tempfile functions" above. */ |
Brandon Williams | ea8ace4 | 2018-02-14 10:59:57 -0800 | [diff] [blame] | 181 | static inline struct tempfile *mks_tempfile_tm(const char *filename_template, int mode) |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 182 | { |
Brandon Williams | ea8ace4 | 2018-02-14 10:59:57 -0800 | [diff] [blame] | 183 | return mks_tempfile_tsm(filename_template, 0, mode); |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 184 | } |
| 185 | |
| 186 | /* See "mks_tempfile functions" above. */ |
Brandon Williams | ea8ace4 | 2018-02-14 10:59:57 -0800 | [diff] [blame] | 187 | static inline struct tempfile *mks_tempfile_t(const char *filename_template) |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 188 | { |
Brandon Williams | ea8ace4 | 2018-02-14 10:59:57 -0800 | [diff] [blame] | 189 | return mks_tempfile_tsm(filename_template, 0, 0600); |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 190 | } |
| 191 | |
| 192 | /* See "mks_tempfile functions" above. */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 193 | struct tempfile *xmks_tempfile_m(const char *filename_template, int mode); |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 194 | |
| 195 | /* See "mks_tempfile functions" above. */ |
Brandon Williams | ea8ace4 | 2018-02-14 10:59:57 -0800 | [diff] [blame] | 196 | static inline struct tempfile *xmks_tempfile(const char *filename_template) |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 197 | { |
Brandon Williams | ea8ace4 | 2018-02-14 10:59:57 -0800 | [diff] [blame] | 198 | return xmks_tempfile_m(filename_template, 0600); |
Michael Haggerty | 354ab11 | 2015-08-10 11:47:43 +0200 | [diff] [blame] | 199 | } |
| 200 | |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 201 | /* |
René Scharfe | 2c2db19 | 2022-04-20 22:26:09 +0200 | [diff] [blame] | 202 | * Attempt to create a temporary directory in $TMPDIR and to create and |
| 203 | * open a file in that new directory. Derive the directory name from the |
| 204 | * template in the manner of mkdtemp(). Arrange for directory and file |
| 205 | * to be deleted if the program exits before they are deleted |
| 206 | * explicitly. On success return a tempfile whose "filename" member |
| 207 | * contains the full path of the file and its "fd" member is open for |
| 208 | * writing the file. On error return NULL and set errno appropriately. |
| 209 | */ |
| 210 | struct tempfile *mks_tempfile_dt(const char *directory_template, |
| 211 | const char *filename); |
| 212 | |
| 213 | /* |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 214 | * Associate a stdio stream with the temporary file (which must still |
| 215 | * be open). Return `NULL` (*without* deleting the file) on error. The |
Jeff King | 49bd0fc | 2017-09-05 08:14:30 -0400 | [diff] [blame] | 216 | * stream is closed automatically when `close_tempfile_gently()` is called or |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 217 | * when the file is deleted or renamed. |
| 218 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 219 | FILE *fdopen_tempfile(struct tempfile *tempfile, const char *mode); |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 220 | |
| 221 | static inline int is_tempfile_active(struct tempfile *tempfile) |
| 222 | { |
Jeff King | 77a42b3 | 2022-08-30 15:45:06 -0400 | [diff] [blame] | 223 | return !!tempfile; |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 224 | } |
| 225 | |
| 226 | /* |
| 227 | * Return the path of the lockfile. The return value is a pointer to a |
| 228 | * field within the lock_file object and should not be freed. |
| 229 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 230 | const char *get_tempfile_path(struct tempfile *tempfile); |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 231 | |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 232 | int get_tempfile_fd(struct tempfile *tempfile); |
| 233 | FILE *get_tempfile_fp(struct tempfile *tempfile); |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 234 | |
| 235 | /* |
| 236 | * If the temporary file is still open, close it (and the file pointer |
| 237 | * too, if it has been opened using `fdopen_tempfile()`) without |
| 238 | * deleting the file. Return 0 upon success. On failure to `close(2)`, |
Jeff King | 49bd0fc | 2017-09-05 08:14:30 -0400 | [diff] [blame] | 239 | * return a negative value. Usually `delete_tempfile()` or `rename_tempfile()` |
| 240 | * should eventually be called regardless of whether `close_tempfile_gently()` |
| 241 | * succeeds. |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 242 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 243 | int close_tempfile_gently(struct tempfile *tempfile); |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 244 | |
| 245 | /* |
| 246 | * Re-open a temporary file that has been closed using |
Jeff King | 49bd0fc | 2017-09-05 08:14:30 -0400 | [diff] [blame] | 247 | * `close_tempfile_gently()` but not yet deleted or renamed. This can be used |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 248 | * to implement a sequence of operations like the following: |
| 249 | * |
| 250 | * * Create temporary file. |
| 251 | * |
Jeff King | 49bd0fc | 2017-09-05 08:14:30 -0400 | [diff] [blame] | 252 | * * Write new contents to file, then `close_tempfile_gently()` to cause the |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 253 | * contents to be written to disk. |
| 254 | * |
| 255 | * * Pass the name of the temporary file to another program to allow |
| 256 | * it (and nobody else) to inspect or even modify the file's |
| 257 | * contents. |
| 258 | * |
Jeff King | 6c003d6 | 2018-09-04 19:36:43 -0400 | [diff] [blame] | 259 | * * `reopen_tempfile()` to reopen the temporary file, truncating the existing |
| 260 | * contents. Write out the new contents. |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 261 | * |
| 262 | * * `rename_tempfile()` to move the file to its permanent location. |
| 263 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 264 | int reopen_tempfile(struct tempfile *tempfile); |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 265 | |
| 266 | /* |
| 267 | * Close the file descriptor and/or file pointer and remove the |
| 268 | * temporary file associated with `tempfile`. It is a NOOP to call |
| 269 | * `delete_tempfile()` for a `tempfile` object that has already been |
| 270 | * deleted or renamed. |
| 271 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 272 | void delete_tempfile(struct tempfile **tempfile_p); |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 273 | |
| 274 | /* |
| 275 | * Close the file descriptor and/or file pointer if they are still |
| 276 | * open, and atomically rename the temporary file to `path`. `path` |
| 277 | * must be on the same filesystem as the lock file. Return 0 on |
| 278 | * success. On failure, delete the temporary file and return -1, with |
| 279 | * `errno` set to the value from the failing call to `close(2)` or |
| 280 | * `rename(2)`. It is a bug to call `rename_tempfile()` for a |
| 281 | * `tempfile` object that is not currently active. |
| 282 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 283 | int rename_tempfile(struct tempfile **tempfile_p, const char *path); |
Michael Haggerty | 1a9d15d | 2015-08-10 11:47:41 +0200 | [diff] [blame] | 284 | |
| 285 | #endif /* TEMPFILE_H */ |