소스 검색

make mkdtemp and mkstemp family leave template unchanged on fail

also refactor mkdtemp based on new shared temp code, removing
dependency on the deprecated mktemp, whose behavior made this logic
more difficult.
Rich Felker 11 년 전
부모
커밋
c4685ae429
2개의 변경된 파일18개의 추가작업 그리고 13개의 파일을 삭제
  1. 14 10
      src/temp/mkdtemp.c
  2. 4 3
      src/temp/mkostemps.c

+ 14 - 10
src/temp/mkdtemp.c

@@ -8,19 +8,23 @@
 #include <sys/stat.h>
 #include "libc.h"
 
-char *__mktemp(char *);
+char *__randname(char *);
 
 char *mkdtemp(char *template)
 {
-	int retries = 100, t0 = *template;
-	while (retries--) {
-		if (!*__mktemp(template)) return 0;
-		if (!mkdir(template, 0700)) return template;
-		if (errno != EEXIST) return 0;
-		/* this is safe because mktemp verified
-		 * that we have a valid template string */
-		template[0] = t0;
-		strcpy(template+strlen(template)-6, "XXXXXX");
+	size_t l = strlen(template);
+	int retries = 100;
+
+	if (l<6 || memcmp(template+l-6, "XXXXXX", 6)) {
+		errno = EINVAL;
+		return 0;
 	}
+
+	do {
+		__randname(template+l-6);
+		if (!mkdir(template, 0700)) return template;
+	} while (--retries && errno == EEXIST);
+
+	memcpy(template+l-6, "XXXXXX", 6);
 	return 0;
 }

+ 4 - 3
src/temp/mkostemps.c

@@ -16,12 +16,13 @@ int __mkostemps(char *template, int len, int flags)
 	}
 
 	int fd, retries = 100;
-	while (retries--) {
+	do {
 		__randname(template+l-len-6);
 		if ((fd = open(template, flags | O_RDWR | O_CREAT | O_EXCL, 0600))>=0)
 			return fd;
-		if (errno != EEXIST) return -1;
-	}
+	} while (--retries && errno == EEXIST);
+
+	memcpy(template+l-len-6, "XXXXXX", 6);
 	return -1;
 }