git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Michael Haggerty <mhagger@alum.mit.edu>
To: Junio C Hamano <gitster@pobox.com>
Cc: Johannes Sixt <j6t@kdbg.org>,
	git@vger.kernel.org, Michael Haggerty <mhagger@alum.mit.edu>
Subject: [PATCH v2 08/16] tempfile: add several functions for creating temporary files
Date: Mon, 10 Aug 2015 11:47:43 +0200	[thread overview]
Message-ID: <c4da9c1988388b25d2c140b4dbd9c39a212790d9.1439198011.git.mhagger@alum.mit.edu> (raw)
In-Reply-To: <cover.1439198011.git.mhagger@alum.mit.edu>

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>
---
 tempfile.c | 53 ++++++++++++++++++++++++++++++++++
 tempfile.h | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 149 insertions(+)

diff --git a/tempfile.c b/tempfile.c
index d840f04..0b5d8ce 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 bcc229f..a30e12c 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
-- 
2.5.0

  parent reply	other threads:[~2015-08-10  9:48 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-10  9:47 [PATCH v2 00/16] Introduce a tempfile module Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 01/16] Move lockfile documentation to lockfile.h and lockfile.c Michael Haggerty
2015-08-11 19:27   ` Junio C Hamano
2015-08-10  9:47 ` [PATCH v2 02/16] create_bundle(): duplicate file descriptor to avoid closing it twice Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 03/16] lockfile: add accessors get_lock_file_fd() and get_lock_file_fp() Michael Haggerty
2015-08-11 19:29   ` Junio C Hamano
2015-08-10  9:47 ` [PATCH v2 04/16] lockfile: add accessor get_lock_file_path() Michael Haggerty
2015-08-11 19:36   ` Junio C Hamano
2015-08-10  9:47 ` [PATCH v2 05/16] commit_lock_file(): use get_locked_file_path() Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 06/16] tempfile: a new module for handling temporary files Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 07/16] prepare_tempfile_object(): new function, extracted from create_tempfile() Michael Haggerty
2015-08-11 19:38   ` Junio C Hamano
2015-08-10  9:47 ` Michael Haggerty [this message]
2015-08-10  9:47 ` [PATCH v2 09/16] register_tempfile(): new function to handle an existing temporary file Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 10/16] write_shared_index(): use tempfile module Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 11/16] setup_temporary_shallow(): " Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 12/16] diff: " Michael Haggerty
2015-08-11 20:03   ` Junio C Hamano
2015-08-12 15:13     ` Michael Haggerty
2015-08-12 16:41       ` Junio C Hamano
2015-08-12 17:12         ` [PATCH v2' " Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 13/16] lock_repo_for_gc(): compute the path to "gc.pid" only once Michael Haggerty
2015-08-11 20:06   ` Junio C Hamano
2015-08-11 20:20     ` Junio C Hamano
2015-08-10  9:47 ` [PATCH v2 14/16] gc: use tempfile module to handle gc.pid file Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 15/16] credential-cache--daemon: delete socket from main() Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 16/16] credential-cache--daemon: use tempfile module Michael Haggerty
2015-08-11 20:21 ` [PATCH v2 00/16] Introduce a " Junio C Hamano
2015-08-12 15:14   ` Michael Haggerty

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c4da9c1988388b25d2c140b4dbd9c39a212790d9.1439198011.git.mhagger@alum.mit.edu \
    --to=mhagger@alum.mit.edu \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=j6t@kdbg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).