Add mkostemp and mkostemps.

* libc/stdio/mktemp.c (_gettemp): Add parameter, all callers
changed.
(mkostemp, _mkostemp_r, mkostemps, _mkostemps_r): New interfaces,
for ELIX level 4.
* libc/include/stdlib.h (mktemp): Avoid namespace issues.
(mkostemp, mkostemps): Declare.
This commit is contained in:
Eric Blake 2010-07-19 18:21:11 +00:00
parent fdd1a78d07
commit 8092f46770
3 changed files with 112 additions and 27 deletions

View File

@ -1,3 +1,12 @@
2010-07-19 Eric Blake <eblake@redhat.com>
* libc/stdio/mktemp.c (_gettemp): Add parameter, all callers
changed.
(mkostemp, _mkostemp_r, mkostemps, _mkostemps_r): New interfaces,
for ELIX level 4.
* libc/include/stdlib.h (mktemp): Avoid namespace issues.
(mkostemp, mkostemps): Declare.
2010-07-13 Corinna Vinschen <corinna@vinschen.de> 2010-07-13 Corinna Vinschen <corinna@vinschen.de>
* libc/include/signal.h (sighandler_t): Only define if _POSIX_SOURCE * libc/include/signal.h (sighandler_t): Only define if _POSIX_SOURCE

View File

@ -103,14 +103,18 @@ size_t _EXFUN(_wcstombs_r,(struct _reent *, char *, const wchar_t *, size_t, _mb
#ifndef __STRICT_ANSI__ #ifndef __STRICT_ANSI__
#ifndef _REENT_ONLY #ifndef _REENT_ONLY
char * _EXFUN(mkdtemp,(char *)); char * _EXFUN(mkdtemp,(char *));
int _EXFUN(mkostemp,(char *, int));
int _EXFUN(mkostemps,(char *, int, int));
int _EXFUN(mkstemp,(char *)); int _EXFUN(mkstemp,(char *));
int _EXFUN(mkstemps,(char *, int)); int _EXFUN(mkstemps,(char *, int));
char * _EXFUN(mktemp,(char *) _ATTRIBUTE ((warning ("the use of `mktemp' is dangerous; use `mkstemp' instead")))); char * _EXFUN(mktemp,(char *) _ATTRIBUTE ((__warning__ ("the use of `mktemp' is dangerous; use `mkstemp' instead"))));
#endif #endif
char * _EXFUN(_mkdtemp_r, (struct _reent *, char *)); char * _EXFUN(_mkdtemp_r, (struct _reent *, char *));
int _EXFUN(_mkostemp_r, (struct _reent *, char *, int));
int _EXFUN(_mkostemps_r, (struct _reent *, char *, int, int));
int _EXFUN(_mkstemp_r, (struct _reent *, char *)); int _EXFUN(_mkstemp_r, (struct _reent *, char *));
int _EXFUN(_mkstemps_r, (struct _reent *, char *, int)); int _EXFUN(_mkstemps_r, (struct _reent *, char *, int));
char * _EXFUN(_mktemp_r, (struct _reent *, char *) _ATTRIBUTE ((warning ("the use of `mktemp' is dangerous; use `mkstemp' instead")))); char * _EXFUN(_mktemp_r, (struct _reent *, char *) _ATTRIBUTE ((__warning__ ("the use of `mktemp' is dangerous; use `mkstemp' instead"))));
#endif #endif
_VOID _EXFUN(qsort,(_PTR __base, size_t __nmemb, size_t __size, int(*_compar)(const _PTR, const _PTR))); _VOID _EXFUN(qsort,(_PTR __base, size_t __nmemb, size_t __size, int(*_compar)(const _PTR, const _PTR)));
int _EXFUN(rand,(_VOID)); int _EXFUN(rand,(_VOID));

View File

@ -23,7 +23,8 @@
/* /*
FUNCTION FUNCTION
<<mktemp>>, <<mkstemp>>, <<mkstemps>>---generate unused file name <<mktemp>>, <<mkstemp>>, <<mkostemp>>, <<mkstemps>>,
<<mkostemps>>---generate unused file name
<<mkdtemp>>---generate unused directory <<mkdtemp>>---generate unused directory
INDEX INDEX
@ -34,6 +35,10 @@ INDEX
mkstemp mkstemp
INDEX INDEX
mkstemps mkstemps
INDEX
mkostemp
INDEX
mkostemps
INDEX INDEX
_mktemp_r _mktemp_r
INDEX INDEX
@ -42,6 +47,10 @@ INDEX
_mkstemp_r _mkstemp_r
INDEX INDEX
_mkstemps_r _mkstemps_r
INDEX
_mkostemp_r
INDEX
_mkostemps_r
ANSI_SYNOPSIS ANSI_SYNOPSIS
#include <stdlib.h> #include <stdlib.h>
@ -49,19 +58,29 @@ ANSI_SYNOPSIS
char *mkdtemp(char *<[path]>); char *mkdtemp(char *<[path]>);
int mkstemp(char *<[path]>); int mkstemp(char *<[path]>);
int mkstemps(char *<[path]>, int <[suffixlen]>); int mkstemps(char *<[path]>, int <[suffixlen]>);
int mkostemp(char *<[path]>, int <[flags]>);
int mkostemps(char *<[path]>, int <[suffixlen]>, int <[flags]>);
char *_mktemp_r(struct _reent *<[reent]>, char *<[path]>); char *_mktemp_r(struct _reent *<[reent]>, char *<[path]>);
char *_mkdtemp_r(struct _reent *<[reent]>, char *<[path]>); char *_mkdtemp_r(struct _reent *<[reent]>, char *<[path]>);
int *_mkstemp_r(struct _reent *<[reent]>, char *<[path]>); int *_mkstemp_r(struct _reent *<[reent]>, char *<[path]>);
int *_mkstemps_r(struct _reent *<[reent]>, char *<[path]>, int <[len]>); int *_mkstemps_r(struct _reent *<[reent]>, char *<[path]>, int <[len]>);
int *_mkostemp_r(struct _reent *<[reent]>, char *<[path]>,
int <[flags]>);
int *_mkostemps_r(struct _reent *<[reent]>, char *<[path]>, int <[len]>,
int <[flags]>);
DESCRIPTION DESCRIPTION
<<mktemp>>, <<mkstemp>>, and <<mkstemps>> attempt to generate a file name <<mktemp>>, <<mkstemp>>, and <<mkstemps>> attempt to generate a file name
that is not yet in use for any existing file. <<mkstemp>> and <<mkstemps>> that is not yet in use for any existing file. <<mkstemp>> and <<mkstemps>>
create the file and open it for reading and writing; <<mktemp>> simply create the file and open it for reading and writing; <<mktemp>> simply
generates the file name (making <<mktemp>> a security risk). <<mkdtemp>> generates the file name (making <<mktemp>> a security risk). <<mkostemp>>
attempts to create a directory instead of a file, with a permissions and <<mkostemps>> allow the addition of other <<open>> flags, such
mask of 0700. as <<O_CLOEXEC>>, <<O_APPEND>>, or <<O_SYNC>>. On platforms with a
separate text mode, <<mkstemp>> forces <<O_BINARY>>, while <<mkostemp>>
allows the choice between <<O_BINARY>>, <<O_TEXT>>, or 0 for default.
<<mkdtemp>> attempts to create a directory instead of a file, with a
permissions mask of 0700.
You supply a simple pattern for the generated file name, as the string You supply a simple pattern for the generated file name, as the string
at <[path]>. The pattern should be a valid filename (including path at <[path]>. The pattern should be a valid filename (including path
@ -72,22 +91,25 @@ combination of digits and letters. With <<mkstemps>>, the `<<X>>'
characters end <[suffixlen]> bytes before the end of the string. characters end <[suffixlen]> bytes before the end of the string.
The alternate functions <<_mktemp_r>>, <<_mkdtemp_r>>, <<_mkstemp_r>>, The alternate functions <<_mktemp_r>>, <<_mkdtemp_r>>, <<_mkstemp_r>>,
and <<_mkstemps_r>> are reentrant versions. The extra argument <[reent]> <<_mkostemp_r>>, <<_mkostemps_r>>, and <<_mkstemps_r>> are reentrant
is a pointer to a reentrancy structure. versions. The extra argument <[reent]> is a pointer to a reentrancy
structure.
RETURNS RETURNS
<<mktemp>> returns the pointer <[path]> to the modified string <<mktemp>> returns the pointer <[path]> to the modified string
representing an unused filename, unless it could not generate one, or representing an unused filename, unless it could not generate one, or
the pattern you provided is not suitable for a filename; in that case, the pattern you provided is not suitable for a filename; in that case,
it returns <<NULL>>. it returns <<NULL>>. Be aware that there is an inherent race between
generating the name and attempting to create a file by that name;
you are advised to use <<O_EXCL|O_CREAT>>.
<<mkdtemp>> returns the pointer <[path]> to the modified string if the <<mkdtemp>> returns the pointer <[path]> to the modified string if the
directory was created, otherwise it returns <<NULL>>. directory was created, otherwise it returns <<NULL>>.
<<mkstemp>> and <<mkstemps>> return a file descriptor to the newly created <<mkstemp>>, <<mkstemps>>, <<mkostemp>>, and <<mkostemps>> return a file
file, unless it could not generate an unused filename, or the pattern you descriptor to the newly created file, unless it could not generate an
provided is not suitable for a filename; in that case, it returns unused filename, or the pattern you provided is not suitable for a
<<-1>>. filename; in that case, it returns <<-1>>.
NOTES NOTES
Never use <<mktemp>>. The generated filenames are easy to guess and Never use <<mktemp>>. The generated filenames are easy to guess and
@ -99,8 +121,9 @@ instead. It doesn't suffer the race condition.
PORTABILITY PORTABILITY
ANSI C does not require either <<mktemp>> or <<mkstemp>>; the System ANSI C does not require either <<mktemp>> or <<mkstemp>>; the System
V Interface Definition requires <<mktemp>> as of Issue 2. POSIX 2001 V Interface Definition requires <<mktemp>> as of Issue 2. POSIX 2001
requires <<mkstemp>>, and POSIX 2008 requires <<mkdtemp>>, but requires <<mkstemp>>, and POSIX 2008 requires <<mkdtemp>> while
<<mkstemps>> is not standardized. deprecating <<mktemp>>. <<mkstemps>>, <<mkostemp>>, and <<mkostemps>>
are not standardized.
Supporting OS subroutines required: <<getpid>>, <<mkdir>>, <<open>>, <<stat>>. Supporting OS subroutines required: <<getpid>>, <<mkdir>>, <<open>>, <<stat>>.
*/ */
@ -116,12 +139,13 @@ Supporting OS subroutines required: <<getpid>>, <<mkdir>>, <<open>>, <<stat>>.
#include <ctype.h> #include <ctype.h>
static int static int
_DEFUN(_gettemp, (ptr, path, doopen, domkdir, suffixlen), _DEFUN(_gettemp, (ptr, path, doopen, domkdir, suffixlen, flags),
struct _reent *ptr _AND struct _reent *ptr _AND
char *path _AND char *path _AND
register int *doopen _AND register int *doopen _AND
int domkdir _AND int domkdir _AND
size_t suffixlen) size_t suffixlen _AND
int flags)
{ {
register char *start, *trv; register char *start, *trv;
char *end; char *end;
@ -200,8 +224,8 @@ _DEFUN(_gettemp, (ptr, path, doopen, domkdir, suffixlen),
#endif /* _ELIX_LEVEL */ #endif /* _ELIX_LEVEL */
if (doopen) if (doopen)
{ {
if ((*doopen = _open_r (ptr, path, O_CREAT | O_EXCL | O_RDWR, 0600)) if ((*doopen = _open_r (ptr, path, O_CREAT | O_EXCL | O_RDWR | flags,
>= 0) 0600)) >= 0)
return 1; return 1;
if (ptr->_errno != EEXIST) if (ptr->_errno != EEXIST)
return 0; return 0;
@ -234,6 +258,10 @@ _DEFUN(_gettemp, (ptr, path, doopen, domkdir, suffixlen),
/*NOTREACHED*/ /*NOTREACHED*/
} }
#ifndef O_BINARY
# define O_BINARY 0
#endif
int int
_DEFUN(_mkstemp_r, (ptr, path), _DEFUN(_mkstemp_r, (ptr, path),
struct _reent *ptr _AND struct _reent *ptr _AND
@ -241,7 +269,7 @@ _DEFUN(_mkstemp_r, (ptr, path),
{ {
int fd; int fd;
return (_gettemp (ptr, path, &fd, 0, 0) ? fd : -1); return (_gettemp (ptr, path, &fd, 0, 0, O_BINARY) ? fd : -1);
} }
#if !defined _ELIX_LEVEL || _ELIX_LEVEL >= 4 #if !defined _ELIX_LEVEL || _ELIX_LEVEL >= 4
@ -250,7 +278,7 @@ _DEFUN(_mkdtemp_r, (ptr, path),
struct _reent *ptr _AND struct _reent *ptr _AND
char *path) char *path)
{ {
return (_gettemp (ptr, path, (int *) NULL, 1, 0) ? path : NULL); return (_gettemp (ptr, path, (int *) NULL, 1, 0, 0) ? path : NULL);
} }
int int
@ -261,7 +289,30 @@ _DEFUN(_mkstemps_r, (ptr, path, len),
{ {
int fd; int fd;
return (_gettemp (ptr, path, &fd, 0, len) ? fd : -1); return (_gettemp (ptr, path, &fd, 0, len, O_BINARY) ? fd : -1);
}
int
_DEFUN(_mkostemp_r, (ptr, path, flags),
struct _reent *ptr _AND
char *path _AND
int flags)
{
int fd;
return (_gettemp (ptr, path, &fd, 0, 0, flags & ~O_ACCMODE) ? fd : -1);
}
int
_DEFUN(_mkostemps_r, (ptr, path, len, flags),
struct _reent *ptr _AND
char *path _AND
int len _AND
int flags)
{
int fd;
return (_gettemp (ptr, path, &fd, 0, len, flags & ~O_ACCMODE) ? fd : -1);
} }
#endif /* _ELIX_LEVEL */ #endif /* _ELIX_LEVEL */
@ -270,7 +321,7 @@ _DEFUN(_mktemp_r, (ptr, path),
struct _reent *ptr _AND struct _reent *ptr _AND
char *path) char *path)
{ {
return (_gettemp (ptr, path, (int *) NULL, 0, 0) ? path : (char *) NULL); return (_gettemp (ptr, path, (int *) NULL, 0, 0, 0) ? path : (char *) NULL);
} }
#ifndef _REENT_ONLY #ifndef _REENT_ONLY
@ -281,7 +332,7 @@ _DEFUN(mkstemp, (path),
{ {
int fd; int fd;
return (_gettemp (_REENT, path, &fd, 0, 0) ? fd : -1); return (_gettemp (_REENT, path, &fd, 0, 0, O_BINARY) ? fd : -1);
} }
# if !defined _ELIX_LEVEL || _ELIX_LEVEL >= 4 # if !defined _ELIX_LEVEL || _ELIX_LEVEL >= 4
@ -289,7 +340,7 @@ char *
_DEFUN(mkdtemp, (path), _DEFUN(mkdtemp, (path),
char *path) char *path)
{ {
return (_gettemp (_REENT, path, (int *) NULL, 1, 0) ? path : NULL); return (_gettemp (_REENT, path, (int *) NULL, 1, 0, 0) ? path : NULL);
} }
int int
@ -299,7 +350,28 @@ _DEFUN(mkstemps, (path, len),
{ {
int fd; int fd;
return (_gettemp (_REENT, path, &fd, 0, len) ? fd : -1); return (_gettemp (_REENT, path, &fd, 0, len, O_BINARY) ? fd : -1);
}
int
_DEFUN(mkostemp, (path, flags),
char *path _AND
int flags)
{
int fd;
return (_gettemp (_REENT, path, &fd, 0, 0, flags & ~O_ACCMODE) ? fd : -1);
}
int
_DEFUN(mkostemps, (path, len, flags),
char *path _AND
int len _AND
int flags)
{
int fd;
return (_gettemp (_REENT, path, &fd, 0, len, flags & ~O_ACCMODE) ? fd : -1);
} }
# endif /* _ELIX_LEVEL */ # endif /* _ELIX_LEVEL */
@ -307,7 +379,7 @@ char *
_DEFUN(mktemp, (path), _DEFUN(mktemp, (path),
char *path) char *path)
{ {
return (_gettemp (_REENT, path, (int *) NULL, 0, 0) ? path : (char *) NULL); return (_gettemp (_REENT, path, (int *) NULL, 0, 0, 0) ? path : (char *) NULL);
} }
#endif /* ! defined (_REENT_ONLY) */ #endif /* ! defined (_REENT_ONLY) */