diff options
Diffstat (limited to 'lib/libc/stdio/mktemp.c')
| -rw-r--r-- | lib/libc/stdio/mktemp.c | 93 | 
1 files changed, 70 insertions, 23 deletions
| diff --git a/lib/libc/stdio/mktemp.c b/lib/libc/stdio/mktemp.c index 19125e677ff9..561952291fb7 100644 --- a/lib/libc/stdio/mktemp.c +++ b/lib/libc/stdio/mktemp.c @@ -36,7 +36,7 @@  static char sccsid[] = "@(#)mktemp.c	8.1 (Berkeley) 6/4/93";  #endif  static const char rcsid[] = -		"$Id: mktemp.c,v 1.6 1997/02/22 15:02:16 peter Exp $"; +		"$Id: mktemp.c,v 1.7 1997/04/07 18:01:10 guido Exp $";  #endif /* LIBC_SCCS and not lint */  #include <sys/types.h> @@ -44,10 +44,11 @@ static const char rcsid[] =  #include <fcntl.h>  #include <errno.h>  #include <stdio.h> +#include <stdlib.h>  #include <ctype.h>  #include <unistd.h> -static int _gettemp(char *, int *); +static int _gettemp(char *, int *, int);  int  mkstemp(path) @@ -55,49 +56,91 @@ 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(char *); + +char * +_mktemp(path) +	char *path; +{ +	return(_gettemp(path, (int *)NULL, 0) ? path : (char *)NULL); +} + +#ifdef UNSAFE_WARN +__warn_references(mktemp, +    "warning: mktemp() possibly used unsafely; consider using mkstemp()"); +#endif + +char *  mktemp(path)  	char *path;  { -	return(_gettemp(path, (int *)NULL) ? path : (char *)NULL); +	return(_mktemp(path));  }  static int -_gettemp(path, doopen) +_gettemp(path, doopen, domkdir)  	char *path;  	register int *doopen; +	int domkdir;  {  	register char *start, *trv;  	struct stat sbuf; -	pid_t pid; +	int pid, rval; + +	if (doopen && domkdir) { +		errno = EINVAL; +		return(0); +	}  	pid = getpid(); -	for (trv = path; *trv; ++trv);		/* extra X's get set to 0's */ -	while (*--trv == 'X') { -		*trv = (pid % 10) + '0'; +	for (trv = path; *trv; ++trv) +		; +	--trv; +	while (*trv == 'X' && pid != 0) { +		*trv-- = (pid % 10) + '0';  		pid /= 10;  	} +	while (*trv == 'X') { +		char c; + +		pid = (arc4random() & 0xffff) % (26+26); +		if (pid < 26) +			c = pid + 'A'; +		else +			c = (pid - 26) + 'a'; +		*trv-- = c; +	}  	/*  	 * check the target directory; if you have six X's and it  	 * doesn't exist this runs for a *very* long time.  	 */ -	for (start = trv + 1;; --trv) { -		if (trv <= path) -			break; -		if (*trv == '/') { -			*trv = '\0'; -			if (stat(path, &sbuf)) -				return(0); -			if (!S_ISDIR(sbuf.st_mode)) { -				errno = ENOTDIR; -				return(0); +	if (doopen || domkdir) { +		for (start = trv + 1;; --trv) { +			if (trv <= path) +				break; +			if (*trv == '/') { +				*trv = '\0'; +				rval = stat(path, &sbuf); +				*trv = '/'; +				if (rval != 0) +					return(0); +				if (!S_ISDIR(sbuf.st_mode)) { +					errno = ENOTDIR; +					return(0); +				} +				break;  			} -			*trv = '/'; -			break;  		}  	} @@ -108,8 +151,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 */ | 
