Statistics
| Branch: | Revision:

root / prex-0.9.0 / usr / lib / libc / stdio / mktemp.c @ 03e9c04a

History | View | Annotate | Download (3.04 KB)

1
/*
2
 * Copyright (c) 1987, 1993
3
 *        The Regents of the University of California.  All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 * 3. Neither the name of the University nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29

    
30
#include <sys/types.h>
31
#include <sys/stat.h>
32
#include <fcntl.h>
33
#include <errno.h>
34
#include <stdio.h>
35
#include <ctype.h>
36
#include <unistd.h>
37

    
38
static int _gettemp(char *, int *);
39

    
40
int
41
mkstemp(path)
42
        char *path;
43
{
44
        int fd;
45

    
46
        return (_gettemp(path, &fd) ? fd : -1);
47
}
48

    
49
char *
50
mktemp(path)
51
        char *path;
52
{
53
        return(_gettemp(path, (int *)NULL) ? path : (char *)NULL);
54
}
55

    
56
static int
57
_gettemp(path, doopen)
58
        char *path;
59
        int *doopen;
60
{
61
        extern int errno;
62
        char *start, *trv;
63
        struct stat sbuf;
64
        u_int pid;
65

    
66
        pid = getpid();
67
        for (trv = path; *trv; ++trv);                /* extra X's get set to 0's */
68
        while (*--trv == 'X') {
69
                *trv = (pid % 10) + '0';
70
                pid /= 10;
71
        }
72

    
73
        /*
74
         * check the target directory; if you have six X's and it
75
         * doesn't exist this runs for a *very* long time.
76
         */
77
        for (start = trv + 1;; --trv) {
78
                if (trv <= path)
79
                        break;
80
                if (*trv == '/') {
81
                        *trv = '\0';
82
                        if (stat(path, &sbuf))
83
                                return(0);
84
                        if (!S_ISDIR(sbuf.st_mode)) {
85
                                errno = ENOTDIR;
86
                                return(0);
87
                        }
88
                        *trv = '/';
89
                        break;
90
                }
91
        }
92

    
93
        for (;;) {
94
                if (doopen) {
95
                        if ((*doopen =
96
                            open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
97
                                return(1);
98
                        if (errno != EEXIST)
99
                                return(0);
100
                }
101
                else if (stat(path, &sbuf))
102
                        return(errno == ENOENT ? 1 : 0);
103

    
104
                /* tricky little algorithm for backward compatibility */
105
                for (trv = start;;) {
106
                        if (!*trv)
107
                                return(0);
108
                        if (*trv == 'z')
109
                                *trv++ = 'a';
110
                        else {
111
                                if (isdigit((unsigned char)*trv))
112
                                        *trv = 'a';
113
                                else
114
                                        ++*trv;
115
                                break;
116
                        }
117
                }
118
        }
119
        /*NOTREACHED*/
120
}