diff options
Diffstat (limited to 'newlib')
-rw-r--r-- | newlib/ChangeLog | 9 | ||||
-rw-r--r-- | newlib/libc/include/stdlib.h | 8 | ||||
-rw-r--r-- | newlib/libc/stdio/mktemp.c | 122 |
3 files changed, 112 insertions, 27 deletions
diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 18591ce16..35a7cefb9 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -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> * libc/include/signal.h (sighandler_t): Only define if _POSIX_SOURCE diff --git a/newlib/libc/include/stdlib.h b/newlib/libc/include/stdlib.h index 453bb505f..0bd2c7d7f 100644 --- a/newlib/libc/include/stdlib.h +++ b/newlib/libc/include/stdlib.h @@ -103,14 +103,18 @@ size_t _EXFUN(_wcstombs_r,(struct _reent *, char *, const wchar_t *, size_t, _mb #ifndef __STRICT_ANSI__ #ifndef _REENT_ONLY char * _EXFUN(mkdtemp,(char *)); +int _EXFUN(mkostemp,(char *, int)); +int _EXFUN(mkostemps,(char *, int, int)); int _EXFUN(mkstemp,(char *)); 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 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(_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 _VOID _EXFUN(qsort,(_PTR __base, size_t __nmemb, size_t __size, int(*_compar)(const _PTR, const _PTR))); int _EXFUN(rand,(_VOID)); diff --git a/newlib/libc/stdio/mktemp.c b/newlib/libc/stdio/mktemp.c index cfd74ad39..1c5d76db4 100644 --- a/newlib/libc/stdio/mktemp.c +++ b/newlib/libc/stdio/mktemp.c @@ -23,7 +23,8 @@ /* FUNCTION -<<mktemp>>, <<mkstemp>>, <<mkstemps>>---generate unused file name +<<mktemp>>, <<mkstemp>>, <<mkostemp>>, <<mkstemps>>, +<<mkostemps>>---generate unused file name <<mkdtemp>>---generate unused directory INDEX @@ -35,6 +36,10 @@ INDEX INDEX mkstemps INDEX + mkostemp +INDEX + mkostemps +INDEX _mktemp_r INDEX _mkdtemp_r @@ -42,6 +47,10 @@ INDEX _mkstemp_r INDEX _mkstemps_r +INDEX + _mkostemp_r +INDEX + _mkostemps_r ANSI_SYNOPSIS #include <stdlib.h> @@ -49,19 +58,29 @@ ANSI_SYNOPSIS char *mkdtemp(char *<[path]>); int mkstemp(char *<[path]>); 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 *_mkdtemp_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 *_mkostemp_r(struct _reent *<[reent]>, char *<[path]>, + int <[flags]>); + int *_mkostemps_r(struct _reent *<[reent]>, char *<[path]>, int <[len]>, + int <[flags]>); DESCRIPTION <<mktemp>>, <<mkstemp>>, and <<mkstemps>> attempt to generate a file name 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 -generates the file name (making <<mktemp>> a security risk). <<mkdtemp>> -attempts to create a directory instead of a file, with a permissions -mask of 0700. +generates the file name (making <<mktemp>> a security risk). <<mkostemp>> +and <<mkostemps>> allow the addition of other <<open>> flags, such +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 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. The alternate functions <<_mktemp_r>>, <<_mkdtemp_r>>, <<_mkstemp_r>>, -and <<_mkstemps_r>> are reentrant versions. The extra argument <[reent]> -is a pointer to a reentrancy structure. +<<_mkostemp_r>>, <<_mkostemps_r>>, and <<_mkstemps_r>> are reentrant +versions. The extra argument <[reent]> is a pointer to a reentrancy +structure. RETURNS <<mktemp>> returns the pointer <[path]> to the modified string representing an unused filename, unless it could not generate one, or 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 directory was created, otherwise it returns <<NULL>>. -<<mkstemp>> and <<mkstemps>> return a file descriptor to the newly created -file, unless it could not generate an unused filename, or the pattern you -provided is not suitable for a filename; in that case, it returns -<<-1>>. +<<mkstemp>>, <<mkstemps>>, <<mkostemp>>, and <<mkostemps>> return a file +descriptor to the newly created file, unless it could not generate an +unused filename, or the pattern you provided is not suitable for a +filename; in that case, it returns <<-1>>. NOTES Never use <<mktemp>>. The generated filenames are easy to guess and @@ -99,8 +121,9 @@ instead. It doesn't suffer the race condition. PORTABILITY ANSI C does not require either <<mktemp>> or <<mkstemp>>; the System V Interface Definition requires <<mktemp>> as of Issue 2. POSIX 2001 -requires <<mkstemp>>, and POSIX 2008 requires <<mkdtemp>>, but -<<mkstemps>> is not standardized. +requires <<mkstemp>>, and POSIX 2008 requires <<mkdtemp>> while +deprecating <<mktemp>>. <<mkstemps>>, <<mkostemp>>, and <<mkostemps>> +are not standardized. Supporting OS subroutines required: <<getpid>>, <<mkdir>>, <<open>>, <<stat>>. */ @@ -116,12 +139,13 @@ Supporting OS subroutines required: <<getpid>>, <<mkdir>>, <<open>>, <<stat>>. #include <ctype.h> static int -_DEFUN(_gettemp, (ptr, path, doopen, domkdir, suffixlen), +_DEFUN(_gettemp, (ptr, path, doopen, domkdir, suffixlen, flags), struct _reent *ptr _AND char *path _AND register int *doopen _AND int domkdir _AND - size_t suffixlen) + size_t suffixlen _AND + int flags) { register char *start, *trv; char *end; @@ -200,8 +224,8 @@ _DEFUN(_gettemp, (ptr, path, doopen, domkdir, suffixlen), #endif /* _ELIX_LEVEL */ if (doopen) { - if ((*doopen = _open_r (ptr, path, O_CREAT | O_EXCL | O_RDWR, 0600)) - >= 0) + if ((*doopen = _open_r (ptr, path, O_CREAT | O_EXCL | O_RDWR | flags, + 0600)) >= 0) return 1; if (ptr->_errno != EEXIST) return 0; @@ -234,6 +258,10 @@ _DEFUN(_gettemp, (ptr, path, doopen, domkdir, suffixlen), /*NOTREACHED*/ } +#ifndef O_BINARY +# define O_BINARY 0 +#endif + int _DEFUN(_mkstemp_r, (ptr, path), struct _reent *ptr _AND @@ -241,7 +269,7 @@ _DEFUN(_mkstemp_r, (ptr, path), { 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 @@ -250,7 +278,7 @@ _DEFUN(_mkdtemp_r, (ptr, path), struct _reent *ptr _AND char *path) { - return (_gettemp (ptr, path, (int *) NULL, 1, 0) ? path : NULL); + return (_gettemp (ptr, path, (int *) NULL, 1, 0, 0) ? path : NULL); } int @@ -261,7 +289,30 @@ _DEFUN(_mkstemps_r, (ptr, path, len), { 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 */ @@ -270,7 +321,7 @@ _DEFUN(_mktemp_r, (ptr, path), struct _reent *ptr _AND 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 @@ -281,7 +332,7 @@ _DEFUN(mkstemp, (path), { 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 @@ -289,7 +340,7 @@ char * _DEFUN(mkdtemp, (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 @@ -299,7 +350,28 @@ _DEFUN(mkstemps, (path, len), { 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 */ @@ -307,7 +379,7 @@ char * _DEFUN(mktemp, (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) */ |