Skip to content

Commit

Permalink
Move gitmkstemps to path.c
Browse files Browse the repository at this point in the history
This function used to be only a compatibility function, but we're
going to extend it and actually use it, so make it part of Git.

Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Matthieu Moy authored and Junio C Hamano committed Feb 22, 2010
1 parent 7aba618 commit 00787ed
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 71 deletions.
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1200,7 +1200,6 @@ ifdef NO_MKDTEMP
endif
ifdef NO_MKSTEMPS
COMPAT_CFLAGS += -DNO_MKSTEMPS
COMPAT_OBJS += compat/mkstemps.o
endif
ifdef NO_UNSETENV
COMPAT_CFLAGS += -DNO_UNSETENV
Expand Down
70 changes: 0 additions & 70 deletions compat/mkstemps.c

This file was deleted.

69 changes: 69 additions & 0 deletions path.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,75 @@ int git_mkstemps(char *path, size_t len, const char *template, int suffix_len)
return mkstemps(path, suffix_len);
}

/* Adapted from libiberty's mkstemp.c. */

#undef TMP_MAX
#define TMP_MAX 16384

int gitmkstemps(char *pattern, int suffix_len)
{
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, 0600);
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';
errno = EINVAL;
return -1;
}

int validate_headref(const char *path)
{
struct stat st;
Expand Down

0 comments on commit 00787ed

Please sign in to comment.