summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Haggerty <mhagger@alum.mit.edu>2015-08-10 11:47:43 +0200
committerJunio C Hamano <gitster@pobox.com>2015-08-10 12:57:14 -0700
commit354ab1120665f691c17b21fdb04c4362c8088dfa (patch)
tree834868915e64ab1df72cee35700aed5dcf079fef
parent7eba6ce5c79447579689218d8dab59a8434fd7c7 (diff)
downloadgit-354ab1120665f691c17b21fdb04c4362c8088dfa.tar.gz
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>
-rw-r--r--tempfile.c53
-rw-r--r--tempfile.h96
2 files changed, 149 insertions, 0 deletions
diff --git a/tempfile.c b/tempfile.c
index d840f0452a..0b5d8ce929 100644
--- a/tempfile.c
+++ b/tempfile.c
@@ -137,6 +137,59 @@ int create_tempfile(struct tempfile *tempfile, const char *path)
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)
{
if (!tempfile->active)
diff --git a/tempfile.h b/tempfile.h
index bcc229f9f3..a30e12c7e5 100644
--- a/tempfile.h
+++ b/tempfile.h
@@ -92,6 +92,102 @@ struct tempfile {
*/
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
* be open). Return `NULL` (*without* deleting the file) on error. The