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