mention /dev/null, put on Berkeley copyright
[unix-history] / usr / src / lib / libc / stdio / mktemp.c
CommitLineData
637a4c81
KB
1/*
2 * Copyright (c) 1987 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
2ce81398 7#if defined(LIBC_SCCS) && !defined(lint)
1a452c7d 8static char sccsid[] = "@(#)mktemp.c 5.4 (Berkeley) %G%";
2ce81398 9#endif LIBC_SCCS and not lint
55221028 10
637a4c81
KB
11#include <sys/types.h>
12#include <sys/file.h>
1a452c7d
KB
13#include <sys/stat.h>
14#include <errno.h>
637a4c81
KB
15#include <stdio.h>
16#include <ctype.h>
17
18#define YES 1
19#define NO 0
20
21mkstemp(as)
22 char *as;
23{
24 int fd;
25
26 return (_gettemp(as, &fd) ? fd : -1);
27}
28
55221028
BJ
29char *
30mktemp(as)
637a4c81 31 char *as;
55221028 32{
637a4c81
KB
33 return(_gettemp(as, (int *)NULL) ? as : (char *)NULL);
34}
35
36static
37_gettemp(as, doopen)
38 char *as;
39 register int *doopen;
40{
1a452c7d 41 extern int errno;
637a4c81 42 register char *start, *trv;
1a452c7d 43 struct stat sbuf;
637a4c81 44 u_int pid;
55221028
BJ
45
46 pid = getpid();
637a4c81
KB
47
48 /* extra X's get set to 0's */
1a452c7d 49 for (trv = as; *trv; ++trv);
637a4c81
KB
50 while (*--trv == 'X') {
51 *trv = (pid % 10) + '0';
55221028
BJ
52 pid /= 10;
53 }
637a4c81
KB
54
55 /*
56 * check for write permission on target directory; if you have
57 * six X's and you can't write the directory, this will run for
58 * a *very* long time.
59 */
1a452c7d 60 for (start = ++trv; trv > as && *trv != '/'; --trv);
637a4c81 61 if (*trv == '/') {
637a4c81 62 *trv = '\0';
1a452c7d 63 if (stat(as, &sbuf) || !(sbuf.st_mode & S_IFDIR))
637a4c81 64 return(NO);
1a452c7d 65 *trv = '/';
637a4c81 66 }
1a452c7d 67 else if (stat(".", &sbuf) == -1)
637a4c81
KB
68 return(NO);
69
70 for (;;) {
1a452c7d
KB
71 if (doopen) {
72 if ((*doopen = open(as, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
637a4c81 73 return(YES);
1a452c7d
KB
74 if (errno != EEXIST)
75 return(NO);
76 }
77 else if (stat(as, &sbuf))
78 return(errno == ENOENT ? YES : NO);
79
637a4c81
KB
80 /* tricky little algorithm for backward compatibility */
81 for (trv = start;;) {
82 if (!*trv)
83 return(NO);
84 if (*trv == 'z')
85 *trv++ = 'a';
86 else {
87 if (isdigit(*trv))
88 *trv = 'a';
89 else
90 ++*trv;
91 break;
92 }
93 }
55221028 94 }
637a4c81 95 /*NOTREACHED*/
55221028 96}