mirror of
git://sourceware.org/git/glibc.git
synced 2026-09-09 23:58:37 +08:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3dbc4418f2 | ||
|
|
77d4f6d1ed |
@@ -1,3 +1,38 @@
|
||||
2014-11-24 Roland McGrath <roland@hack.frob.com>
|
||||
|
||||
* nptl/sem_open.c (sem_open): Use __gen_tempname with
|
||||
__gen_tempname_try_file and custom MODE value, rather than
|
||||
using __mktemp and open in a loop.
|
||||
* stdio-common/Versions (GLIBC_PRIVATE): Add __gen_tempname,
|
||||
__gen_tempname_try_file.
|
||||
|
||||
* sysdeps/posix/tempname.c (__gen_tempname): Instead of FLAGS and KIND
|
||||
arguments, take a function pointer TRY_NAME and void *TRY_NAME_ARG.
|
||||
Call that *TRY_NAME to try a candidate name.
|
||||
(__gen_tempname_try_nocreate, __gen_tempname_try_file): New functions.
|
||||
* stdio-common/tempname.c (__gen_tempname): Update signature.
|
||||
* include/stdio.h: Update decl.
|
||||
(__GT_FILE, __GT_NOCREATE, __GT_DIR): Macros removed.
|
||||
(__GT_FILE_DEFAULTS): New macro.
|
||||
* stdio-common/tmpnam.c: Update caller.
|
||||
* stdio-common/tmpnam_r.c: Likewise.
|
||||
* stdio-common/tmpfile.c: Likewise.
|
||||
* misc/mktemp.c (__mktemp): Prototypify. Update caller.
|
||||
* libio/oldtmpfile.c (__old_tmpfile): Update caller.
|
||||
* misc/mkostemp.c: Prototypify. Update caller.
|
||||
* misc/mkstemp.c: Likewise.
|
||||
* misc/mkostemps.c: Likewise.
|
||||
* misc/mkstemp64.c: Likewise.
|
||||
* misc/mkdtemp.c (try_mkdir): New function.
|
||||
(mkdtemp): Use it with new __gen_tempname signature. Prototypify.
|
||||
* misc/mkostemp.c: Prototypify. Just call mkostemps.
|
||||
* misc/mkstemps.c: Likewise.
|
||||
* misc/mkstemps64.c: Likewise.
|
||||
* misc/mkostemp64.c: Prototypify.
|
||||
Just call mkostemp with modified flags.
|
||||
* misc/mkostemps64.c: Prototypify.
|
||||
Just call mkostemps with modified flags.
|
||||
|
||||
2014-11-24 Ryan Cumming <etaoins@gmail.com>
|
||||
|
||||
[BZ #17608]
|
||||
|
||||
+16
-6
@@ -82,12 +82,22 @@ extern int __path_search (char *__tmpl, size_t __tmpl_len,
|
||||
const char *__dir, const char *__pfx,
|
||||
int __try_tempdir);
|
||||
|
||||
extern int __gen_tempname (char *__tmpl, int __suffixlen, int __flags,
|
||||
int __kind);
|
||||
/* The __kind argument to __gen_tempname may be one of: */
|
||||
# define __GT_FILE 0 /* create a file */
|
||||
# define __GT_DIR 1 /* create a directory */
|
||||
# define __GT_NOCREATE 2 /* just find a name not currently in use */
|
||||
/* The *TRY_NAME function is called repeatedly on candidate names until
|
||||
it returns >= 0. If it returns -2, the next candidate name is tried.
|
||||
If it returns -1 (with errno set), __gen_tempname fails immediately. */
|
||||
extern int __gen_tempname (char *__tmpl, int __suffixlen,
|
||||
int (*__try_name) (const char *__name, void *__arg),
|
||||
void *__try_name_arg);
|
||||
|
||||
/* These are the common TRY_NAME functions. */
|
||||
|
||||
/* ARG is ignored. */
|
||||
extern int __gen_tempname_try_nocreate (const char *__name, void *__arg);
|
||||
|
||||
/* ARG is int[2] of {flags, mode}. */
|
||||
extern int __gen_tempname_try_file (const char *__name, void *__arg);
|
||||
#define __GT_FILE_DEFAULTS (&((int[2]) { 0, 0600 }))
|
||||
|
||||
|
||||
/* Print out MESSAGE on the error output and abort. */
|
||||
extern void __libc_fatal (const char *__message)
|
||||
|
||||
+3
-1
@@ -37,7 +37,9 @@ __old_tmpfile (void)
|
||||
|
||||
if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0))
|
||||
return NULL;
|
||||
fd = __gen_tempname (buf, 0, 0, __GT_FILE);
|
||||
|
||||
int flags_and_mode[2] = { 0, 0 };
|
||||
fd = __gen_tempname (buf, 0, &__gen_tempname_try_file, __GT_FILE_DEFAULTS);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
|
||||
+15
-3
@@ -15,8 +15,21 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
static int
|
||||
try_mkdir (const char *name, void *arg __attribute__ ((unused)))
|
||||
{
|
||||
int result = __mkdir (name, S_IRUSR | S_IWUSR | S_IXUSR);
|
||||
if (result < 0 && errno == EEXIST)
|
||||
/* Nothing funny went wrong, it just already exists. Keep looking. */
|
||||
result = -2;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Generate a unique temporary directory from TEMPLATE.
|
||||
The last six characters of TEMPLATE must be "XXXXXX";
|
||||
@@ -24,10 +37,9 @@
|
||||
The directory is created, mode 700, and its name is returned.
|
||||
(This function comes from OpenBSD.) */
|
||||
char *
|
||||
mkdtemp (template)
|
||||
char *template;
|
||||
mkdtemp (char *template)
|
||||
{
|
||||
if (__gen_tempname (template, 0, 0, __GT_DIR))
|
||||
if (__gen_tempname (template, 0, &try_mkdir, NULL))
|
||||
return NULL;
|
||||
else
|
||||
return template;
|
||||
|
||||
+3
-8
@@ -17,21 +17,16 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef __GT_FILE
|
||||
# define __GT_FILE 0
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* Generate a unique temporary file name from TEMPLATE.
|
||||
The last six characters of TEMPLATE must be "XXXXXX";
|
||||
they are replaced with a string that makes the filename unique.
|
||||
Then open the file and return a fd. */
|
||||
int
|
||||
mkostemp (template, flags)
|
||||
char *template;
|
||||
int flags;
|
||||
mkostemp (char *template, int flags)
|
||||
{
|
||||
return __gen_tempname (template, 0, flags, __GT_FILE);
|
||||
return mkostemps (template, 0, flags);
|
||||
}
|
||||
|
||||
#if !defined O_LARGEFILE || O_LARGEFILE == 0
|
||||
|
||||
+2
-4
@@ -27,11 +27,9 @@
|
||||
they are replaced with a string that makes the filename unique.
|
||||
Then open the file and return a fd. */
|
||||
int
|
||||
mkostemp64 (template, flags)
|
||||
char *template;
|
||||
int flags;
|
||||
mkostemp64 (char *template, int flags)
|
||||
{
|
||||
return __gen_tempname (template, 0, flags | O_LARGEFILE, __GT_FILE);
|
||||
return mkostemp (template, flags | O_LARGEFILE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+3
-9
@@ -19,19 +19,12 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef __GT_FILE
|
||||
# define __GT_FILE 0
|
||||
#endif
|
||||
|
||||
/* Generate a unique temporary file name from TEMPLATE. The last six
|
||||
characters before a suffix of length SUFFIXLEN of TEMPLATE must be
|
||||
"XXXXXX"; they are replaced with a string that makes the filename
|
||||
unique. Then open the file and return a fd. */
|
||||
int
|
||||
mkostemps (template, suffixlen, flags)
|
||||
char *template;
|
||||
int suffixlen;
|
||||
int flags;
|
||||
mkostemps (char *template, int suffixlen, int flags)
|
||||
{
|
||||
if (suffixlen < 0)
|
||||
{
|
||||
@@ -39,7 +32,8 @@ mkostemps (template, suffixlen, flags)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return __gen_tempname (template, suffixlen, flags, __GT_FILE);
|
||||
return __gen_tempname (template, suffixlen, &__gen_tempname_try_file,
|
||||
&((int[2]) { flags, S_IRUSR | S_IWUSR }));
|
||||
}
|
||||
|
||||
#if !defined O_LARGEFILE || O_LARGEFILE == 0
|
||||
|
||||
+2
-11
@@ -28,18 +28,9 @@
|
||||
"XXXXXX"; they are replaced with a string that makes the filename
|
||||
unique. Then open the file and return a fd. */
|
||||
int
|
||||
mkostemps64 (template, suffixlen, flags)
|
||||
char *template;
|
||||
int suffixlen;
|
||||
int flags;
|
||||
mkostemps64 (char *template, int suffixlen, int flags)
|
||||
{
|
||||
if (suffixlen < 0)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return __gen_tempname (template, suffixlen, flags | O_LARGEFILE, __GT_FILE);
|
||||
return mkostemps (template, sufflixen, flags | O_LARGEFILE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+3
-7
@@ -18,19 +18,15 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef __GT_FILE
|
||||
# define __GT_FILE 0
|
||||
#endif
|
||||
|
||||
/* Generate a unique temporary file name from TEMPLATE.
|
||||
The last six characters of TEMPLATE must be "XXXXXX";
|
||||
they are replaced with a string that makes the filename unique.
|
||||
Then open the file and return a fd. */
|
||||
int
|
||||
mkstemp (template)
|
||||
char *template;
|
||||
mkstemp (char *template)
|
||||
{
|
||||
return __gen_tempname (template, 0, 0, __GT_FILE);
|
||||
return __gen_tempname (template, 0,
|
||||
&__gen_tempname_try_file, __GT_FILE_DEFAULTS);
|
||||
}
|
||||
|
||||
#if !defined O_LARGEFILE || O_LARGEFILE == 0
|
||||
|
||||
+3
-3
@@ -27,10 +27,10 @@
|
||||
they are replaced with a string that makes the filename unique.
|
||||
Then open the file and return a fd. */
|
||||
int
|
||||
mkstemp64 (template)
|
||||
char *template;
|
||||
mkstemp64 (char *template)
|
||||
{
|
||||
return __gen_tempname (template, 0, O_LARGEFILE, __GT_FILE);
|
||||
return __gen_tempname (template, 0, &__gen_tempname_try_file,
|
||||
(&((int[2]) { O_LARGEFILE, 0600 })));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+2
-14
@@ -19,26 +19,14 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef __GT_FILE
|
||||
# define __GT_FILE 0
|
||||
#endif
|
||||
|
||||
/* Generate a unique temporary file name from TEMPLATE. The last six
|
||||
characters before a suffix of length SUFFIXLEN of TEMPLATE must be
|
||||
"XXXXXX"; they are replaced with a string that makes the filename
|
||||
unique. Then open the file and return a fd. */
|
||||
int
|
||||
mkstemps (template, suffixlen)
|
||||
char *template;
|
||||
int suffixlen;
|
||||
mkstemps (char *template, int suffixlen)
|
||||
{
|
||||
if (suffixlen < 0)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return __gen_tempname (template, suffixlen, 0, __GT_FILE);
|
||||
return mkostemps (template, suffixlen, 0);
|
||||
}
|
||||
|
||||
#if !defined O_LARGEFILE || O_LARGEFILE == 0
|
||||
|
||||
+2
-10
@@ -28,17 +28,9 @@
|
||||
"XXXXXX"; they are replaced with a string that makes the filename
|
||||
unique. Then open the file and return a fd. */
|
||||
int
|
||||
mkstemps64 (template, suffixlen)
|
||||
char *template;
|
||||
int suffixlen;
|
||||
mkstemps64 (char *template, int suffixlen)
|
||||
{
|
||||
if (suffixlen < 0)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return __gen_tempname (template, suffixlen, O_LARGEFILE, __GT_FILE);
|
||||
return mkostemps (template, suffixlen, O_LARGEFILE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+2
-3
@@ -22,10 +22,9 @@
|
||||
The last six characters of TEMPLATE must be "XXXXXX";
|
||||
they are replaced with a string that makes the filename unique. */
|
||||
char *
|
||||
__mktemp (template)
|
||||
char *template;
|
||||
__mktemp (char *template)
|
||||
{
|
||||
if (__gen_tempname (template, 0, 0, __GT_NOCREATE) < 0)
|
||||
if (__gen_tempname (template, 0, &__gen_tempname_try_nocreate, NULL) < 0)
|
||||
/* We return the null string if we can't find a unique file name. */
|
||||
template[0] = '\0';
|
||||
|
||||
|
||||
+11
-33
@@ -318,40 +318,18 @@ sem_open (const char *name, int oflag, ...)
|
||||
sizeof (sem_t) - sizeof (struct new_sem));
|
||||
|
||||
tmpfname = (char *) alloca (mountpoint.dirlen + 6 + 1);
|
||||
char *xxxxxx = __mempcpy (tmpfname, mountpoint.dir, mountpoint.dirlen);
|
||||
strcpy (__mempcpy (tmpfname, mountpoint.dir, mountpoint.dirlen),
|
||||
"XXXXXX");
|
||||
|
||||
int retries = 0;
|
||||
#define NRETRIES 50
|
||||
while (1)
|
||||
{
|
||||
/* Add the suffix for mktemp. */
|
||||
strcpy (xxxxxx, "XXXXXX");
|
||||
|
||||
/* We really want to use mktemp here. We cannot use mkstemp
|
||||
since the file must be opened with a specific mode. The
|
||||
mode cannot later be set since then we cannot apply the
|
||||
file create mask. */
|
||||
if (__mktemp (tmpfname) == NULL)
|
||||
return SEM_FAILED;
|
||||
|
||||
/* Open the file. Make sure we do not overwrite anything. */
|
||||
fd = __libc_open (tmpfname, O_RDWR | O_CREAT | O_EXCL, mode);
|
||||
if (fd == -1)
|
||||
{
|
||||
if (errno == EEXIST)
|
||||
{
|
||||
if (++retries < NRETRIES)
|
||||
continue;
|
||||
|
||||
__set_errno (EAGAIN);
|
||||
}
|
||||
|
||||
return SEM_FAILED;
|
||||
}
|
||||
|
||||
/* We got a file. */
|
||||
break;
|
||||
}
|
||||
/* This is just like mkstemp, but with a specific mode. */
|
||||
fd = __gen_tempname (tmpfname, 0,
|
||||
&__gen_tempname_try_file, &((int[2]) { 0, mode }));
|
||||
if (fd < 0)
|
||||
{
|
||||
if (errno == EEXIST)
|
||||
__set_errno (EAGAIN);
|
||||
return SEM_FAILED;
|
||||
}
|
||||
|
||||
if (TEMP_FAILURE_RETRY (__libc_write (fd, &sem.initsem, sizeof (sem_t)))
|
||||
== sizeof (sem_t)
|
||||
|
||||
@@ -58,6 +58,9 @@ libc {
|
||||
register_printf_modifier; register_printf_type; register_printf_specifier;
|
||||
}
|
||||
GLIBC_PRIVATE {
|
||||
__gen_tempname;
|
||||
__gen_tempname_try_file;
|
||||
|
||||
# global variables
|
||||
_itoa_lower_digits;
|
||||
}
|
||||
|
||||
@@ -30,10 +30,11 @@ tempnam (const char *dir, const char *pfx)
|
||||
{
|
||||
char buf[FILENAME_MAX];
|
||||
|
||||
if (__path_search (buf, FILENAME_MAX, dir, pfx, 1))
|
||||
if (__glibc_unlikely (__path_search (buf, sizeof buf, dir, pfx, 1)))
|
||||
return NULL;
|
||||
|
||||
if (__gen_tempname (buf, 0, 0, __GT_NOCREATE))
|
||||
if (__glibc_unlikely (__gen_tempname (buf, 0,
|
||||
__gen_tempname_try_nocreate, NULL)))
|
||||
return NULL;
|
||||
|
||||
return __strdup (buf);
|
||||
|
||||
+10
-13
@@ -36,21 +36,18 @@ __path_search (tmpl, tmpl_len, dir, pfx, try_tmpdir)
|
||||
}
|
||||
stub_warning (__path_search)
|
||||
|
||||
/* Generate a (hopefully) unique temporary filename
|
||||
in DIR (if applicable), using template TMPL.
|
||||
KIND determines what to do with that name. It may be one of:
|
||||
__GT_FILE: create a file and return a read-write fd.
|
||||
__GT_BIGFILE: same, but use open64() (or equivalent).
|
||||
__GT_DIR: create a directory.
|
||||
__GT_NOCREATE: just find a name not currently in use.
|
||||
*/
|
||||
/* Generate a temporary file name based on TMPL. TMPL must match the
|
||||
rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix).
|
||||
The name constructed does not exist at the time of the call to
|
||||
__gen_tempname. TMPL is overwritten with the result.
|
||||
|
||||
The *TRY_NAME function is called repeatedly on candidate names until
|
||||
it returns >= 0. If it returns -2, the next candidate name is tried.
|
||||
If it returns -1 (with errno set), __gen_tempname fails immediately. */
|
||||
int
|
||||
__gen_tempname (tmpl, suffixlen, flags, kind)
|
||||
char *tmpl;
|
||||
int suffixlen;
|
||||
int flags;
|
||||
int kind;
|
||||
__gen_tempname (char *tmpl, int suffixlen,
|
||||
int (*try_name) (const char *name, void *arg),
|
||||
void *try_name_arg)
|
||||
{
|
||||
__set_errno (ENOSYS);
|
||||
return -1;
|
||||
|
||||
@@ -44,7 +44,8 @@ tmpfile (void)
|
||||
#ifdef FLAGS
|
||||
flags = FLAGS;
|
||||
#endif
|
||||
fd = __gen_tempname (buf, 0, flags, __GT_FILE);
|
||||
fd = __gen_tempname (buf, 0, &__gen_tempname_try_file,
|
||||
&((int[2]) { flags, S_IRUSR | S_IWUSR }));
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -34,11 +34,11 @@ tmpnam (char *s)
|
||||
/* In the following call we use the buffer pointed to by S if
|
||||
non-NULL although we don't know the size. But we limit the size
|
||||
to L_tmpnam characters in any case. */
|
||||
if (__builtin_expect (__path_search (tmpbuf, L_tmpnam, NULL, NULL, 0),
|
||||
0))
|
||||
if (__glibc_unlikely (__path_search (tmpbuf, L_tmpnam, NULL, NULL, 0)))
|
||||
return NULL;
|
||||
|
||||
if (__glibc_unlikely (__gen_tempname (tmpbuf, 0, 0, __GT_NOCREATE)))
|
||||
if (__glibc_unlikely (__gen_tempname (tmpbuf, 0,
|
||||
__gen_tempname_try_nocreate, NULL)))
|
||||
return NULL;
|
||||
|
||||
if (s == NULL)
|
||||
|
||||
@@ -25,9 +25,10 @@ tmpnam_r (char *s)
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
|
||||
if (__path_search (s, L_tmpnam, NULL, NULL, 0))
|
||||
if (__glibc_unlikely (__path_search (s, L_tmpnam, NULL, NULL, 0)))
|
||||
return NULL;
|
||||
if (__gen_tempname (s, 0, 0, __GT_NOCREATE))
|
||||
if (__glibc_unlikely (__gen_tempname (s, 0,
|
||||
__gen_tempname_try_nocreate, NULL)))
|
||||
return NULL;
|
||||
|
||||
return s;
|
||||
|
||||
+41
-49
@@ -180,25 +180,22 @@ static const char letters[] =
|
||||
The name constructed does not exist at the time of the call to
|
||||
__gen_tempname. TMPL is overwritten with the result.
|
||||
|
||||
KIND may be one of:
|
||||
__GT_NOCREATE: simply verify that the name does not exist
|
||||
at the time of the call.
|
||||
__GT_FILE: create the file using open(O_CREAT|O_EXCL)
|
||||
and return a read-write fd. The file is mode 0600.
|
||||
__GT_DIR: create a directory, which will be mode 0700.
|
||||
The *TRY_NAME function is called repeatedly on candidate names until
|
||||
it returns >= 0. If it returns -2, the next candidate name is tried.
|
||||
If it returns -1 (with errno set), __gen_tempname fails immediately.
|
||||
|
||||
We use a clever algorithm to get hard-to-predict names. */
|
||||
int
|
||||
__gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
|
||||
__gen_tempname (char *tmpl, int suffixlen,
|
||||
int (*try_name) (const char *name, void *arg),
|
||||
void *try_name_arg)
|
||||
{
|
||||
int len;
|
||||
char *XXXXXX;
|
||||
static uint64_t value;
|
||||
uint64_t random_time_bits;
|
||||
unsigned int count;
|
||||
int fd = -1;
|
||||
int save_errno = errno;
|
||||
struct_stat64 st;
|
||||
|
||||
/* A lower bound on the number of temporary files to attempt to
|
||||
generate. The maximum total number of temporary file names that
|
||||
@@ -255,51 +252,46 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
|
||||
v /= 62;
|
||||
XXXXXX[5] = letters[v % 62];
|
||||
|
||||
switch (kind)
|
||||
{
|
||||
case __GT_FILE:
|
||||
fd = __open (tmpl,
|
||||
(flags & ~O_ACCMODE)
|
||||
| O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
|
||||
break;
|
||||
|
||||
case __GT_DIR:
|
||||
fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
|
||||
break;
|
||||
|
||||
case __GT_NOCREATE:
|
||||
/* This case is backward from the other three. __gen_tempname
|
||||
succeeds if __xstat fails because the name does not exist.
|
||||
Note the continue to bypass the common logic at the bottom
|
||||
of the loop. */
|
||||
if (__lxstat64 (_STAT_VER, tmpl, &st) < 0)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
__set_errno (save_errno);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
/* Give up now. */
|
||||
return -1;
|
||||
}
|
||||
continue;
|
||||
|
||||
default:
|
||||
assert (! "invalid KIND in __gen_tempname");
|
||||
abort ();
|
||||
}
|
||||
|
||||
if (fd >= 0)
|
||||
{
|
||||
__set_errno (save_errno);
|
||||
int fd = (*try_name) (tmpl, try_name_arg);
|
||||
if (fd != -2)
|
||||
{
|
||||
if (fd >= 0)
|
||||
__set_errno (save_errno);
|
||||
return fd;
|
||||
}
|
||||
else if (errno != EEXIST)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* We got out of the loop because we ran out of combinations to try. */
|
||||
__set_errno (EEXIST);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
__gen_tempname_try_nocreate (const char *name, void *arg)
|
||||
{
|
||||
struct stat64 st;
|
||||
if (__lxstat64 (_STAT_VER, name, &st) == 0)
|
||||
/* This name exists. Try another. */
|
||||
return -2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ARG is int[2] of {flags, mode}. */
|
||||
int
|
||||
__gen_tempname_try_file (const char *name, void *arg)
|
||||
{
|
||||
const int *args = arg;
|
||||
int flags = args[0];
|
||||
mode_t mode = args[1];
|
||||
|
||||
int fd = __open (name,
|
||||
(flags & ~O_ACCMODE) | O_RDWR | O_CREAT | O_EXCL,
|
||||
mode);
|
||||
if (fd < 0 && errno == EEXIST)
|
||||
/* Nothing funny went wrong, it just already exists. Keep looking. */
|
||||
fd = -2;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user