Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
313 dpurdie 1
/***************************************************************************
2
* Module name   : mktemp.c
3
* Module type   : CMDFILE source file
4
* Environment(s): n/a
5
*
6
* Description:
7
*
8
    Build 'binary' temp file ...
9
*
10
* Version   Who      Date        Description
11
            APY      12/99       Created
12
            APY      07//2001    WIN32 support
13
*
14
* $Source: /cvsroot/device/DEVL/UTILS/CMDFILE/mktemp.c,v $            
15
* $Revision: 1.1 $ $Date: 2002/08/02 06:49:28 $ $State: Exp $ 
16
* $Author: adamy $ $Locker:  $
17
*.........................................................................*/
18
 
19
#include <sys/types.h>
20
#include <sys/stat.h>
21
#include <fcntl.h>
22
#if defined(MSDOS)
23
#include <process.h>                            /* getpid() */
24
#endif
25
#if defined(WIN32)
26
#include <process.h>
27
#include <windows.h>
28
#endif
29
#include <errno.h>
30
#include "unistd.h"
31
 
32
#if defined(WIN32)
33
#define DISABLE_HARD_ERRORS     SetErrorMode (0);
34
#define ENABLE_HARD_ERRORS      SetErrorMode (SEM_FAILCRITICALERRORS | \
35
                                        SEM_NOOPENFILEERRORBOX);
36
#else
37
#define DISABLE_HARD_ERRORS
38
#define ENABLE_HARD_ERRORS
39
#endif
40
 
41
 
42
static int
43
_gettemp(char *path, register int *fd)
44
{
45
        register char *start, *trv;
46
        struct stat sbuf;
47
        unsigned pid;
48
        int rc;
49
        char c;
50
 
51
        pid = (unsigned)getpid();
52
        for (trv = path; *trv; ++trv);          /* extra X's get set to 0's */
53
        while (*--trv == 'X' && trv >= path) {
54
                *trv = (pid % 10) + '0';
55
                pid /= 10;
56
        }
57
 
58
        /*
59
         * check the target directory; if you have six X's and it
60
         * doesn't exist this runs for a *very* long time.
61
         */
62
        for (start = trv + 1;; --trv) {
63
                if (trv <= path)
64
                        break;
65
                if ((c = *trv) == '/' || c == '\\') {
66
                        *trv = '\0';
67
                        if (trv[-1] == ':') {
68
                                *trv = c;
69
                                break;
70
                        }
71
                        DISABLE_HARD_ERRORS
72
                        rc = stat(path, &sbuf);
73
                        ENABLE_HARD_ERRORS
74
                        if (rc)
75
                                return(0);
76
                        if (!(sbuf.st_mode & S_IFDIR)) {
77
                                errno = ENOTDIR;
78
                                return(0);
79
                        }
80
                        *trv = c;
81
                        break;
82
                }
83
        }
84
 
85
        for (;;) {
86
                if (fd) {
87
                        if ((*fd =
88
#if defined(MSDOS) || defined(WIN32)
89
                            open(path, O_CREAT|O_EXCL|O_RDWR|O_BINARY, 0600)) >= 0)
90
#else
91
                            open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
92
#endif
93
                                return(1);
94
                        if (errno != EEXIST)
95
                                return(0);
96
                }
97
                else
98
                {
99
                    DISABLE_HARD_ERRORS
100
                    rc = stat(path, &sbuf);
101
                    ENABLE_HARD_ERRORS
102
                    if (rc)
103
                    {
104
#ifndef ENMFILE
105
                        return(((errno == ENOENT)) ? 1 : 0);
106
#else
107
                        return(((errno == ENOENT) || (errno == ENMFILE)) ? 1 : 0);
108
#endif
109
                    }
110
                }
111
 
112
                /* tricky little algorithm for backward compatibility */
113
                for (trv = start;;) {
114
                        if (*trv == '\0')       /* EOS */
115
                                return(0);
116
                        if (*trv == 'z')
117
                                *trv++ = 'a';
118
                        else {
119
                                if (isdigit(*trv))
120
                                        *trv = 'a';
121
                                else
122
                                        ++*trv;
123
                                break;
124
                        }
125
                }
126
        }
127
        /*NOTREACHED*/
128
}
129
 
130
 
131
int
132
mkstemp(char *path)
133
{
134
        int fd;
135
 
136
        return (_gettemp(path, &fd) ? fd : -1);
137
}
138