зеркало из https://github.com/microsoft/git.git
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>
This commit is contained in:
Родитель
7eba6ce5c7
Коммит
354ab11206
53
tempfile.c
53
tempfile.c
|
@ -137,6 +137,59 @@ int create_tempfile(struct tempfile *tempfile, const char *path)
|
||||||
return tempfile->fd;
|
return tempfile->fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mks_tempfile_sm(struct tempfile *tempfile,
|
||||||
|
const char *template, int suffixlen, int mode)
|
||||||
|
{
|
||||||
|
prepare_tempfile_object(tempfile);
|
||||||
|
|
||||||
|
strbuf_add_absolute_path(&tempfile->filename, template);
|
||||||
|
tempfile->fd = git_mkstemps_mode(tempfile->filename.buf, suffixlen, mode);
|
||||||
|
if (tempfile->fd < 0) {
|
||||||
|
strbuf_reset(&tempfile->filename);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tempfile->owner = getpid();
|
||||||
|
tempfile->active = 1;
|
||||||
|
return tempfile->fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mks_tempfile_tsm(struct tempfile *tempfile,
|
||||||
|
const char *template, int suffixlen, int mode)
|
||||||
|
{
|
||||||
|
const char *tmpdir;
|
||||||
|
|
||||||
|
prepare_tempfile_object(tempfile);
|
||||||
|
|
||||||
|
tmpdir = getenv("TMPDIR");
|
||||||
|
if (!tmpdir)
|
||||||
|
tmpdir = "/tmp";
|
||||||
|
|
||||||
|
strbuf_addf(&tempfile->filename, "%s/%s", tmpdir, template);
|
||||||
|
tempfile->fd = git_mkstemps_mode(tempfile->filename.buf, suffixlen, mode);
|
||||||
|
if (tempfile->fd < 0) {
|
||||||
|
strbuf_reset(&tempfile->filename);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tempfile->owner = getpid();
|
||||||
|
tempfile->active = 1;
|
||||||
|
return tempfile->fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xmks_tempfile_m(struct tempfile *tempfile, const char *template, int mode)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct strbuf full_template = STRBUF_INIT;
|
||||||
|
|
||||||
|
strbuf_add_absolute_path(&full_template, template);
|
||||||
|
fd = mks_tempfile_m(tempfile, full_template.buf, mode);
|
||||||
|
if (fd < 0)
|
||||||
|
die_errno("Unable to create temporary file '%s'",
|
||||||
|
full_template.buf);
|
||||||
|
|
||||||
|
strbuf_release(&full_template);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
FILE *fdopen_tempfile(struct tempfile *tempfile, const char *mode)
|
FILE *fdopen_tempfile(struct tempfile *tempfile, const char *mode)
|
||||||
{
|
{
|
||||||
if (!tempfile->active)
|
if (!tempfile->active)
|
||||||
|
|
96
tempfile.h
96
tempfile.h
|
@ -92,6 +92,102 @@ struct tempfile {
|
||||||
*/
|
*/
|
||||||
extern int create_tempfile(struct tempfile *tempfile, const char *path);
|
extern int create_tempfile(struct tempfile *tempfile, const char *path);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mks_tempfile functions
|
||||||
|
*
|
||||||
|
* The following functions attempt to create and open temporary files
|
||||||
|
* with names derived automatically from a template, in the manner of
|
||||||
|
* mkstemps(), and arrange for them to be deleted if the program ends
|
||||||
|
* before they are deleted explicitly. There is a whole family of such
|
||||||
|
* functions, named according to the following pattern:
|
||||||
|
*
|
||||||
|
* x?mks_tempfile_t?s?m?()
|
||||||
|
*
|
||||||
|
* The optional letters have the following meanings:
|
||||||
|
*
|
||||||
|
* x - die if the temporary file cannot be created.
|
||||||
|
*
|
||||||
|
* t - create the temporary file under $TMPDIR (as opposed to
|
||||||
|
* relative to the current directory). When these variants are
|
||||||
|
* used, template should be the pattern for the filename alone,
|
||||||
|
* without a path.
|
||||||
|
*
|
||||||
|
* s - template includes a suffix that is suffixlen characters long.
|
||||||
|
*
|
||||||
|
* m - the temporary file should be created with the specified mode
|
||||||
|
* (otherwise, the mode is set to 0600).
|
||||||
|
*
|
||||||
|
* None of these functions modify template. If the caller wants to
|
||||||
|
* know the (absolute) path of the file that was created, it can be
|
||||||
|
* read from tempfile->filename.
|
||||||
|
*
|
||||||
|
* On success, the functions return a file descriptor that is open for
|
||||||
|
* writing the temporary file. On errors, they return -1 and set errno
|
||||||
|
* appropriately (except for the "x" variants, which die() on errors).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* See "mks_tempfile functions" above. */
|
||||||
|
extern int mks_tempfile_sm(struct tempfile *tempfile,
|
||||||
|
const char *template, int suffixlen, int mode);
|
||||||
|
|
||||||
|
/* See "mks_tempfile functions" above. */
|
||||||
|
static inline int mks_tempfile_s(struct tempfile *tempfile,
|
||||||
|
const char *template, int suffixlen)
|
||||||
|
{
|
||||||
|
return mks_tempfile_sm(tempfile, template, suffixlen, 0600);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See "mks_tempfile functions" above. */
|
||||||
|
static inline int mks_tempfile_m(struct tempfile *tempfile,
|
||||||
|
const char *template, int mode)
|
||||||
|
{
|
||||||
|
return mks_tempfile_sm(tempfile, template, 0, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See "mks_tempfile functions" above. */
|
||||||
|
static inline int mks_tempfile(struct tempfile *tempfile,
|
||||||
|
const char *template)
|
||||||
|
{
|
||||||
|
return mks_tempfile_sm(tempfile, template, 0, 0600);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See "mks_tempfile functions" above. */
|
||||||
|
extern int mks_tempfile_tsm(struct tempfile *tempfile,
|
||||||
|
const char *template, int suffixlen, int mode);
|
||||||
|
|
||||||
|
/* See "mks_tempfile functions" above. */
|
||||||
|
static inline int mks_tempfile_ts(struct tempfile *tempfile,
|
||||||
|
const char *template, int suffixlen)
|
||||||
|
{
|
||||||
|
return mks_tempfile_tsm(tempfile, template, suffixlen, 0600);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See "mks_tempfile functions" above. */
|
||||||
|
static inline int mks_tempfile_tm(struct tempfile *tempfile,
|
||||||
|
const char *template, int mode)
|
||||||
|
{
|
||||||
|
return mks_tempfile_tsm(tempfile, template, 0, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See "mks_tempfile functions" above. */
|
||||||
|
static inline int mks_tempfile_t(struct tempfile *tempfile,
|
||||||
|
const char *template)
|
||||||
|
{
|
||||||
|
return mks_tempfile_tsm(tempfile, template, 0, 0600);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See "mks_tempfile functions" above. */
|
||||||
|
extern int xmks_tempfile_m(struct tempfile *tempfile,
|
||||||
|
const char *template, int mode);
|
||||||
|
|
||||||
|
/* See "mks_tempfile functions" above. */
|
||||||
|
static inline int xmks_tempfile(struct tempfile *tempfile,
|
||||||
|
const char *template)
|
||||||
|
{
|
||||||
|
return xmks_tempfile_m(tempfile, template, 0600);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Associate a stdio stream with the temporary file (which must still
|
* Associate a stdio stream with the temporary file (which must still
|
||||||
* be open). Return `NULL` (*without* deleting the file) on error. The
|
* be open). Return `NULL` (*without* deleting the file) on error. The
|
||||||
|
|
Загрузка…
Ссылка в новой задаче