blob: d9e5280b2ccb740676f6ebaa585c37259d2d33b5 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
/* This file is part of ff-woff, a reduced version of the FontForge library.
* It provides the function tmpfile2() with the functionality of tmpfile() but
* works on POSIX and Windows systems.
* License: Revised BSD license used by FontForge
* https://github.com/fontforge/fontforge/blob/master/LICENSE
* (C) 2017-2020 Martin Gieseking <martin.gieseking@uos.de> */
#include <cstdio>
#include <cstdlib>
#include <exception>
#include <iostream>
#include <string>
#if _WIN32
#include <fcntl.h>
#include <sys/stat.h>
#include <windows.h>
#ifdef _MSC_VER
#include <io.h>
#endif
#endif
using namespace std;
class TmpFileException : public exception {
public:
TmpFileException (const char *msg) : _message(msg) {}
const char* what () const noexcept override {return _message.c_str();}
private:
string _message;
};
static inline void tmpfile_error (const char *msg) {
#if defined(_MSC_VER) || defined(__MINGW32__)
// Visual C++ and MinGW support exception handling
// between extern "C" and C++ functions.
throw TmpFileException(msg);
#else
cerr << msg << endl;
exit(EXIT_FAILURE);
#endif
}
/* Creates a temporary binary file in the system's temp folder and returns
* its file pointer. The file is automatically removed when closing it.
* If the temp file can't be created for some reason, the function calls
* exit() or throws a TmpFileException (depending on OS and compiler). */
extern "C" FILE* tmpfile2 () {
#ifndef _WIN32
if (FILE *fp = std::tmpfile())
return fp;
#else
char tmpdir[MAX_PATH+1];
DWORD len = GetTempPath(MAX_PATH+1, tmpdir);
if (len > 0) {
if (len >= MAX_PATH-14)
tmpfile_error("path to temp folder too long");
char fname[MAX_PATH];
if (GetTempFileName(tmpdir, "tmp", 0, fname)) {
int fd = _open(fname, _O_CREAT | _O_TEMPORARY | _O_RDWR | _O_BINARY, _S_IREAD | _S_IWRITE);
if (fd >= 0) {
if (FILE *fp = _fdopen(fd, "w+b"))
return fp;
int saved_errno = errno;
_close(fd);
errno = saved_errno;
}
}
}
#endif
tmpfile_error("failed to create temporary file");
}
|