From d7e23b02a40384be1eaf00762ea36fd117c462cd Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 11 Aug 2007 02:48:28 +0000 Subject: [PATCH] * nscd/connections.c: Use O_CLOEXEC is possible. Use mkostemp instead of mkstemp. * misc/Makefile (routines): Add mkostemp and mkostemp64. * misc/Versions: Export mkostemp and mkostemp64 for GLIBC_2.7. * misc/mkostemp.c: New file. * misc/mkostemp64.c: New file. * stdlib/stdlib.h: Declare the new functions. * sysdeps/posix/tempname.c: Add new parameter which is added to the flags for open. Remove __GT_BIGFILE handling. * stdio-common/tempname.c: Likewise. * include/stdio.h: Adjust __gen_tempname prototype. Renumber __GT_* constants. * libio/oldtmpfile.c: Adjust for __gen_tempname interface change. * misc/mkdtemp.c: Likewise. * misc/mkstemp.c: Likewise. * misc/mkstemp64.c: Likewise. * misc/mktemp.c: Likewise. * stdio-common/tempnam.c: Likewise. * stdio-common/tmpfile.c: Likewise. * stdio-common/tmpfile64.c: Likewise. * stdio-common/tmpnam.c: Likewise. * stdio-common/tmpnam_r.c: Likewise. --- ChangeLog | 26 ++++++++++++++++++++++++++ include/stdio.h | 7 +++---- libio/oldtmpfile.c | 5 +++-- misc/Makefile | 3 ++- misc/Versions | 3 +++ misc/mkdtemp.c | 4 ++-- misc/mkostemp.c | 36 ++++++++++++++++++++++++++++++++++++ misc/mkostemp64.c | 33 +++++++++++++++++++++++++++++++++ misc/mkstemp.c | 4 ++-- misc/mkstemp64.c | 5 +++-- misc/mktemp.c | 4 ++-- nscd/connections.c | 27 +++++++++++++++++++++------ stdio-common/tempnam.c | 4 ++-- stdio-common/tempname.c | 5 +++-- stdio-common/tmpfile.c | 15 +++++++++------ stdio-common/tmpfile64.c | 4 ++-- stdio-common/tmpnam.c | 4 ++-- stdio-common/tmpnam_r.c | 4 ++-- stdlib/stdlib.h | 22 ++++++++++++++++++++++ sysdeps/posix/tempname.c | 18 +++++++----------- 20 files changed, 185 insertions(+), 48 deletions(-) create mode 100644 misc/mkostemp.c create mode 100644 misc/mkostemp64.c diff --git a/ChangeLog b/ChangeLog index cc2035f..2213f6b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2007-08-10 Ulrich Drepper + + * nscd/connections.c: Use O_CLOEXEC is possible. Use mkostemp + instead of mkstemp. + + * misc/Makefile (routines): Add mkostemp and mkostemp64. + * misc/Versions: Export mkostemp and mkostemp64 for GLIBC_2.7. + * misc/mkostemp.c: New file. + * misc/mkostemp64.c: New file. + * stdlib/stdlib.h: Declare the new functions. + * sysdeps/posix/tempname.c: Add new parameter which is added to + the flags for open. Remove __GT_BIGFILE handling. + * stdio-common/tempname.c: Likewise. + * include/stdio.h: Adjust __gen_tempname prototype. + Renumber __GT_* constants. + * libio/oldtmpfile.c: Adjust for __gen_tempname interface change. + * misc/mkdtemp.c: Likewise. + * misc/mkstemp.c: Likewise. + * misc/mkstemp64.c: Likewise. + * misc/mktemp.c: Likewise. + * stdio-common/tempnam.c: Likewise. + * stdio-common/tmpfile.c: Likewise. + * stdio-common/tmpfile64.c: Likewise. + * stdio-common/tmpnam.c: Likewise. + * stdio-common/tmpnam_r.c: Likewise. + 2007-08-10 Roland McGrath * sysdeps/mach/hurd/bits/ioctls.h (NLDLY, TABDLY, BSDLY, VTDLY): diff --git a/include/stdio.h b/include/stdio.h index 6fe881c..748523d 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -54,12 +54,11 @@ extern int __path_search (char *__tmpl, size_t __tmpl_len, __const char *__dir, __const char *__pfx, int __try_tempdir); -extern int __gen_tempname (char *__tmpl, int __kind); +extern int __gen_tempname (char *__tmpl, int __flags, int __kind); /* The __kind argument to __gen_tempname may be one of: */ # define __GT_FILE 0 /* create a file */ -# define __GT_BIGFILE 1 /* create a file, using open64 */ -# define __GT_DIR 2 /* create a directory */ -# define __GT_NOCREATE 3 /* just find a name not currently in use */ +# define __GT_DIR 1 /* create a directory */ +# define __GT_NOCREATE 2 /* just find a name not currently in use */ /* Print out MESSAGE on the error output and abort. */ extern void __libc_fatal (__const char *__message) diff --git a/libio/oldtmpfile.c b/libio/oldtmpfile.c index 8631d48..d85467a 100644 --- a/libio/oldtmpfile.c +++ b/libio/oldtmpfile.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1991,1993,1996-2000,2003,2004 Free Software Foundation, Inc. +/* Copyright (C) 1991,1993,1996-2000,2003,2004,2007 + Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -38,7 +39,7 @@ __old_tmpfile (void) if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0)) return NULL; - fd = __gen_tempname (buf, __GT_FILE); + fd = __gen_tempname (buf, 0, __GT_FILE); if (fd < 0) return NULL; diff --git a/misc/Makefile b/misc/Makefile index 9eac1b6..a9709f9 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1991-2002,2003,2004,2005,2006 Free Software Foundation, Inc. +# Copyright (C) 1991-2006, 2007 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -45,6 +45,7 @@ routines := brk sbrk sstk ioctl \ gethostid sethostid \ revoke vhangup \ swapon swapoff mktemp mkstemp mkstemp64 mkdtemp \ + mkostemp mkostemp64 \ ualarm usleep \ gtty stty \ ptrace \ diff --git a/misc/Versions b/misc/Versions index fdf2d9d..b182f12 100644 --- a/misc/Versions +++ b/misc/Versions @@ -134,4 +134,7 @@ libc { futimesat; __syslog_chk; __vsyslog_chk; } + GLIBC_2.7 { + mkostemp; mkostemp64; + } } diff --git a/misc/mkdtemp.c b/misc/mkdtemp.c index abb9a35..7cd3a44 100644 --- a/misc/mkdtemp.c +++ b/misc/mkdtemp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1999 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,7 @@ char * mkdtemp (template) char *template; { - if (__gen_tempname (template, __GT_DIR)) + if (__gen_tempname (template, 0, __GT_DIR)) return NULL; else return template; diff --git a/misc/mkostemp.c b/misc/mkostemp.c new file mode 100644 index 0000000..372e4f3 --- /dev/null +++ b/misc/mkostemp.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1998, 1999, 2001, 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +#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 filename unique. + Then open the file and return a fd. */ +int +mkostemp (template, flags) + char *template; + int flags; +{ + return __gen_tempname (template, flags, __GT_FILE); +} diff --git a/misc/mkostemp64.c b/misc/mkostemp64.c new file mode 100644 index 0000000..2ae7309 --- /dev/null +++ b/misc/mkostemp64.c @@ -0,0 +1,33 @@ +/* Copyright (C) 2000, 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + +/* 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 filename unique. + Then open the file and return a fd. */ +int +mkostemp64 (template, flags) + char *template; + int flags; +{ + return __gen_tempname (template, flags | O_LARGEFILE, __GT_FILE); +} diff --git a/misc/mkstemp.c b/misc/mkstemp.c index ff0ffa2..d3edca0 100644 --- a/misc/mkstemp.c +++ b/misc/mkstemp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1998, 1999, 2001, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -31,5 +31,5 @@ int mkstemp (template) char *template; { - return __gen_tempname (template, __GT_FILE); + return __gen_tempname (template, 0, __GT_FILE); } diff --git a/misc/mkstemp64.c b/misc/mkstemp64.c index 93c2a3e..400bf47 100644 --- a/misc/mkstemp64.c +++ b/misc/mkstemp64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -16,6 +16,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include #include #include @@ -27,5 +28,5 @@ int mkstemp64 (template) char *template; { - return __gen_tempname (template, __GT_BIGFILE); + return __gen_tempname (template, O_LARGEFILE, __GT_FILE); } diff --git a/misc/mktemp.c b/misc/mktemp.c index 20dfc74..f600d7e 100644 --- a/misc/mktemp.c +++ b/misc/mktemp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1998, 1999, 2000, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -26,7 +26,7 @@ char * mktemp (template) char *template; { - if (__gen_tempname (template, __GT_NOCREATE) < 0) + if (__gen_tempname (template, 0, __GT_NOCREATE) < 0) /* We return the null string if we can't find a unique file name. */ template[0] = '\0'; diff --git a/nscd/connections.c b/nscd/connections.c index 48e91e8..20b676e 100644 --- a/nscd/connections.c +++ b/nscd/connections.c @@ -468,6 +468,13 @@ fail: } +#ifdef O_CLOEXEC +# define EXTRA_O_FLAGS O_CLOEXEC +#else +# define EXTRA_O_FLAGS 0 +#endif + + /* Initialize database information structures. */ void nscd_init (void) @@ -490,7 +497,7 @@ nscd_init (void) if (dbs[cnt].persistent) { /* Try to open the appropriate file on disk. */ - int fd = open (dbs[cnt].db_filename, O_RDWR); + int fd = open (dbs[cnt].db_filename, O_RDWR | EXTRA_O_FLAGS); if (fd != -1) { struct stat64 st; @@ -569,7 +576,8 @@ nscd_init (void) /* We also need a read-only descriptor. */ if (dbs[cnt].shared) { - dbs[cnt].ro_fd = open (dbs[cnt].db_filename, O_RDONLY); + dbs[cnt].ro_fd = open (dbs[cnt].db_filename, + O_RDONLY | EXTRA_O_FLAGS); if (dbs[cnt].ro_fd == -1) dbg_log (_("\ cannot create read-only descriptor for \"%s\"; no mmap"), @@ -606,22 +614,23 @@ cannot create read-only descriptor for \"%s\"; no mmap"), if (dbs[cnt].persistent) { fd = open (dbs[cnt].db_filename, - O_RDWR | O_CREAT | O_EXCL | O_TRUNC, + O_RDWR | O_CREAT | O_EXCL | O_TRUNC | EXTRA_O_FLAGS, S_IRUSR | S_IWUSR); if (fd != -1 && dbs[cnt].shared) - ro_fd = open (dbs[cnt].db_filename, O_RDONLY); + ro_fd = open (dbs[cnt].db_filename, + O_RDONLY | EXTRA_O_FLAGS); } else { char fname[] = _PATH_NSCD_XYZ_DB_TMP; - fd = mkstemp (fname); + fd = mkostemp (fname, EXTRA_O_FLAGS); /* We do not need the file name anymore after we opened another file descriptor in read-only mode. */ if (fd != -1) { if (dbs[cnt].shared) - ro_fd = open (fname, O_RDONLY); + ro_fd = open (fname, O_RDONLY | EXTRA_O_FLAGS); unlink (fname); } @@ -740,6 +749,11 @@ cannot create read-only descriptor for \"%s\"; no mmap"), } } +#if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC + /* We do not check here whether the O_CLOEXEC provided to the + open call was successful or not. The two fcntl calls are + only performed once each per process start-up and therefore + is not noticeable at all. */ if (paranoia && ((dbs[cnt].wr_fd != -1 && fcntl (dbs[cnt].wr_fd, F_SETFD, FD_CLOEXEC) == -1) @@ -751,6 +765,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"), strerror (errno)); paranoia = 0; } +#endif if (dbs[cnt].head == NULL) { diff --git a/stdio-common/tempnam.c b/stdio-common/tempnam.c index cd3dd40..c631d46 100644 --- a/stdio-common/tempnam.c +++ b/stdio-common/tempnam.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,1993,1996-1999,2000 Free Software Foundation, Inc. +/* Copyright (C) 1991,1993,1996-2000,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -34,7 +34,7 @@ tempnam (const char *dir, const char *pfx) if (__path_search (buf, FILENAME_MAX, dir, pfx, 1)) return NULL; - if (__gen_tempname (buf, __GT_NOCREATE)) + if (__gen_tempname (buf, 0, __GT_NOCREATE)) return NULL; return __strdup (buf); diff --git a/stdio-common/tempname.c b/stdio-common/tempname.c index 60c94d6..2c7bcde 100644 --- a/stdio-common/tempname.c +++ b/stdio-common/tempname.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 92, 93, 95-98, 99 Free Software Foundation, Inc. +/* Copyright (C) 1991, 92, 93, 95-98, 99, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -47,8 +47,9 @@ stub_warning (__path_search) */ int -__gen_tempname (tmpl, kind) +__gen_tempname (tmpl, flags, kind) char *tmpl; + int flags; int kind; { __set_errno (ENOSYS); diff --git a/stdio-common/tmpfile.c b/stdio-common/tmpfile.c index 41f12bc..b900513 100644 --- a/stdio-common/tmpfile.c +++ b/stdio-common/tmpfile.c @@ -1,5 +1,6 @@ /* Open a stdio stream on an anonymous temporary file. Generic/POSIX version. - Copyright (C) 1991,93,1996-2000,2002,2003 Free Software Foundation, Inc. + Copyright (C) 1991,1993,1996-2000,2002,2003,2007 + Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,6 +18,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include #include #include @@ -28,9 +30,6 @@ # endif #endif -#ifndef GEN_THIS -# define GEN_THIS __GT_FILE -#endif /* This returns a new stream opened on a temporary file (generated by tmpnam). The file is opened with mode "w+b" (binary read/write). @@ -45,7 +44,11 @@ tmpfile (void) if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0)) return NULL; - fd = __gen_tempname (buf, GEN_THIS); + int flags = 0; +#ifdef FLAGS + flags = FLAGS; +#endif + fd = __gen_tempname (buf, flags, __GT_FILE); if (fd < 0) return NULL; @@ -59,7 +62,7 @@ tmpfile (void) return f; } -#if defined USE_IN_LIBIO && GEN_THIS == __GT_FILE /* Not for tmpfile64. */ +#if defined USE_IN_LIBIO && !defined FLAGS /* Not for tmpfile64. */ # undef tmpfile # include versioned_symbol (libc, __new_tmpfile, tmpfile, GLIBC_2_1); diff --git a/stdio-common/tmpfile64.c b/stdio-common/tmpfile64.c index b265aee..ead3f50 100644 --- a/stdio-common/tmpfile64.c +++ b/stdio-common/tmpfile64.c @@ -1,3 +1,3 @@ -#define GEN_THIS __GT_BIGFILE -#define tmpfile tmpfile64 +#define FLAGS O_LARGEFILE +#define tmpfile tmpfile64 #include diff --git a/stdio-common/tmpnam.c b/stdio-common/tmpnam.c index 6b26f4f..f1c1644 100644 --- a/stdio-common/tmpnam.c +++ b/stdio-common/tmpnam.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,1993,1996-1999,2000 Free Software Foundation, Inc. +/* Copyright (C) 1991,1993,1996-1999,2000,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -39,7 +39,7 @@ tmpnam (char *s) 0)) return NULL; - if (__builtin_expect (__gen_tempname (tmpbuf, __GT_NOCREATE), 0)) + if (__builtin_expect (__gen_tempname (tmpbuf, 0, __GT_NOCREATE), 0)) return NULL; if (s == NULL) diff --git a/stdio-common/tmpnam_r.c b/stdio-common/tmpnam_r.c index 565a424..60c4286 100644 --- a/stdio-common/tmpnam_r.c +++ b/stdio-common/tmpnam_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,1993,1996-1999,2000 Free Software Foundation, Inc. +/* Copyright (C) 1991,1993,1996-1999,2000,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,7 @@ tmpnam_r (char *s) if (__path_search (s, L_tmpnam, NULL, NULL, 0)) return NULL; - if (__gen_tempname (s, __GT_NOCREATE)) + if (__gen_tempname (s, 0, __GT_NOCREATE)) return NULL; return s; diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h index d475668..d405cbf 100644 --- a/stdlib/stdlib.h +++ b/stdlib/stdlib.h @@ -614,6 +614,28 @@ extern int mkstemp64 (char *__template) __nonnull ((1)) __wur; extern char *mkdtemp (char *__template) __THROW __nonnull ((1)) __wur; #endif +#ifdef __USE_GNU +/* Generate a unique temporary file name from TEMPLATE similar to + mkstemp. But allow the caller to pass additional flags which are + used in the open call to create the file.. + + This function is a possible cancellation points and therefore not + marked with __THROW. */ +# ifndef __USE_FILE_OFFSET64 +extern int mkostemp (char *__template, int __flags) __nonnull ((1)) __wur; +# else +# ifdef __REDIRECT +extern int __REDIRECT (mkostemp, (char *__template, int __flags), mkostemp64) + __nonnull ((1)) __wur; +# else +# define mkostemp mkostemp64 +# endif +# endif +# ifdef __USE_LARGEFILE64 +extern int mkostemp64 (char *__template, int __flags) __nonnull ((1)) __wur; +# endif +#endif + __BEGIN_NAMESPACE_STD /* Execute the given line as a shell command. diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c index c8973a0..eab658d 100644 --- a/sysdeps/posix/tempname.c +++ b/sysdeps/posix/tempname.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-1999, 2000, 2001, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1991-2001, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -37,9 +37,8 @@ #endif #ifndef __GT_FILE # define __GT_FILE 0 -# define __GT_BIGFILE 1 -# define __GT_DIR 2 -# define __GT_NOCREATE 3 +# define __GT_DIR 1 +# define __GT_NOCREATE 2 #endif #if STDC_HEADERS || _LIBC @@ -220,12 +219,11 @@ static const char letters[] = 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; @@ -298,11 +296,9 @@ __gen_tempname (char *tmpl, int kind) switch (kind) { case __GT_FILE: - fd = __open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); - break; - - case __GT_BIGFILE: - fd = __open64 (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); + fd = __open (tmpl, + (flags & ~ACCESSPERMS) + | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); break; case __GT_DIR: -- 2.7.4