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