From 2ed0c6aa0e1c6c6ea85978958593e7a4dcd877bb Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Fri, 20 Jun 1997 04:10:21 +0000 Subject: Add mkdtemp(3) --- include/unistd.h | 3 ++- lib/libc/stdio/mktemp.3 | 35 ++++++++++++++++++++++++++++------- lib/libc/stdio/mktemp.c | 31 ++++++++++++++++++++++++------- 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/include/unistd.h b/include/unistd.h index 011e6aa1dd4..5063e7f721a 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: unistd.h,v 1.12 1997/01/26 05:11:16 downsj Exp $ */ +/* $OpenBSD: unistd.h,v 1.13 1997/06/20 04:10:20 millert Exp $ */ /* $NetBSD: unistd.h,v 1.26.4.1 1996/05/28 02:31:51 mrg Exp $ */ /*- @@ -132,6 +132,7 @@ int initgroups __P((const char *, gid_t)); int iruserok __P((u_int32_t, int, const char *, const char *)); int lchown __P((const char *, uid_t, gid_t)); int mknod __P((const char *, mode_t, dev_t)); +char *mkdtemp __P((char *)); int mkstemp __P((char *)); char *mktemp __P((char *)); int nfssvc __P((int, void *)); diff --git a/lib/libc/stdio/mktemp.3 b/lib/libc/stdio/mktemp.3 index 14ff1c53424..f0c0866ae09 100644 --- a/lib/libc/stdio/mktemp.3 +++ b/lib/libc/stdio/mktemp.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: mktemp.3,v 1.3 1996/08/21 19:03:29 deraadt Exp $ +.\" $OpenBSD: mktemp.3,v 1.4 1997/06/20 04:10:18 millert Exp $ .\" .\" Copyright (c) 1989, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -43,6 +43,8 @@ .Fn mktemp "char *template" .Ft int .Fn mkstemp "char *template" +.Ft char * +.Fn mkdtemp "char *template" .Sh DESCRIPTION The .Fn mktemp @@ -78,11 +80,18 @@ makes the same replacement to the template and creates the template file, mode 0600, returning a file descriptor opened for reading and writing. This avoids the race between testing for a file's existence and opening it for use. +.Pp +The +.Fn mkdtemp +function makes the same replacement to the template as in +.Xr mktemp 3 +and creates the template directory, mode 0700. .Sh RETURN VALUES The .Fn mktemp -function -returns a pointer to the template on success and +and +.Fn mkdtemp +functions return a pointer to the template on success and .Dv NULL on failure. The @@ -93,9 +102,10 @@ If either call fails an error code is placed in the global variable .Va errno . .Sh ERRORS The -.Fn mktemp -and +.Fn mktemp , .Fn mkstemp +and +.Fn mkdtemp functions may set .Va errno @@ -106,9 +116,10 @@ The pathname portion of the template is not an existing directory. .El .Pp The -.Fn mktemp -and +.Fn mktemp , .Fn mkstemp +and +.Fn mkdtemp functions may also set .Va errno @@ -124,6 +135,15 @@ may also set to any value specified by the .Xr open 2 function. +.Pp +The +.Fn mkdtemp +function +may also set +.Va errno +to any value specified by the +.Xr mkdir 2 +function. .Sh BUGS An attacker can guess the filenames produced by .Fn mktemp . @@ -133,6 +153,7 @@ should be used instead. .Sh SEE ALSO .Xr chmod 2 , .Xr getpid 2 , +.Xr mkdir 2 , .Xr open 2 , .Xr stat 2 .Sh HISTORY diff --git a/lib/libc/stdio/mktemp.c b/lib/libc/stdio/mktemp.c index a44da95580f..1dcbc02b8d4 100644 --- a/lib/libc/stdio/mktemp.c +++ b/lib/libc/stdio/mktemp.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: mktemp.c,v 1.8 1997/04/07 22:48:50 millert Exp $"; +static char rcsid[] = "$OpenBSD: mktemp.c,v 1.9 1997/06/20 04:10:19 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include @@ -44,7 +44,7 @@ static char rcsid[] = "$OpenBSD: mktemp.c,v 1.8 1997/04/07 22:48:50 millert Exp #include #include -static int _gettemp(); +static int _gettemp __P((char *, int *, int)); int mkstemp(path) @@ -52,7 +52,14 @@ mkstemp(path) { int fd; - return (_gettemp(path, &fd) ? fd : -1); + return (_gettemp(path, &fd, 0) ? fd : -1); +} + +char * +mkdtemp(path) + char *path; +{ + return(_gettemp(path, (int *)NULL, 1) ? path : (char *)NULL); } char *_mktemp __P((char *)); @@ -61,7 +68,7 @@ char * _mktemp(path) char *path; { - return(_gettemp(path, (int *)NULL) ? path : (char *)NULL); + return(_gettemp(path, (int *)NULL, 0) ? path : (char *)NULL); } __warn_references(mktemp, @@ -76,15 +83,21 @@ mktemp(path) static int -_gettemp(path, doopen) +_gettemp(path, doopen, domkdir) char *path; register int *doopen; + int domkdir; { extern int errno; register char *start, *trv; struct stat sbuf; int pid; + if (doopen && domkdir) { + errno = EINVAL; + return(0); + } + pid = getpid(); for (trv = path; *trv; ++trv) ; @@ -131,8 +144,12 @@ _gettemp(path, doopen) return(1); if (errno != EEXIST) return(0); - } - else if (lstat(path, &sbuf)) + } else if (domkdir) { + if (mkdir(path, 0700) == 0) + return(1); + if (errno != EEXIST) + return(0); + } else if (lstat(path, &sbuf)) return(errno == ENOENT ? 1 : 0); /* tricky little algorithm for backward compatibility */ -- cgit v1.2.3