tempfile: add several functions for creating temporary files
Add several functions for creating temporary files with automatically-generated names, analogous to mkstemps(), but also arranging for the files to be deleted on program exit. The functions are named according to a pattern depending how they operate. They will be used to replace many places in the code where temporary files are created and cleaned up ad-hoc. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Michael Haggerty committed
Aug 10, 2015 at 11:47 UTC
354ab1120665f691c17b21fdb04c4362c8088dfa
2 files changed
+149
tempfile.c
+53
@@ -137,6 +137,59 @@ int create_tempfile(struct tempfile *tempfile, const char *path)
137
return tempfile->fd;
138
}
139
140
+int mks_tempfile_sm(struct tempfile *tempfile,
141
+ const char *template, int suffixlen, int mode)
142
+{
143
+ prepare_tempfile_object(tempfile);
144
+
145
+ strbuf_add_absolute_path(&tempfile->filename, template);
146
+ tempfile->fd = git_mkstemps_mode(tempfile->filename.buf, suffixlen, mode);
147
+ if (tempfile->fd < 0) {
148
+ strbuf_reset(&tempfile->filename);
149
+ return -1;
150
+ }
151
+ tempfile->owner = getpid();
152
+ tempfile->active = 1;
153
+ return tempfile->fd;
154
+}
155
+
156
+int mks_tempfile_tsm(struct tempfile *tempfile,
157
+ const char *template, int suffixlen, int mode)
158
+{
159
+ const char *tmpdir;
160
+
161
+ prepare_tempfile_object(tempfile);
162
+
163
+ tmpdir = getenv("TMPDIR");
164
+ if (!tmpdir)
165
+ tmpdir = "/tmp";
166
+
167
+ strbuf_addf(&tempfile->filename, "%s/%s", tmpdir, template);
168
+ tempfile->fd = git_mkstemps_mode(tempfile->filename.buf, suffixlen, mode);
169
+ if (tempfile->fd < 0) {
170
+ strbuf_reset(&tempfile->filename);
171
+ return -1;
172
+ }
173
+ tempfile->owner = getpid();
174
+ tempfile->active = 1;
175
+ return tempfile->fd;
176
+}
177
+
178
+int xmks_tempfile_m(struct tempfile *tempfile, const char *template, int mode)
179
+{
180
+ int fd;
181
+ struct strbuf full_template = STRBUF_INIT;
182
+
183
+ strbuf_add_absolute_path(&full_template, template);
184
+ fd = mks_tempfile_m(tempfile, full_template.buf, mode);
185
+ if (fd < 0)
186
+ die_errno("Unable to create temporary file '%s'",
187
+ full_template.buf);
188
+
189
+ strbuf_release(&full_template);
190
+ return fd;
191
+}
192
+
193
FILE *fdopen_tempfile(struct tempfile *tempfile, const char *mode)
194
{
195
if (!tempfile->active)
tempfile.h
+96
@@ -92,6 +92,102 @@ struct tempfile {
92
*/
93
extern int create_tempfile(struct tempfile *tempfile, const char *path);
94
95
+
96
+/*
97
+ * mks_tempfile functions
98
+ *
99
+ * The following functions attempt to create and open temporary files
100
+ * with names derived automatically from a template, in the manner of
101
+ * mkstemps(), and arrange for them to be deleted if the program ends
102
+ * before they are deleted explicitly. There is a whole family of such
103
+ * functions, named according to the following pattern:
104
+ *
105
+ * x?mks_tempfile_t?s?m?()
106
+ *
107
+ * The optional letters have the following meanings:
108
+ *
109
+ * x - die if the temporary file cannot be created.
110
+ *
111
+ * t - create the temporary file under $TMPDIR (as opposed to
112
+ * relative to the current directory). When these variants are
113
+ * used, template should be the pattern for the filename alone,
114
+ * without a path.
115
+ *
116
+ * s - template includes a suffix that is suffixlen characters long.
117
+ *
118
+ * m - the temporary file should be created with the specified mode
119
+ * (otherwise, the mode is set to 0600).
120
+ *
121
+ * None of these functions modify template. If the caller wants to
122
+ * know the (absolute) path of the file that was created, it can be
123
+ * read from tempfile->filename.
124
+ *
125
+ * On success, the functions return a file descriptor that is open for
126
+ * writing the temporary file. On errors, they return -1 and set errno
127
+ * appropriately (except for the "x" variants, which die() on errors).
128
+ */
129
+
130
+/* See "mks_tempfile functions" above. */
131
+extern int mks_tempfile_sm(struct tempfile *tempfile,
132
+ const char *template, int suffixlen, int mode);
133
+
134
+/* See "mks_tempfile functions" above. */
135
+static inline int mks_tempfile_s(struct tempfile *tempfile,
136
+ const char *template, int suffixlen)
137
+{
138
+ return mks_tempfile_sm(tempfile, template, suffixlen, 0600);
139
+}
140
+
141
+/* See "mks_tempfile functions" above. */
142
+static inline int mks_tempfile_m(struct tempfile *tempfile,
143
+ const char *template, int mode)
144
+{
145
+ return mks_tempfile_sm(tempfile, template, 0, mode);
146
+}
147
+
148
+/* See "mks_tempfile functions" above. */
149
+static inline int mks_tempfile(struct tempfile *tempfile,
150
+ const char *template)
151
+{
152
+ return mks_tempfile_sm(tempfile, template, 0, 0600);
153
+}
154
+
155
+/* See "mks_tempfile functions" above. */
156
+extern int mks_tempfile_tsm(struct tempfile *tempfile,
157
+ const char *template, int suffixlen, int mode);
158
+
159
+/* See "mks_tempfile functions" above. */
160
+static inline int mks_tempfile_ts(struct tempfile *tempfile,
161
+ const char *template, int suffixlen)
162
+{
163
+ return mks_tempfile_tsm(tempfile, template, suffixlen, 0600);
164
+}
165
+
166
+/* See "mks_tempfile functions" above. */
167
+static inline int mks_tempfile_tm(struct tempfile *tempfile,
168
+ const char *template, int mode)
169
+{
170
+ return mks_tempfile_tsm(tempfile, template, 0, mode);
171
+}
172
+
173
+/* See "mks_tempfile functions" above. */
174
+static inline int mks_tempfile_t(struct tempfile *tempfile,
175
+ const char *template)
176
+{
177
+ return mks_tempfile_tsm(tempfile, template, 0, 0600);
178
+}
179
+
180
+/* See "mks_tempfile functions" above. */
181
+extern int xmks_tempfile_m(struct tempfile *tempfile,
182
+ const char *template, int mode);
183
+
184
+/* See "mks_tempfile functions" above. */
185
+static inline int xmks_tempfile(struct tempfile *tempfile,
186
+ const char *template)
187
+{
188
+ return xmks_tempfile_m(tempfile, template, 0600);
189
+}
190
+
191
/*
192
* Associate a stdio stream with the temporary file (which must still
193
* be open). Return `NULL` (*without* deleting the file) on error. The