Evil: Add support for mkstemps

This adds filename suffix support for temporary files on Windows.
This commit is contained in:
Jean-Philippe Andre 2014-04-01 17:55:09 +09:00
parent 0fdb02fb51
commit 5926aadd9e
3 changed files with 86 additions and 28 deletions

View File

@ -35,19 +35,60 @@ test_mkstemp_test(void)
return 1; return 1;
} }
static int
test_mkstemps_test(void)
{
char _template[PATH_MAX];
#ifdef _WIN32_WCE
char cwd[PATH_MAX];
#endif
int fd;
#ifdef _WIN32_WCE
if (!getcwd(cwd, PATH_MAX))
return 0;
_snprintf(_template, PATH_MAX, "%s\\%s", cwd, "file_XXXXXX.ext");
#else
_snprintf(_template, PATH_MAX, "%s", "file_XXXXXX.ext");
#endif
fd = mkstemps(_template, 4);
if (fd < 0)
return 0;
return 1;
}
static int static int
test_mkstemp_run(suite *s) test_mkstemp_run(suite *s)
{ {
int res; int res;
(void) s;
res = test_mkstemp_test(); res = test_mkstemp_test();
return res; return res;
} }
static int
test_mkstemps_run(suite *s)
{
int res;
(void) s;
res = test_mkstemps_test();
return res;
}
int int
test_mkstemp(suite *s) test_mkstemp(suite *s)
{ {
int res;
return test_mkstemp_run(s); res = test_mkstemp_run(s);
res &= test_mkstemps_run(s);
return res;
} }

View File

@ -269,17 +269,18 @@ unsetenv(const char *name)
* *
*/ */
static int static int
_mkstemp_init(char *__template, char **suffix, size_t *length, DWORD *val) _mkstemp_init(char *__template, char **suffix, size_t *length, DWORD *val,
size_t suffixlen)
{ {
*length = strlen(__template); *length = strlen(__template);
if ((*length < 6) || if ((*length < (6 + suffixlen))
(strncmp (__template + *length - 6, "XXXXXX", 6))) || (strncmp(__template + *length - 6 - suffixlen, "XXXXXX", 6) != 0))
{ {
errno = EINVAL; errno = EINVAL;
return 0; return 0;
} }
*suffix = __template + *length - 6; *suffix = __template + *length - 6 - suffixlen;
*val = GetTickCount(); *val = GetTickCount();
*val += GetCurrentProcessId(); *val += GetCurrentProcessId();
@ -322,27 +323,27 @@ mkdtemp(char *__template)
if (!__template) if (!__template)
{ {
errno = EINVAL; errno = EINVAL;
return NULL; return NULL;
} }
if (!_mkstemp_init(__template, &suffix, &length, &val)) if (!_mkstemp_init(__template, &suffix, &length, &val, 0))
return NULL; return NULL;
for (i = 0; i < 32768; i++) for (i = 0; i < 32768; i++)
{ {
val = _mkstemp(suffix, val); val = _mkstemp(suffix, val);
if (mkdir(__template)) if (mkdir(__template))
return __template; return __template;
if (errno == EFAULT || if (errno == EFAULT ||
errno == ENOSPC || errno == ENOSPC ||
errno == ENOMEM || errno == ENOMEM ||
errno == ENOENT || errno == ENOENT ||
errno == ENOTDIR || errno == ENOTDIR ||
errno == EPERM || errno == EPERM ||
errno == EROFS) errno == EROFS)
return NULL; return NULL;
} }
errno = EEXIST; errno = EEXIST;
@ -350,17 +351,17 @@ mkdtemp(char *__template)
} }
int int
mkstemp(char *__template) mkstemps(char *__template, int suffixlen)
{ {
char *suffix; char *suffix;
DWORD val; DWORD val;
size_t length; size_t length;
int i; int i;
if (!__template) if (!__template || (suffixlen < 0))
return 0; return 0;
if (!_mkstemp_init(__template, &suffix, &length, &val)) if (!_mkstemp_init(__template, &suffix, &length, &val, (size_t) suffixlen))
return -1; return -1;
for (i = 0; i < 32768; i++) for (i = 0; i < 32768; i++)
@ -397,6 +398,11 @@ mkstemp(char *__template)
return -1; return -1;
} }
int
mkstemp(char *__template)
{
return mkstemps(__template, 0);
}
char * char *
realpath(const char *file_name, char *resolved_name) realpath(const char *file_name, char *resolved_name)

View File

@ -128,7 +128,7 @@ EAPI int unsetenv(const char *name);
*/ */
/** /**
* @brief Make temporay unique file name. * @brief Create a unique temporary file name.
* *
* @param __template Template of the file to create. * @param __template Template of the file to create.
* @return A file descriptor on success, -1 otherwise. * @return A file descriptor on success, -1 otherwise.
@ -137,14 +137,14 @@ EAPI int unsetenv(const char *name);
* to create a file name. This file is guaranted not to exist at the * to create a file name. This file is guaranted not to exist at the
* time invocation and is suitable for use by the function. * time invocation and is suitable for use by the function.
* *
* The @p template parameter can be any file name with some number of * The @p template parameter can be any file name with six X's at the end
* 'Xs' appended to it, for example @em baseXXXXXX, where @em base is * for example @em baseXXXXXX, where @em base is the part of the new file
* the part of the new file that you supply and eacg 'X' is a placeholder * that you supply and each 'X' is a placeholder for a character supplied
* for a character supplied by mkstemp(). The trailing 'Xs' are replaced * by mkstemp(). The trailing 'Xs' are replaced with a six-digit value;
* with a five-digit value; this value is a unique number. Each successful * this value is a unique number. Each successful call to mkstemp()
* call to mkstemp() modifes @p template. * modifies @p template.
* *
* When mkstemp() succeeds, it creates and opens the template file for * When mkstemp() succeeds, it creates and opens the temporary file for
* reading and writing. * reading and writing.
* *
* On success, the function returns the file descriptor of the * On success, the function returns the file descriptor of the
@ -166,6 +166,17 @@ EAPI int mkstemp(char *__template);
*/ */
EAPI char *mkdtemp(char *__template); EAPI char *mkdtemp(char *__template);
/**
* @brief Create a unique temporary file name with a suffix.
*
* @param __template Template of the file to create.
* @param suffixlen Length of the suffix following the 'XXXXXX' placeholder.
* @return A file descriptor on success, -1 otherwise.
*
* @since 1.10.0
*/
EAPI int mkstemps(char *__template, int suffixlen);
/** /**
* @brief Return an absolute or full path name for a specified relative path name. * @brief Return an absolute or full path name for a specified relative path name.
* *