[klibc] [PATCH 2/2] Add a relatively minimal mkstemp(3) implementation.
Thorsten Glaser
tg at mirbsd.de
Sat Jan 29 09:31:35 PST 2011
Requires arc4random. Debian: (Closes: #516774)
Signed-off-by: Thorsten Glaser <tg at mirbsd.de>
---
usr/include/stdlib.h | 2 +
usr/klibc/Kbuild | 2 +-
usr/klibc/mkstemp.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 79 insertions(+), 1 deletions(-)
create mode 100644 usr/klibc/mkstemp.c
diff --git a/usr/include/stdlib.h b/usr/include/stdlib.h
index 28c7150..74c9bf3 100644
--- a/usr/include/stdlib.h
+++ b/usr/include/stdlib.h
@@ -85,6 +85,8 @@ static __inline__ void srandom(unsigned int __s)
srand48(__s);
}
+__extern int mkstemp(char *);
+
/* Basic PTY functions. These only work if devpts is mounted! */
__extern int unlockpt(int);
diff --git a/usr/klibc/Kbuild b/usr/klibc/Kbuild
index 1138e6d..783ed69 100644
--- a/usr/klibc/Kbuild
+++ b/usr/klibc/Kbuild
@@ -47,7 +47,7 @@ klib-y := vsnprintf.o snprintf.o vsprintf.o sprintf.o \
time.o utime.o llseek.o nice.o getpriority.o \
qsort.o bsearch.o \
lrand48.o jrand48.o mrand48.o nrand48.o srand48.o seed48.o \
- arc4random.o \
+ arc4random.o mkstemp.o \
inet/inet_ntoa.o inet/inet_aton.o inet/inet_addr.o \
inet/inet_ntop.o inet/inet_pton.o inet/bindresvport.o \
send.o recv.o \
diff --git a/usr/klibc/mkstemp.c b/usr/klibc/mkstemp.c
new file mode 100644
index 0000000..ef575da
--- /dev/null
+++ b/usr/klibc/mkstemp.c
@@ -0,0 +1,76 @@
+/*-
+ * Compact mkstemp(3)-only implementation, for klibc
+ *
+ * Copyright (c) 2009, 2011
+ * Thorsten Glaser <tg at mirbsd.de>
+ *
+ * This file is available under the same terms ("historic
+ * permission clause") as klibc itself or under the terms
+ * of The MirOS Licence (dual licenced).
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int
+mkstemp(char *template)
+{
+ int i;
+ char *cp, *sp;
+ struct stat sbuf;
+
+ cp = template;
+ while (*cp)
+ ++cp;
+
+ sp = cp;
+ /* generate random suffix */
+ while (sp > template && sp[-1] == 'X') {
+ i = arc4random() % (26 + 26);
+ *--sp = i < 26 ? 'A' + i : 'a' + i - 26;
+ }
+ if (sp == cp) {
+ /* zero-length template or no X at its end */
+ errno = EINVAL;
+ return (-1);
+ }
+
+ /* check the target directory */
+ cp = sp;
+ while (cp > template && *cp != '/')
+ --cp;
+ if (cp > template) {
+ *cp = '\0';
+ i = stat(template, &sbuf);
+ *cp = '/';
+
+ if (i != 0)
+ /* stat failed, pass errno */
+ return (-1);
+ if (!S_ISDIR(sbuf.st_mode)) {
+ errno = ENOTDIR;
+ return (-1);
+ }
+ }
+
+ while (1) {
+ if ((i = open(template, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0 ||
+ errno != EEXIST)
+ break;
+
+ while (*cp == 'Z')
+ if (!*++cp)
+ return (-1);
+ if (*cp == 'z')
+ *cp = 'A';
+ else
+ ++*cp;
+ }
+ return (i);
+}
--
1.7.2.3
More information about the klibc
mailing list