Mercurial > hg > octave-nkf > gnulib-hg
annotate lib/tmpfile.c @ 9928:9a02133ad731
Add tentative support for Linux libc5.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Thu, 17 Apr 2008 02:01:23 +0200 |
parents | bbbbbf4cd1c5 |
children | d741ba7b3804 |
rev | line source |
---|---|
8162 | 1 /* Create a temporary file. |
2 Copyright (C) 2007 Free Software Foundation, Inc. | |
3 | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8162
diff
changeset
|
4 This program is free software: you can redistribute it and/or modify |
8162 | 5 it under the terms of the GNU General Public License as published by |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8162
diff
changeset
|
6 the Free Software Foundation; either version 3 of the License, or |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8162
diff
changeset
|
7 (at your option) any later version. |
8162 | 8 |
9 This program is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 GNU General Public License for more details. | |
13 | |
14 You should have received a copy of the GNU General Public License | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8162
diff
changeset
|
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
8162 | 16 |
17 /* Written by Ben Pfaff. */ | |
18 | |
19 #include <config.h> | |
20 | |
21 /* Specification. */ | |
22 #include <stdio.h> | |
23 | |
24 /* This replacement is used only on native Windows platforms. */ | |
25 | |
26 #include <errno.h> | |
27 #include <fcntl.h> | |
28 #include <string.h> | |
29 #include <sys/stat.h> | |
30 | |
31 #include <io.h> | |
32 | |
33 #define WIN32_LEAN_AND_MEAN /* avoid including junk */ | |
34 #include <windows.h> | |
35 | |
36 #include "pathmax.h" | |
37 #include "tempname.h" | |
38 #include "tmpdir.h" | |
39 | |
40 /* On Windows, opening a file with _O_TEMPORARY has the effect of passing | |
41 the FILE_FLAG_DELETE_ON_CLOSE flag to CreateFile(), which has the effect | |
42 of deleting the file when it is closed - even when the program crashes. | |
43 But (according to the Cygwin sources) it works only on Windows NT or newer. | |
44 So we cache the info whether we are running on Windows NT or newer. */ | |
45 | |
46 static bool | |
47 supports_delete_on_close () | |
48 { | |
49 static int known; /* 1 = yes, -1 = no, 0 = unknown */ | |
50 if (!known) | |
51 { | |
52 OSVERSIONINFO v; | |
53 | |
54 if (GetVersionEx (&v)) | |
55 known = (v.dwPlatformId == VER_PLATFORM_WIN32_NT ? 1 : -1); | |
56 else | |
57 known = -1; | |
58 } | |
59 return (known > 0); | |
60 } | |
61 | |
62 FILE * | |
63 tmpfile (void) | |
64 { | |
65 char dir[PATH_MAX]; | |
66 DWORD retval; | |
67 | |
68 /* Find Windows temporary file directory. | |
69 We provide this as the directory argument to path_search because Windows | |
70 defines P_tmpdir to "\\" and will therefore try to put all temporary files | |
71 in the root directory (unless $TMPDIR is set). */ | |
72 retval = GetTempPath (PATH_MAX, dir); | |
73 if (retval > 0 && retval < PATH_MAX) | |
74 { | |
75 char xtemplate[PATH_MAX]; | |
76 | |
77 if (path_search (xtemplate, PATH_MAX, dir, NULL, true) >= 0) | |
78 { | |
79 size_t len = strlen (xtemplate); | |
80 int o_temporary = (supports_delete_on_close () ? _O_TEMPORARY : 0); | |
81 int fd; | |
82 | |
83 do | |
84 { | |
85 memcpy (&xtemplate[len - 6], "XXXXXX", 6); | |
86 if (gen_tempname (xtemplate, GT_NOCREATE) < 0) | |
87 { | |
88 fd = -1; | |
89 break; | |
90 } | |
91 | |
92 fd = _open (xtemplate, | |
93 _O_CREAT | _O_EXCL | o_temporary | |
94 | _O_RDWR | _O_BINARY, | |
95 _S_IREAD | _S_IWRITE); | |
96 } | |
97 while (fd < 0 && errno == EEXIST); | |
98 | |
99 if (fd >= 0) | |
100 { | |
101 FILE *fp = _fdopen (fd, "w+b"); | |
102 | |
103 if (fp != NULL) | |
104 return fp; | |
105 else | |
106 { | |
107 int saved_errno = errno; | |
108 _close (fd); | |
109 errno = saved_errno; | |
110 } | |
111 } | |
112 } | |
113 } | |
114 else | |
115 { | |
116 if (retval > 0) | |
117 errno = ENAMETOOLONG; | |
118 else | |
119 /* Ideally this should translate GetLastError () to an errno value. */ | |
120 errno = ENOENT; | |
121 } | |
122 | |
123 return NULL; | |
124 } |