Skip to content

Commit 354ab11

Browse files
mhaggergitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7eba6ce commit 354ab11

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed

tempfile.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,59 @@ int create_tempfile(struct tempfile *tempfile, const char *path)
137137
return tempfile->fd;
138138
}
139139

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+
140193
FILE *fdopen_tempfile(struct tempfile *tempfile, const char *mode)
141194
{
142195
if (!tempfile->active)

tempfile.h

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,102 @@ struct tempfile {
9292
*/
9393
extern int create_tempfile(struct tempfile *tempfile, const char *path);
9494

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+
95191
/*
96192
* Associate a stdio stream with the temporary file (which must still
97193
* be open). Return `NULL` (*without* deleting the file) on error. The

0 commit comments

Comments
 (0)