mirror of
https://github.com/git/git.git
synced 2024-05-05 07:06:34 +02:00
tempfile: add mks_tempfile_dt()
Add a function to create a temporary file with a certain name in a temporary directory created using mkdtemp(3). Its result is more sightly than the paths created by mks_tempfile_ts(), which include a random prefix. That's useful for files passed to a program that displays their name, e.g. an external diff tool. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
6cd33dceed
commit
2c2db194bd
63
tempfile.c
63
tempfile.c
|
@ -56,6 +56,20 @@
|
||||||
|
|
||||||
static VOLATILE_LIST_HEAD(tempfile_list);
|
static VOLATILE_LIST_HEAD(tempfile_list);
|
||||||
|
|
||||||
|
static void remove_template_directory(struct tempfile *tempfile,
|
||||||
|
int in_signal_handler)
|
||||||
|
{
|
||||||
|
if (tempfile->directorylen > 0 &&
|
||||||
|
tempfile->directorylen < tempfile->filename.len &&
|
||||||
|
tempfile->filename.buf[tempfile->directorylen] == '/') {
|
||||||
|
strbuf_setlen(&tempfile->filename, tempfile->directorylen);
|
||||||
|
if (in_signal_handler)
|
||||||
|
rmdir(tempfile->filename.buf);
|
||||||
|
else
|
||||||
|
rmdir_or_warn(tempfile->filename.buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void remove_tempfiles(int in_signal_handler)
|
static void remove_tempfiles(int in_signal_handler)
|
||||||
{
|
{
|
||||||
pid_t me = getpid();
|
pid_t me = getpid();
|
||||||
|
@ -74,6 +88,7 @@ static void remove_tempfiles(int in_signal_handler)
|
||||||
unlink(p->filename.buf);
|
unlink(p->filename.buf);
|
||||||
else
|
else
|
||||||
unlink_or_warn(p->filename.buf);
|
unlink_or_warn(p->filename.buf);
|
||||||
|
remove_template_directory(p, in_signal_handler);
|
||||||
|
|
||||||
p->active = 0;
|
p->active = 0;
|
||||||
}
|
}
|
||||||
|
@ -100,6 +115,7 @@ static struct tempfile *new_tempfile(void)
|
||||||
tempfile->owner = 0;
|
tempfile->owner = 0;
|
||||||
INIT_LIST_HEAD(&tempfile->list);
|
INIT_LIST_HEAD(&tempfile->list);
|
||||||
strbuf_init(&tempfile->filename, 0);
|
strbuf_init(&tempfile->filename, 0);
|
||||||
|
tempfile->directorylen = 0;
|
||||||
return tempfile;
|
return tempfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,6 +214,52 @@ struct tempfile *mks_tempfile_tsm(const char *filename_template, int suffixlen,
|
||||||
return tempfile;
|
return tempfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct tempfile *mks_tempfile_dt(const char *directory_template,
|
||||||
|
const char *filename)
|
||||||
|
{
|
||||||
|
struct tempfile *tempfile;
|
||||||
|
const char *tmpdir;
|
||||||
|
struct strbuf sb = STRBUF_INIT;
|
||||||
|
int fd;
|
||||||
|
size_t directorylen;
|
||||||
|
|
||||||
|
if (!ends_with(directory_template, "XXXXXX")) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpdir = getenv("TMPDIR");
|
||||||
|
if (!tmpdir)
|
||||||
|
tmpdir = "/tmp";
|
||||||
|
|
||||||
|
strbuf_addf(&sb, "%s/%s", tmpdir, directory_template);
|
||||||
|
directorylen = sb.len;
|
||||||
|
if (!mkdtemp(sb.buf)) {
|
||||||
|
int orig_errno = errno;
|
||||||
|
strbuf_release(&sb);
|
||||||
|
errno = orig_errno;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
strbuf_addf(&sb, "/%s", filename);
|
||||||
|
fd = open(sb.buf, O_CREAT | O_EXCL | O_RDWR, 0600);
|
||||||
|
if (fd < 0) {
|
||||||
|
int orig_errno = errno;
|
||||||
|
strbuf_setlen(&sb, directorylen);
|
||||||
|
rmdir(sb.buf);
|
||||||
|
strbuf_release(&sb);
|
||||||
|
errno = orig_errno;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tempfile = new_tempfile();
|
||||||
|
strbuf_swap(&tempfile->filename, &sb);
|
||||||
|
tempfile->directorylen = directorylen;
|
||||||
|
tempfile->fd = fd;
|
||||||
|
activate_tempfile(tempfile);
|
||||||
|
return tempfile;
|
||||||
|
}
|
||||||
|
|
||||||
struct tempfile *xmks_tempfile_m(const char *filename_template, int mode)
|
struct tempfile *xmks_tempfile_m(const char *filename_template, int mode)
|
||||||
{
|
{
|
||||||
struct tempfile *tempfile;
|
struct tempfile *tempfile;
|
||||||
|
@ -316,6 +378,7 @@ void delete_tempfile(struct tempfile **tempfile_p)
|
||||||
|
|
||||||
close_tempfile_gently(tempfile);
|
close_tempfile_gently(tempfile);
|
||||||
unlink_or_warn(tempfile->filename.buf);
|
unlink_or_warn(tempfile->filename.buf);
|
||||||
|
remove_template_directory(tempfile, 0);
|
||||||
deactivate_tempfile(tempfile);
|
deactivate_tempfile(tempfile);
|
||||||
*tempfile_p = NULL;
|
*tempfile_p = NULL;
|
||||||
}
|
}
|
||||||
|
|
13
tempfile.h
13
tempfile.h
|
@ -82,6 +82,7 @@ struct tempfile {
|
||||||
FILE *volatile fp;
|
FILE *volatile fp;
|
||||||
volatile pid_t owner;
|
volatile pid_t owner;
|
||||||
struct strbuf filename;
|
struct strbuf filename;
|
||||||
|
size_t directorylen;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -198,6 +199,18 @@ static inline struct tempfile *xmks_tempfile(const char *filename_template)
|
||||||
return xmks_tempfile_m(filename_template, 0600);
|
return xmks_tempfile_m(filename_template, 0600);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attempt to create a temporary directory in $TMPDIR and to create and
|
||||||
|
* open a file in that new directory. Derive the directory name from the
|
||||||
|
* template in the manner of mkdtemp(). Arrange for directory and file
|
||||||
|
* to be deleted if the program exits before they are deleted
|
||||||
|
* explicitly. On success return a tempfile whose "filename" member
|
||||||
|
* contains the full path of the file and its "fd" member is open for
|
||||||
|
* writing the file. On error return NULL and set errno appropriately.
|
||||||
|
*/
|
||||||
|
struct tempfile *mks_tempfile_dt(const char *directory_template,
|
||||||
|
const char *filename);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
|
|
Loading…
Reference in New Issue