From 8092f467704a09cbfffb553e38f6ca1408c0d9ed Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Mon, 19 Jul 2010 18:21:11 +0000 Subject: [PATCH] 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. --- newlib/ChangeLog | 9 +++ newlib/libc/include/stdlib.h | 8 ++- 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 + + * 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 * 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 -<>, <>, <>---generate unused file name +<>, <>, <>, <>, +<>---generate unused file name <>---generate unused directory INDEX @@ -34,6 +35,10 @@ INDEX mkstemp INDEX mkstemps +INDEX + mkostemp +INDEX + mkostemps INDEX _mktemp_r INDEX @@ -42,6 +47,10 @@ INDEX _mkstemp_r INDEX _mkstemps_r +INDEX + _mkostemp_r +INDEX + _mkostemps_r ANSI_SYNOPSIS #include @@ -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 <>, <>, and <> attempt to generate a file name that is not yet in use for any existing file. <> and <> create the file and open it for reading and writing; <> simply -generates the file name (making <> a security risk). <> -attempts to create a directory instead of a file, with a permissions -mask of 0700. +generates the file name (making <> a security risk). <> +and <> allow the addition of other <> flags, such +as <>, <>, or <>. On platforms with a +separate text mode, <> forces <>, while <> +allows the choice between <>, <>, or 0 for default. +<> 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 <>, the `<>' 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 <> 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 <>. +it returns <>. 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 <>. <> returns the pointer <[path]> to the modified string if the directory was created, otherwise it returns <>. -<> and <> 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>>. +<>, <>, <>, and <> 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 <>. 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 <> or <>; the System V Interface Definition requires <> as of Issue 2. POSIX 2001 -requires <>, and POSIX 2008 requires <>, but -<> is not standardized. +requires <>, and POSIX 2008 requires <> while +deprecating <>. <>, <>, and <> +are not standardized. Supporting OS subroutines required: <>, <>, <>, <>. */ @@ -116,12 +139,13 @@ Supporting OS subroutines required: <>, <>, <>, <>. #include 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) */