This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
add mkstemps
- From: Eric Blake <ebb9 at byu dot net>
- To: newlib at sources dot redhat dot com
- Date: Sat, 27 Jun 2009 16:41:09 -0600
- Subject: add mkstemps
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
The ability to have an arbitrary file suffix on a temporary file is quite
useful for programs that react to a file's extension; in fact, git wants
to use mk[s]temps when available, even though no standards bodies have
adopted it yet. According to google, mkstemps is available on several
systems (sometimes by the more confusing name mktemps), but there is no
consistency on whether it should be in <stdlib.h> or <unistd.h>. I went
with <stdlib.h>, since that is where POSIX puts mkstemp. This also fixes
the documentation (mktemp is NOT in <stdio.h>), but does not move the
files to a more appropriate subdirectory.
OK to apply?
2009-06-27 Eric Blake <ebb9@byu.net>
Add mkstemps.
* libc/stdio/mktemp.c: Fix documentation.
(_gettemp): Add length parameter.
(_mkstemp_r, _mktemp_r, mkstemp, mktemp): Adjust clients.
(_mkstemps_r, mkstemps): New functions.
* libc/include/stdlib.h (_mkstemps_r, mkstemps): Declare them.
- --
Don't work too hard, make some time for fun as well!
Eric Blake ebb9@byu.net
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iEYEARECAAYFAkpGoAUACgkQ84KuGfSFAYB43QCfdlbQ8d34x2u+D3y29jfRAG0u
dPMAoImTaRB0t/0FHcrS3jB0zJ62P9n8
=PJPD
-----END PGP SIGNATURE-----
Index: libc/stdio/mktemp.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/mktemp.c,v
retrieving revision 1.10
diff -u -p -r1.10 mktemp.c
--- libc/stdio/mktemp.c 14 Mar 2009 12:14:08 -0000 1.10
+++ libc/stdio/mktemp.c 27 Jun 2009 22:39:09 -0000
@@ -23,27 +23,33 @@
/*
FUNCTION
-<<mktemp>>, <<mkstemp>>---generate unused file name
+<<mktemp>>, <<mkstemp>>, <<mkstemps>>---generate unused file name
INDEX
mktemp
INDEX
mkstemp
INDEX
+ mkstemps
+INDEX
_mktemp_r
INDEX
_mkstemp_r
+INDEX
+ _mkstemps_r
ANSI_SYNOPSIS
- #include <stdio.h>
+ #include <stdlib.h>
char *mktemp(char *<[path]>);
int mkstemp(char *<[path]>);
+ int mkstemps(char *<[path]>, int <[suffixlen]>);
char *_mktemp_r(struct _reent *<[reent]>, char *<[path]>);
int *_mkstemp_r(struct _reent *<[reent]>, char *<[path]>);
+ int *_mkstemps_r(struct _reent *<[reent]>, char *<[path]>, int <[len]>);
TRAD_SYNOPSIS
- #include <stdio.h>
+ #include <stdlib.h>
char *mktemp(<[path]>)
char *<[path]>;
@@ -59,20 +65,22 @@ TRAD_SYNOPSIS
char *<[path]>;
DESCRIPTION
-<<mktemp>> and <<mkstemp>> attempt to generate a file name that is not
-yet in use for any existing file. <<mkstemp>> creates the file and
-opens it for reading and writing; <<mktemp>> simply generates the 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>>
+create the file and open it for reading and writing; <<mktemp>> simply
+generates the file name (making <<mktemp>> a security risk).
You supply a simple pattern for the generated file name, as the string
at <[path]>. The pattern should be a valid filename (including path
information if you wish) ending with some number of `<<X>>'
characters. The generated filename will match the leading part of the
name you supply, with the trailing `<<X>>' characters replaced by some
-combination of digits and letters.
+combination of digits and letters. With <<mkstemps>>, the `<<X>>'
+characters end <[suffixlen]> bytes before the end of the string.
-The alternate functions <<_mktemp_r>> and <<_mkstemp_r>> are reentrant
-versions. The extra argument <[reent]> is a pointer to a reentrancy
-structure.
+The alternate functions <<_mktemp_r>>, <<_mkstemp_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
@@ -80,7 +88,7 @@ representing an unused filename, unless
the pattern you provided is not suitable for a filename; in that case,
it returns <<NULL>>.
-<<mkstemp>> returns a file descriptor to the newly created file,
+<<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>>.
@@ -94,7 +102,8 @@ instead. It doesn't suffer the race con
PORTABILITY
ANSI C does not require either <<mktemp>> or <<mkstemp>>; the System
-V Interface Definition requires <<mktemp>> as of Issue 2.
+V Interface Definition requires <<mktemp>> as of Issue 2. POSIX
+requires <<mkstemp>>, but <<mkstemps>> is not standardized.
Supporting OS subroutines required: <<getpid>>, <<open>>, <<stat>>.
*/
@@ -109,10 +118,11 @@ Supporting OS subroutines required: <<ge
#include <ctype.h>
static int
-_DEFUN(_gettemp, (ptr, path, doopen),
+_DEFUN(_gettemp, (ptr, path, doopen, suffixlen),
struct _reent *ptr _AND
char *path _AND
- register int *doopen)
+ register int *doopen _AND
+ int suffixlen)
{
register char *start, *trv;
#ifdef __USE_INTERNAL_STAT64
@@ -125,6 +135,7 @@ _DEFUN(_gettemp, (ptr, path, doopen),
pid = _getpid_r (ptr);
for (trv = path; *trv; ++trv) /* extra X's get set to 0's */
continue;
+ trv -= suffixlen;
while (*--trv == 'X')
{
*trv = (pid % 10) + '0';
@@ -207,7 +218,18 @@ _DEFUN(_mkstemp_r, (ptr, path),
{
int fd;
- return (_gettemp (ptr, path, &fd) ? fd : -1);
+ return (_gettemp (ptr, path, &fd, 0) ? fd : -1);
+}
+
+int
+_DEFUN(_mkstemps_r, (ptr, path, len),
+ struct _reent *ptr _AND
+ char *path _AND
+ int len)
+{
+ int fd;
+
+ return (_gettemp (ptr, path, &fd, len) ? fd : -1);
}
char *
@@ -215,7 +237,7 @@ _DEFUN(_mktemp_r, (ptr, path),
struct _reent *ptr _AND
char *path)
{
- return (_gettemp (ptr, path, (int *) NULL) ? path : (char *) NULL);
+ return (_gettemp (ptr, path, (int *) NULL, 0) ? path : (char *) NULL);
}
#ifndef _REENT_ONLY
@@ -226,14 +248,24 @@ _DEFUN(mkstemp, (path),
{
int fd;
- return (_gettemp (_REENT, path, &fd) ? fd : -1);
+ return (_gettemp (_REENT, path, &fd, 0) ? fd : -1);
+}
+
+int
+_DEFUN(mkstemps, (path, len),
+ char *path _AND
+ int len)
+{
+ int fd;
+
+ return (_gettemp (_REENT, path, &fd, len) ? fd : -1);
}
char *
_DEFUN(mktemp, (path),
char *path)
{
- return (_gettemp (_REENT, path, (int *) NULL) ? path : (char *) NULL);
+ return (_gettemp (_REENT, path, (int *) NULL, 0) ? path : (char *) NULL);
}
#endif /* ! defined (_REENT_ONLY) */
Index: libc/include/stdlib.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/include/stdlib.h,v
retrieving revision 1.34
diff -u -p -r1.34 stdlib.h
--- libc/include/stdlib.h 24 Apr 2009 22:49:55 -0000 1.34
+++ libc/include/stdlib.h 27 Jun 2009 22:39:09 -0000
@@ -99,9 +99,11 @@ size_t _EXFUN(_wcstombs_r,(struct _reent
#ifndef __STRICT_ANSI__
#ifndef _REENT_ONLY
int _EXFUN(mkstemp,(char *));
+int _EXFUN(mkstemps,(char *, int));
char * _EXFUN(mktemp,(char *) _ATTRIBUTE ((warning ("the use of `mktemp' is dangerous; use `mkstemp' instead"))));
#endif
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"))));
#endif
_VOID _EXFUN(qsort,(_PTR __base, size_t __nmemb, size_t __size, int(*_compar)(const _PTR, const _PTR)));