SCCS-vsn: lib/libc/stdio/mktemp.c 5.3
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
#if defined(LIBC_SCCS) && !defined(lint)
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)mktemp.c 5.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)mktemp.c 5.3 (Berkeley) %G%";
#endif LIBC_SCCS and not lint
#endif LIBC_SCCS and not lint
+#include <sys/types.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#define YES 1
+#define NO 0
+
+mkstemp(as)
+ char *as;
+{
+ int fd;
+
+ return (_gettemp(as, &fd) ? fd : -1);
+}
+
- register char *s;
- register unsigned pid;
- register i;
+ return(_gettemp(as, (int *)NULL) ? as : (char *)NULL);
+}
+
+static
+_gettemp(as, doopen)
+ char *as;
+ register int *doopen;
+{
+ register char *start, *trv;
+ u_int pid;
+ char savech;
- s = as;
- while (*s++)
- ;
- s--;
- while (*--s == 'X') {
- *s = (pid%10) + '0';
+
+ /* extra X's get set to 0's */
+ for (trv = as;*trv;++trv);
+ while (*--trv == 'X') {
+ *trv = (pid % 10) + '0';
- s++;
- i = 'a';
- while (access(as, 0) != -1) {
- if (i=='z')
- return("/");
- *s = i++;
+
+ /*
+ * check for write permission on target directory; if you have
+ * six X's and you can't write the directory, this will run for
+ * a *very* long time.
+ */
+ for (start = ++trv;trv > as && *trv != '/';--trv);
+ if (*trv == '/') {
+ savech = *++trv;
+ *trv = '\0';
+ if (access(as, W_OK))
+ return(NO);
+ *trv = savech;
+ }
+ else if (access(".", W_OK))
+ return(NO);
+
+ for (;;) {
+ if (doopen
+ && (*doopen = open(as, O_CREAT|O_EXCL|O_RDWR, 0600)) != -1
+ || access(as, F_OK))
+ return(YES);
+ /* tricky little algorithm for backward compatibility */
+ for (trv = start;;) {
+ if (!*trv)
+ return(NO);
+ if (*trv == 'z')
+ *trv++ = 'a';
+ else {
+ if (isdigit(*trv))
+ *trv = 'a';
+ else
+ ++*trv;
+ break;
+ }
+ }