diff options
author | Peter Johnson <peter@tortall.net> | 2011-10-30 23:50:31 -0700 |
---|---|---|
committer | Peter Johnson <peter@tortall.net> | 2011-10-31 00:29:42 -0700 |
commit | ab19547382660d81e0b4a0232dccb38f44c52a36 (patch) | |
tree | f17294e61b18a06a57fed5eee5c144b938a3ca75 | |
parent | b334347286cc1cd088d79ff7c81ceca0a4ad923c (diff) | |
download | yasm-ab19547382660d81e0b4a0232dccb38f44c52a36.tar.gz |
re2c: Work around tmpfile() issue on win32.
tmpfile() defaults to C:\, and on Windows 7 can run into permissions issues.
Add workaround implementation from cairo
(http://cgit.freedesktop.org/cairo/commit/?id=4fa46e3caaffb54f4419887418d8d0ea39816092)
See also: http://msdn.microsoft.com/en-us/library/x8x7sakw(v=VS.80).aspx
(community content section)
-rw-r--r-- | tools/re2c/code.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/tools/re2c/code.c b/tools/re2c/code.c index 8a78eaa0..bd54baac 100644 --- a/tools/re2c/code.c +++ b/tools/re2c/code.c @@ -1,3 +1,7 @@ +#ifdef _WIN32 +#include <windows.h> +#include <io.h> +#endif #include <stdlib.h> #include <string.h> #include <ctype.h> @@ -6,6 +10,57 @@ #include "tools/re2c/dfa.h" #include "tools/re2c/parse.h" +#ifdef _WIN32 +/* tmpfile() replacment for Windows. + * + * On Windows tmpfile() creates the file in the root directory. This + * may fail due to unsufficient privileges. + */ +static FILE * +win32_tmpfile (void) +{ + DWORD path_len; + WCHAR path_name[MAX_PATH + 1]; + WCHAR file_name[MAX_PATH + 1]; + HANDLE handle; + int fd; + FILE *fp; + + path_len = GetTempPathW (MAX_PATH, path_name); + if (path_len <= 0 || path_len >= MAX_PATH) + return NULL; + + if (GetTempFileNameW (path_name, L"ps_", 0, file_name) == 0) + return NULL; + + handle = CreateFileW (file_name, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, + NULL); + if (handle == INVALID_HANDLE_VALUE) { + DeleteFileW (file_name); + return NULL; + } + + fd = _open_osfhandle((intptr_t) handle, 0); + if (fd < 0) { + CloseHandle (handle); + return NULL; + } + + fp = fdopen(fd, "w+b"); + if (fp == NULL) { + _close(fd); + return NULL; + } + + return fp; +} +#endif + static void useLabel(size_t value) { while (value >= vUsedLabelAlloc) { vUsedLabels = realloc(vUsedLabels, vUsedLabelAlloc * 2); @@ -844,7 +899,11 @@ void DFA_emit(DFA *d, FILE *o){ nOrgOline = oline; maxFillIndexes = vFillIndexes; orgVFillIndexes = vFillIndexes; +#ifdef _WIN32 + tmpo = win32_tmpfile(); +#else tmpo = tmpfile(); +#endif for(s = d->head; s; s = s->next){ int readCh = 0; State_emit(s, tmpo, &readCh); |