cleanup, update, reimplement to work as correctly as possible
authorKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Sat, 23 Feb 1991 09:00:01 +0000 (01:00 -0800)
committerKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Sat, 23 Feb 1991 09:00:01 +0000 (01:00 -0800)
SCCS-vsn: lib/libc/stdio/tmpfile.c 5.2
SCCS-vsn: lib/libc/stdio/tmpnam.c 5.2
SCCS-vsn: lib/libc/stdio/tempnam.c 5.1
SCCS-vsn: lib/libc/stdio/tmpnam.3 5.11

usr/src/lib/libc/stdio/tempnam.c
usr/src/lib/libc/stdio/tmpfile.c
usr/src/lib/libc/stdio/tmpnam.3
usr/src/lib/libc/stdio/tmpnam.c

index 76f6444..6c0221a 100644 (file)
@@ -6,64 +6,53 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)tempnam.c  4.8 (Berkeley) %G%";
+static char sccsid[] = "@(#)tempnam.c  5.1 (Berkeley) %G%";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/param.h>
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/param.h>
+#include <errno.h>
 #include <stdio.h>
 #include <stdio.h>
-
-#define        P_tmpdir        "/usr/tmp"
-
-FILE *
-tmpfile()
-{
-       FILE *fp;
-       char *f, *tmpnam();
-
-       if (!(f = tmpnam((char *)NULL)) || !(fp = fopen(f, "w+"))) {
-               fprintf(stderr, "tmpfile: cannot open %s.\n", f);
-               return(NULL);
-       }
-       (void)unlink(f);
-       return(fp);
-}
-
-char *
-tmpnam(s)
-       char *s;
-{
-       char *malloc(), *mktemp();
-
-       if (!s && !(s = malloc((u_int)MAXPATHLEN)))
-               return(NULL);
-       (void)sprintf(s, "%s/XXXXXX", P_tmpdir);
-       return(mktemp(s));
-}
+#include <stdlib.h>
+#include <unistd.h>
+#include <paths.h>
 
 char *
 tempnam(dir, pfx)
 
 char *
 tempnam(dir, pfx)
-       char *dir, *pfx;
+       const char *dir, *pfx;
 {
 {
-       char *f, *name, *getenv(), *malloc(), *mktemp();
+       int sverrno;
+       char *f, *name;
 
 
-       if (!(name = malloc((u_int)MAXPATHLEN)))
+       if (!(name = malloc(MAXPATHLEN)))
                return(NULL);
 
                return(NULL);
 
+       if (!pfx)
+               pfx = "tmp.";
+
        if (f = getenv("TMPDIR")) {
        if (f = getenv("TMPDIR")) {
-               (void)sprintf(name, "%s/%sXXXXXX", f, pfx ? "" : pfx);
+               (void)snprintf(name, MAXPATHLEN, "%s/%sXXXXXX", f, pfx);
                if (f = mktemp(name))
                        return(f);
        }
                if (f = mktemp(name))
                        return(f);
        }
-       if (dir) {
-               (void)sprintf(name, "%s/%sXXXXXX", dir, pfx ? "" : pfx);
+
+       if (f = (char *)dir) {
+               (void)snprintf(name, MAXPATHLEN, "%s/%sXXXXXX", f, pfx);
                if (f = mktemp(name))
                        return(f);
        }
                if (f = mktemp(name))
                        return(f);
        }
-       (void)sprintf(name, "%s/%sXXXXXX", P_tmpdir, pfx ? "" : pfx);
+
+       f = P_tmpdir;
+       (void)snprintf(name, MAXPATHLEN, "%s/%sXXXXXX", f, pfx);
        if (f = mktemp(name))
                return(f);
        if (f = mktemp(name))
                return(f);
-       (void)sprintf(name, "/tmp/%sXXXXXX", pfx ? "" : pfx);
-       if (!(f = mktemp(name)))
-               (void)free(name);
-       return(f);
+
+       f = _PATH_TMP;
+       (void)snprintf(name, MAXPATHLEN, "%s/%sXXXXXX", f, pfx);
+       if (f = mktemp(name))
+               return(f);
+
+       sverrno = errno;
+       free(name);
+       errno = sverrno;
+       return(NULL);
 }
 }
index be82915..38abccf 100644 (file)
@@ -9,25 +9,48 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)tmpfile.c  5.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)tmpfile.c  5.2 (Berkeley) %G%";
 #endif /* LIBC_SCCS and not lint */
 
 #endif /* LIBC_SCCS and not lint */
 
-#include <sys/param.h>
-#include <stdio.h>
+#include <sys/types.h>
+#include <signal.h>
 #include <errno.h>
 #include <errno.h>
+#include <stdio.h>
+#include <paths.h>
 
 FILE *
 tmpfile()
 {
 
 FILE *
 tmpfile()
 {
+       sigset_t set, oset;
        FILE *fp;
        FILE *fp;
-       int e;
-       char *f, buf[MAXPATHLEN];
-
-       if ((f = tmpnam(buf)) == NULL)
-               return (NULL);
-       fp = fopen(f, "w+");
-       e = errno;
-       (void) unlink(f);
-       errno = e;
-       return (fp);
+       int fd, sverrno;
+#define        TRAILER "tmp.XXXXXX"
+       char buf[sizeof(_PATH_TMP) + sizeof(TRAILER)];
+
+       bcopy(_PATH_TMP, buf, sizeof(_PATH_TMP) - 1);
+       bcopy(TRAILER, buf + sizeof(_PATH_TMP) - 1, sizeof(TRAILER));
+
+       sigemptyset(&set);
+       sigaddset(&set, SIGHUP);
+       sigaddset(&set, SIGINT);
+       sigaddset(&set, SIGQUIT);
+       sigaddset(&set, SIGTERM);
+       (void)sigprocmask(SIG_BLOCK, &set, &oset);
+
+       fd = mkstemp(buf);
+       if (fd != -1)
+               (void)unlink(buf);
+
+       (void)sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL);
+
+       if (fd == -1)
+               return(NULL);
+
+       if (!(fp = fdopen(fd, "w+"))) {
+               sverrno = errno;
+               (void)close(fd);
+               errno = sverrno;
+               return(NULL);
+       }
+       return(fp);
 }
 }
index bfb0df5..a272eaa 100644 (file)
@@ -3,7 +3,7 @@
 .\"
 .\" %sccs.include.redist.man%
 .\"
 .\"
 .\" %sccs.include.redist.man%
 .\"
-.\"    @(#)tmpnam.3    5.10 (Berkeley) %G%
+.\"    @(#)tmpnam.3    5.11 (Berkeley) %G%
 .\"
 .TH TMPFILE 3 ""
 .UC 7
 .\"
 .TH TMPFILE 3 ""
 .UC 7
@@ -26,38 +26,32 @@ tempnam(const char *tmpdir, const char *prefix);
 .fi
 .SH DESCRIPTION
 .I Tmpfile
 .fi
 .SH DESCRIPTION
 .I Tmpfile
-opens a file using a file name generated by the routine
-.IR tmpnam (3),
-and returns a pointer to the stream associated with the file.
+returns a pointer to a stream associated with a file descriptor returned
+by the routine
+.IR mkstemp (3).
 The created file is unlinked before
 .I tmpfile
 The created file is unlinked before
 .I tmpfile
-returns, causing the contents of the file to be deleted automatically
-when the last reference to it is closed.
+returns, causing the file to be automatically deleted when the last
+reference to it is closed.
 The file is opened with the access value ``w+''.
 The file is opened with the access value ``w+''.
-If
-.I tmpnam
-returns NULL, or if
-.I tmpfile
-is unable to open the file, a NULL pointer is returned.
 .PP
 .I Tmpnam
 .PP
 .I Tmpnam
-returns a pointer to a file name, in the directory ``/usr/tmp'', which
+returns a pointer to a file name, in the ``P_tmpdir'' directory, which
 did not reference an existing file at some indeterminate point in the
 past.
 did not reference an existing file at some indeterminate point in the
 past.
+P_tmpdir is defined in the include file <stdio.h>.
 If the argument
 .I s
 If the argument
 .I s
-is non-NULL, this file name is copied to the buffer it references.
-Otherwise, memory to contain this file name is allocated by
-.IR tmpnam .
+is non-NULL, the file name is copied to the buffer it references.
+Otherwise, the file name is copied to a static buffer.
 In either case,
 .I tmpnam
 In either case,
 .I tmpnam
-returns a pointer to the file name; in the latter case, the return
-value may be used as a subsequent argument to
-.IR free (3).
+returns a pointer to the file name.
 .PP
 .PP
-In the current implementation, the memory buffer referenced by
+The buffer referenced by 
 .I s
 .I s
-must be at least 16 bytes long.
+is expected to be at least ``L_tmpnam'' bytes in length.
+L_tmpnam is defined in the include file <stdio.h>.
 .PP
 .I Tempnam
 is similar to
 .PP
 .I Tempnam
 is similar to
@@ -67,75 +61,86 @@ contain the temporary file and the file name prefix.
 .PP
 The environmental variable ``TMPDIR'' (if set), the argument
 .I dir
 .PP
 The environmental variable ``TMPDIR'' (if set), the argument
 .I dir
-(if non-NULL), the directory ``/usr/tmp'' and the directory ``/tmp''
+(if non-NULL), the directory P_tmpdir, and the directory ``/tmp''
 are tried, in the listed order, as directories in which to store the
 temporary file.
 are tried, in the listed order, as directories in which to store the
 temporary file.
-.I Tempnam
-allocates memory in which to store the file name; the returned pointer
-may be used as a subsequent argument to
-.IR free (3).
+.PP
 The argument
 .IR prefix ,
 if non-NULL, is used to specify a file name prefix, which will be the
 first part of the created file name.
 The argument
 .IR prefix ,
 if non-NULL, is used to specify a file name prefix, which will be the
 first part of the created file name.
+.I Tempnam
+allocates memory in which to store the file name; the returned pointer
+may be used as a subsequent argument to
+.IR free (3).
+.SH "RETURN VALUES"
+.I Tmpfile
+returns a pointer to an open file stream on success, and a NULL pointer
+on error.
 .PP
 .I Tmpnam
 and
 .PP
 .I Tmpnam
 and
-.I tempname
-return a NULL pointer if unable to allocate memory or find a file
-which may be created.
+.I tempfile
+return a pointer to a file name on success, and a NULL pointer
+on error.
+.SH ERRORS
+.I Tmpfile
+may fail and set
+.I errno
+for any of the errors specified for the library functions
+.IR fdopen (3)
+or
+.IR mkstemp (3).
 .PP
 .PP
-The manifest constants ``TMP_MAX'', ``P_tmpdir'' and ``L_tmpnam'',
-documented for the routines
-.I tmpnam
-and
-.I tempnam
-in other systems, are not available in this implementation.
-If the source code requires them, simply use:
-.sp
-.RS
-#define        TMP_MAX         308915776
-.br
-#define        P_tmpdir                "/usr/tmp"
-.br
-#define        L_tmpnam                1024
-.RE
+.I Tmpnam
+may fail and set
+.I errno
+for any of the errors specified for the library function
+.IR mktemp (3).
 .PP
 .PP
+.I Tempnam
+may fail and set
+.I errno
+for any of the errors specified for the library functions
+.IR malloc (3)
+or
+.IR mktemp (3).
 .SH BUGS
 .SH BUGS
-These interfaces are provided for System V compatibility only.
+These interfaces are provided for System V and ANSI compatibility only.
 The
 .IR mkstemp (3)
 interface is strongly preferred.
 .PP
 The
 .IR mkstemp (3)
 interface is strongly preferred.
 .PP
-There are three important problems with these interfaces (as well as
+There are four important problems with these interfaces (as well as
 with the historic
 .IR mktemp (3)
 interface).
 First, there is an obvious race between file name selection and file
 with the historic
 .IR mktemp (3)
 interface).
 First, there is an obvious race between file name selection and file
-creation.
-Second, most implementations provide only a limited number (usually
-26) of possible temporary file names before file names will start being
-recycled.
-Third, the System V implementations of these functions (and
+creation and deletion.
+Second, most historic implementations provide only a limited number
+of possible temporary file names (usually 26) before file names will
+start being recycled.
+Third, the System V implementations of these functions (and of
 .IR mktemp )
 use the
 .IR access (2)
 .IR mktemp )
 use the
 .IR access (2)
-system call to determine whether or not the temporary file may be created.
+function to determine whether or not the temporary file may be created.
 This has obvious ramifications for setuid or setgid programs, complicating
 the portable use of these interfaces in such programs.
 This has obvious ramifications for setuid or setgid programs, complicating
 the portable use of these interfaces in such programs.
+Finally, there is no specification of the permissions with which the
+temporary files are created.
 .PP
 .PP
-The
-.IR mkstemp (3)
-interface has none of these problems;
-the
-.IR mktemp(3)
-implementation in this system suffers only from the race condition described
-above.
-.PP
-The
+This implementation does not have these flaws, but portable software
+cannot depend on that.
+In particular, the
 .I tmpfile
 .I tmpfile
-interface should not be used if there is any possibility that the user
-does not wish the temporary file to be publicly readable or writable.
-.PP
+interface should not be used in software expected to be used on other systems
+if there is any possibility that the user does not wish the temporary file to
+be publicly readable and writable.
+.SH STANDARDS
+.I Tmpfile
+and
+.I tmpnam
+conform to ANSI X3.159-1989 (``ANSI C'').
 .SH SEE ALSO
 .SH SEE ALSO
-fopen(3), mkstemp(3), mktemp(3)
+mkstemp(3), mktemp(3)
index a9a1369..37f3dc4 100644 (file)
@@ -9,21 +9,21 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)tmpnam.c   5.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)tmpnam.c   5.2 (Berkeley) %G%";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/param.h>
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/param.h>
+#include <unistd.h>
 #include <stdio.h>
 
 char *
 tmpnam(s)
        char *s;
 {
 #include <stdio.h>
 
 char *
 tmpnam(s)
        char *s;
 {
-       static char buf[MAXPATHLEN];
-       char *mktemp();
+       static char buf[L_tmpnam];
 
        if (s == NULL)
                s = buf;
 
        if (s == NULL)
                s = buf;
-       (void) sprintf(s, "%s/XXXXXX", P_tmpdir);
-       return (mktemp(s));
+       (void)snprintf(s, L_tmpnam, "%s/tmp.XXXXXX", P_tmpdir);
+       return(mktemp(s));
 }
 }