diff options
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/tmpfile2.cpp')
-rw-r--r-- | Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/tmpfile2.cpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/tmpfile2.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/tmpfile2.cpp new file mode 100644 index 00000000000..9e4a26dbfb7 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/tmpfile2.cpp @@ -0,0 +1,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-2021 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"); +} |