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