All of lore.kernel.org
 help / color / mirror / Atom feed
From: Drew Northup <n1xim.email@gmail.com>
To: Drew Northup <n1xim.email@gmail.com>
Cc: git@vger.kernel.org, David Aguilar <davvid@gmail.com>,
	Junio C Hamano <gitster@pobox.com>, Johannes Sixt <j6t@kdbg.org>,
	Jonas Fonseca <fonseca@diku.dk>
Subject: Re: [PATCH] TIG: Implement mkstemps() work-around for platforms lacking it
Date: Thu, 18 Jul 2013 00:45:23 -0400	[thread overview]
Message-ID: <51E772E3.20008@gmail.com> (raw)
In-Reply-To: <1373383992-4298-1-git-send-email-n1xim.email@gmail.com>

Giving this one last kick to make absolutely sure that nobody disagrees
with allowing this code to be included into tig, which does not limit
to a specific version of the GPL (version 2 in the case of git, any
version equal to or newer than 2 in the case of tig), pursuant to
paragraph 9 of said license.

On 07/09/2013 11:33 AM, Drew Northup wrote:
> The function mkstemps() isn't available in all libc implementations. In
> glibc it first became available in 2.11, so platforms such as RHEL 5&
> Slackware 13 lack it. This is likely true of many non-LINUX platforms
> as well.
>
> This fixes breakage that was introduced with a0fdac29 "Create temporary
> file with name as suffix."
>
> Signed-off-by: Drew Northup<n1xim.email@gmail.com>
> ---
>
> This work-around is taken from Git and was inspired by code in libiberty.
> It is presumed that this isn't a problem due to compatible license terms.
>
> A (virtually identical) version of this available in
> https://github.com/n1xim/tig/tree/mkstemps_wkarnd (differences only in
> the commit message).
>
>   configure.ac |  4 ++++
>   io.c         | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   io.h         | 14 +++++++++++
>   3 files changed, 95 insertions(+)
>
> diff --git a/configure.ac b/configure.ac
> index 8dd2508..40e1f85 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -21,6 +21,10 @@ AC_SUBST(CURSES_LIB)
>
>   AM_ICONV
>
> +dnl  Not all platforms have mkstemps
> +AC_CHECK_FUNC([mkstemps], [AC_DEFINE([HAVE_MKSTEMPS], [1],
> +	      [Define if mkstemps is available.])])
> +
>   AC_PROG_CC
>
>   AC_CHECK_PROGS(ASCIIDOC, [asciidoc], [false])
> diff --git a/io.c b/io.c
> index 3ff1d1c..f1b6fbc 100644
> --- a/io.c
> +++ b/io.c
> @@ -237,6 +237,83 @@ encoding_convert(struct encoding *encoding, char *line)
>   }
>
>   /*
> + * Compatibility: no mkstemps()
> + */
> +
> +/* Adapted from libiberty's mkstemp.c via Git's wrapper.c. */
> +
> +#undef TMP_MAX
> +#define TMP_MAX 16384
> +
> +int tig_mkstemps_mode(char *pattern, int suffix_len, int mode)
> +{
> +	static const char letters[] =
> +		"abcdefghijklmnopqrstuvwxyz"
> +		"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
> +		"0123456789";
> +	static const int num_letters = 62;
> +	uint64_t value;
> +	struct timeval tv;
> +	char *template;
> +	size_t len;
> +	int fd, count;
> +
> +	len = strlen(pattern);
> +
> +	if (len<  6 + suffix_len) {
> +		errno = EINVAL;
> +		return -1;
> +	}
> +
> +	if (strncmp(&pattern[len - 6 - suffix_len], "XXXXXX", 6)) {
> +		errno = EINVAL;
> +		return -1;
> +	}
> +
> +	/*
> +	 * Replace pattern's XXXXXX characters with randomness.
> +	 * Try TMP_MAX different filenames.
> +	 */
> +	gettimeofday(&tv, NULL);
> +	value = ((size_t)(tv.tv_usec<<  16)) ^ tv.tv_sec ^ getpid();
> +	template =&pattern[len - 6 - suffix_len];
> +	for (count = 0; count<  TMP_MAX; ++count) {
> +		uint64_t v = value;
> +		/* Fill in the random bits. */
> +		template[0] = letters[v % num_letters]; v /= num_letters;
> +		template[1] = letters[v % num_letters]; v /= num_letters;
> +		template[2] = letters[v % num_letters]; v /= num_letters;
> +		template[3] = letters[v % num_letters]; v /= num_letters;
> +		template[4] = letters[v % num_letters]; v /= num_letters;
> +		template[5] = letters[v % num_letters]; v /= num_letters;
> +
> +		fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode);
> +		if (fd>  0)
> +			return fd;
> +		/*
> +		 * Fatal error (EPERM, ENOSPC etc).
> +		 * It doesn't make sense to loop.
> +		 */
> +		if (errno != EEXIST)
> +			break;
> +		/*
> +		 * This is a random value.  It is only necessary that
> +		 * the next TMP_MAX values generated by adding 7777 to
> +		 * VALUE are different with (module 2^32).
> +		 */
> +		value += 7777;
> +	}
> +	/* We return the null string if we can't find a unique file name.  */
> +	pattern[0] = '\0';
> +	return -1;
> +}
> +
> +int tigmkstemps(char *pattern, int suffix_len)
> +{
> +	return tig_mkstemps_mode(pattern, suffix_len, 0600);
> +}
> +
> +/*
>    * Executing external commands.
>    */
>
> diff --git a/io.h b/io.h
> index 646989d..8f43216 100644
> --- a/io.h
> +++ b/io.h
> @@ -16,6 +16,9 @@
>
>   #include "tig.h"
>
> +/* Needed for mkstemps workaround */
> +#include<stdint.h>
> +
>   /*
>    * Argument array helpers.
>    */
> @@ -41,6 +44,17 @@ struct encoding *encoding_open(const char *fromcode);
>   char *encoding_convert(struct encoding *encoding, char *line);
>
>   /*
> + * Compatibility: no mkstemps()
> + */
> +
> +#ifndef HAVE_MKSTEMPS
> +#define mkstemps tigmkstemps
> +#endif
> +
> +int tigmkstemps(char *, int);
> +int tig_mkstemps_mode(char *pattern, int suffix_len, int mode);
> +
> +/*
>    * Executing external commands.
>    */
>

      reply	other threads:[~2013-07-18  4:52 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-09 15:33 [PATCH] TIG: Implement mkstemps() work-around for platforms lacking it Drew Northup
2013-07-18  4:45 ` Drew Northup [this message]

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

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

  git send-email \
    --in-reply-to=51E772E3.20008@gmail.com \
    --to=n1xim.email@gmail.com \
    --cc=davvid@gmail.com \
    --cc=fonseca@diku.dk \
    --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.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.