This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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)));

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]