]> pd.if.org Git - pdclib/blob - platform/win32/functions/stdio/tmpfile.c
c4b09761d13c3ba3e99624375b8d0767b75fbe9a
[pdclib] / platform / win32 / functions / stdio / tmpfile.c
1 /* tmpfile( void )
2
3    This file is part of the Public Domain C Library (PDCLib).
4    Permission is granted to use, modify, and / or redistribute at will.
5 */
6
7 #include <stdio.h>
8
9 #ifndef REGTEST
10 #include <errno.h>
11 #include <_PDCLIB_glue.h>
12 #include <windows.h>
13 #include <string.h>
14
15 static char tmpname_prefix[4] = {0, 0, 0, 0};
16
17 extern const _PDCLIB_fileops_t _PDCLIB_fileops;
18 extern void _PDCLIB_w32errno( void );
19
20 FILE* tmpfile( void )
21 {
22     if(!tmpname_prefix[0]) {
23         char namebuf[MAX_PATH+1];
24         DWORD res = GetModuleFileNameA(NULL, namebuf, MAX_PATH+1);
25         if(res) {
26             char * basename = strrchr(namebuf, '\\');
27             if(basename) {
28                 basename += 1;
29             } else basename = namebuf;
30
31             char* dot = strchr(basename, '.');
32             if(dot) *dot = 0;
33
34             strncpy(tmpname_prefix, basename, 3);
35         } else {
36             // Error getting file name
37             strcpy(tmpname_prefix, "PDU");
38         }
39     }
40
41     char tmpdir[MAX_PATH + 1];
42     DWORD rv = GetTempPathA(MAX_PATH + 1, tmpdir);
43     if(rv == 0) {
44         _PDCLIB_w32errno();
45         return NULL;
46     }
47
48     char name[MAX_PATH + 1];
49     rv = GetTempFileNameA(tmpdir, tmpname_prefix, 0, name);
50     if(rv == 0) {
51         _PDCLIB_w32errno();
52         return NULL;
53     }
54
55     /* OPEN_EXISTING as CreateTempFileName creates the file then closes the
56        handle to it (to avoid race conditions as associated with e.g. tmpnam)
57      */
58     HANDLE fd = CreateFileA(name, GENERIC_READ | GENERIC_WRITE, 
59         FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 
60         FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_TEMPORARY, NULL);
61
62     if(fd == INVALID_HANDLE_VALUE) {
63         _PDCLIB_w32errno();
64         return NULL;
65     }
66
67     /* Set the file to delete on close */
68     DeleteFile(name);
69
70     FILE* fs = _PDCLIB_fvopen(((_PDCLIB_fd_t){fd}), &_PDCLIB_fileops, _PDCLIB_FWRITE | _PDCLIB_FRW, name);
71     if(!fs) {
72         CloseHandle(fd);
73     }
74     return fs;
75 }
76
77 #endif
78
79 #ifdef TEST
80 #include <_PDCLIB_test.h>
81 #include <string.h>
82
83 int main( void )
84 {
85     return TEST_RESULTS;
86 }
87
88 #endif
89