summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Johnson <peter@tortall.net>2011-10-30 23:50:31 -0700
committerPeter Johnson <peter@tortall.net>2011-10-31 00:29:42 -0700
commitab19547382660d81e0b4a0232dccb38f44c52a36 (patch)
treef17294e61b18a06a57fed5eee5c144b938a3ca75
parentb334347286cc1cd088d79ff7c81ceca0a4ad923c (diff)
downloadyasm-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.c59
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);