Here is a proposal to add a module 'mkostemp', using the source code changes from glibc. It also reduces the diffs to glibc, by incorporating parts of this glibc commit: http://sourceware.org/git/?p=glibc.git;a=commitdiff;h=d7e23b02a40384be1eaf00762ea36fd117c462cd
Opinions? Objections? 2009-08-22 Bruno Haible <br...@clisp.org> New module 'mkostemp'. * lib/stdlib.in.h (mksotemp): New declaration. * lib/mkostemp.c: New file, from glibc with modifications. * lib/tempname.h (GT_FILE): Remove outdated comment. (gen_tempname): Add flags argument. * lib/tempname.c (__GT_BIGFILE): Remove macro. (__GT_FILE): Map to 1. (small_open, large_open): Remove macros. (__gen_tempname): Add flags argument. Remove code for __GT_BIGFILE. * lib/mkstemp.c (mkstemp): Update. * lib/mkdtemp.c (mkdtemp): Likewise. * m4/mkostemp.m4: New file. * m4/stdlib_h.m4 (gl_STDLIB_H_DEFAULTS): Initialize GNULIB_MKOSTEMP, HAVE_MKOSTEMP. * modules/stdlib (Makefile.am): Substitute GNULIB_MKOSTEMP, HAVE_MKOSTEMP. * modules/mkostemp: New file, based on modules/mkstemp. * doc/glibc-functions/mkostemp.texi: Mention the new module. ================================ lib/mkostemp.c ================================ /* Copyright (C) 1998, 1999, 2001, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. This file is derived from the one in the GNU C Library. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #if !_LIBC # include <config.h> #endif #include <stdlib.h> #if !_LIBC # include "tempname.h" # define __gen_tempname gen_tempname # define __GT_FILE GT_FILE #endif #include <stdio.h> #ifndef __GT_FILE # define __GT_FILE 0 #endif /* Generate a unique temporary file name from TEMPLATE. The last six characters of TEMPLATE must be "XXXXXX"; they are replaced with a string that makes the file name unique. Then open the file and return a fd. */ int mkostemp (template, flags) char *template; int flags; { return __gen_tempname (template, flags, __GT_FILE); } ================================ m4/mkostemp.m4 ================================ # mkostemp.m4 serial 1 dnl Copyright (C) 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_FUNC_MKOSTEMP], [ AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) dnl Persuade glibc <stdlib.h> to declare mkostemp(). AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) AC_CHECK_FUNCS_ONCE([mkostemp]) if test $ac_cv_func_mkostemp != yes; then HAVE_MKOSTEMP=0 AC_LIBOBJ([mkostemp]) gl_PREREQ_MKOSTEMP fi ]) # Prerequisites of lib/mkostemp.c. AC_DEFUN([gl_PREREQ_MKOSTEMP], [ ]) =============================== modules/mkostemp =============================== Description: mkostemp() function: create a private temporary file, with specific opening flags. Files: lib/mkostemp.c m4/mkostemp.m4 Depends-on: extensions stdlib tempname configure.ac: gl_FUNC_MKOSTEMP gl_STDLIB_MODULE_INDICATOR([mkostemp]) Makefile.am: Include: <stdlib.h> License: LGPLv2+ Maintainer: Jim Meyering, Bruno Haible ================================================================================ --- doc/glibc-functions/mkostemp.texi.orig 2009-08-23 01:16:42.000000000 +0200 +++ doc/glibc-functions/mkostemp.texi 2009-08-23 00:08:59.000000000 +0200 @@ -2,15 +2,15 @@ @subsection @code{mkostemp} @findex mkostemp -Gnulib module: --- +Gnulib module: mkostemp Portability problems fixed by Gnulib: @itemize +...@item +This function is missing on all non-glibc platforms: +MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin, mingw, Interix 3.5, BeOS. @end itemize Portability problems not fixed by Gnulib: @itemize -...@item -This function is missing on all non-glibc platforms: -MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin, mingw, Interix 3.5, BeOS. @end itemize --- lib/mkdtemp.c.orig 2009-08-23 01:16:42.000000000 +0200 +++ lib/mkdtemp.c 2009-08-23 00:08:10.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2001-2003, 2006-2007 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2001-2003, 2006-2007, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. This program is free software: you can redistribute it and/or modify @@ -31,7 +31,7 @@ char * mkdtemp (char *template) { - if (gen_tempname (template, GT_DIR)) + if (gen_tempname (template, 0, GT_DIR)) return NULL; else return template; --- lib/mkstemp.c.orig 2009-08-23 01:16:42.000000000 +0200 +++ lib/mkstemp.c 2009-08-22 23:52:00.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999, 2001, 2005, 2006, 2007 Free Software Foundation, Inc. +/* Copyright (C) 1998, 1999, 2001, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. This file is derived from the one in the GNU C Library. This program is free software: you can redistribute it and/or modify @@ -40,5 +40,5 @@ mkstemp (template) char *template; { - return __gen_tempname (template, __GT_FILE); + return __gen_tempname (template, 0, __GT_FILE); } --- lib/stdlib.in.h.orig 2009-08-23 01:16:42.000000000 +0200 +++ lib/stdlib.in.h 2009-08-22 23:58:21.000000000 +0200 @@ -207,6 +207,29 @@ #endif +#if @GNULIB_MKOSTEMP@ +# if !...@have_mkostemp@ +/* Create a unique temporary file from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the file name unique. + The file is then created, with the specified flags, ensuring it didn't exist + before. + The file is created read-write (mask at least 0600 & ~umask), but it may be + world-readable and world-writable (mask 0666 & ~umask), depending on the + implementation. + Returns the open file descriptor if successful, otherwise -1 and errno + set. */ +extern int mkostemp (char * /*template*/, int /*flags*/); +# endif +#elif defined GNULIB_POSIXCHECK +# undef mksotemp +# define mksotemp(t,f) \ + (GL_LINK_WARNING ("mkostemp is unportable - " \ + "use gnulib module mkostemp for portability"), \ + mksotemp (t, f)) +#endif + + #if @GNULIB_MKSTEMP@ # if @REPLACE_MKSTEMP@ /* Create a unique temporary file from TEMPLATE. --- lib/tempname.c.orig 2009-08-23 01:16:42.000000000 +0200 +++ lib/tempname.c 2009-08-23 01:15:25.000000000 +0200 @@ -1,7 +1,7 @@ /* tempname.c - generate the name of a temporary file. Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2005, 2006, 2007 Free Software Foundation, + 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -40,8 +40,7 @@ # define TMP_MAX 238328 #endif #ifndef __GT_FILE -# define __GT_FILE 0 -# define __GT_BIGFILE 1 +# define __GT_FILE 1 # define __GT_DIR 2 # define __GT_NOCREATE 3 #endif @@ -59,12 +58,9 @@ #if _LIBC # define struct_stat64 struct stat64 -# define small_open __open -# define large_open __open64 #else # define struct_stat64 struct stat -# define small_open open -# define large_open open +# define __open open # define __gen_tempname gen_tempname # define __getpid getpid # define __gettimeofday gettimeofday @@ -192,12 +188,11 @@ at the time of the call. __GT_FILE: create the file using open(O_CREAT|O_EXCL) and return a read-write fd. The file is mode 0600. - __GT_BIGFILE: same as __GT_FILE but use open64(). __GT_DIR: create a directory, which will be mode 0700. We use a clever algorithm to get hard-to-predict names. */ int -__gen_tempname (char *tmpl, int kind) +__gen_tempname (char *tmpl, int flags, int kind) { int len; char *XXXXXX; @@ -266,11 +261,9 @@ switch (kind) { case __GT_FILE: - fd = small_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); - break; - - case __GT_BIGFILE: - fd = large_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); + fd = __open (tmpl, + (flags & ~0777) | O_RDWR | O_CREAT | O_EXCL, + S_IRUSR | S_IWUSR); break; case __GT_DIR: --- lib/tempname.h.orig 2009-08-23 01:16:42.000000000 +0200 +++ lib/tempname.h 2009-08-23 01:16:40.000000000 +0200 @@ -1,6 +1,6 @@ /* Create a temporary file or directory. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,8 +17,6 @@ /* header written by Eric Blake */ -/* In gnulib, always prefer large files. GT_FILE maps to - __GT_BIGFILE, not __GT_FILE, for a reason. */ #define GT_FILE 1 #define GT_DIR 2 #define GT_NOCREATE 3 @@ -36,4 +34,4 @@ GT_DIR: create a directory, which will be mode 0700. We use a clever algorithm to get hard-to-predict names. */ -extern int gen_tempname (char *tmpl, int kind); +extern int gen_tempname (char *tmpl, int flags, int kind); --- m4/stdlib_h.m4.orig 2009-08-23 01:16:42.000000000 +0200 +++ m4/stdlib_h.m4 2009-08-22 23:58:56.000000000 +0200 @@ -1,4 +1,4 @@ -# stdlib_h.m4 serial 15 +# stdlib_h.m4 serial 16 dnl Copyright (C) 2007-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -40,6 +40,7 @@ GNULIB_GETLOADAVG=0; AC_SUBST([GNULIB_GETLOADAVG]) GNULIB_GETSUBOPT=0; AC_SUBST([GNULIB_GETSUBOPT]) GNULIB_MKDTEMP=0; AC_SUBST([GNULIB_MKDTEMP]) + GNULIB_MKOSTEMP=0; AC_SUBST([GNULIB_MKOSTEMP]) GNULIB_MKSTEMP=0; AC_SUBST([GNULIB_MKSTEMP]) GNULIB_PUTENV=0; AC_SUBST([GNULIB_PUTENV]) GNULIB_RANDOM_R=0; AC_SUBST([GNULIB_RANDOM_R]) @@ -55,6 +56,7 @@ HAVE_GETSUBOPT=1; AC_SUBST([HAVE_GETSUBOPT]) HAVE_MALLOC_POSIX=1; AC_SUBST([HAVE_MALLOC_POSIX]) HAVE_MKDTEMP=1; AC_SUBST([HAVE_MKDTEMP]) + HAVE_MKOSTEMP=1; AC_SUBST([HAVE_MKOSTEMP]) HAVE_REALLOC_POSIX=1; AC_SUBST([HAVE_REALLOC_POSIX]) HAVE_RANDOM_R=1; AC_SUBST([HAVE_RANDOM_R]) HAVE_RPMATCH=1; AC_SUBST([HAVE_RPMATCH]) --- modules/stdlib.orig 2009-08-23 01:16:42.000000000 +0200 +++ modules/stdlib 2009-08-22 23:56:13.000000000 +0200 @@ -34,6 +34,7 @@ -e 's|@''GNULIB_GETLOADAVG''@|$(GNULIB_GETLOADAVG)|g' \ -e 's|@''GNULIB_GETSUBOPT''@|$(GNULIB_GETSUBOPT)|g' \ -e 's|@''GNULIB_MKDTEMP''@|$(GNULIB_MKDTEMP)|g' \ + -e 's|@''GNULIB_MKOSTEMP''@|$(GNULIB_MKOSTEMP)|g' \ -e 's|@''GNULIB_MKSTEMP''@|$(GNULIB_MKSTEMP)|g' \ -e 's|@''GNULIB_PUTENV''@|$(GNULIB_PUTENV)|g' \ -e 's|@''GNULIB_RANDOM_R''@|$(GNULIB_RANDOM_R)|g' \ @@ -48,6 +49,7 @@ -e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \ -e 's|@''HAVE_MALLOC_POSIX''@|$(HAVE_MALLOC_POSIX)|g' \ -e 's|@''HAVE_MKDTEMP''@|$(HAVE_MKDTEMP)|g' \ + -e 's|@''HAVE_MKOSTEMP''@|$(HAVE_MKOSTEMP)|g' \ -e 's|@''HAVE_REALLOC_POSIX''@|$(HAVE_REALLOC_POSIX)|g' \ -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \ -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \