summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/libuv/test/runner-win.c
diff options
context:
space:
mode:
author ImJezze <jezze@gmx.net>2016-02-21 11:48:45 +0100
committer ImJezze <jezze@gmx.net>2016-02-21 11:48:45 +0100
commitcc24a339d8c0517259084b5c178d784626ba965c (patch)
tree9868e9687b5802ae0a3733712a3bbeb3bc75c953 /3rdparty/libuv/test/runner-win.c
parentb5daabda5495dea5c50e17961ecfed2ea8619d76 (diff)
Merge remote-tracking branch 'refs/remotes/mamedev/master'
Second attempt
Diffstat (limited to '3rdparty/libuv/test/runner-win.c')
-rw-r--r--3rdparty/libuv/test/runner-win.c371
1 files changed, 371 insertions, 0 deletions
diff --git a/3rdparty/libuv/test/runner-win.c b/3rdparty/libuv/test/runner-win.c
new file mode 100644
index 00000000000..97ef7599eb8
--- /dev/null
+++ b/3rdparty/libuv/test/runner-win.c
@@ -0,0 +1,371 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <fcntl.h>
+#include <io.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <process.h>
+#if !defined(__MINGW32__)
+# include <crtdbg.h>
+#endif
+
+
+#include "task.h"
+#include "runner.h"
+
+
+/*
+ * Define the stuff that MinGW doesn't have
+ */
+#ifndef GetFileSizeEx
+ WINBASEAPI BOOL WINAPI GetFileSizeEx(HANDLE hFile,
+ PLARGE_INTEGER lpFileSize);
+#endif
+
+
+/* Do platform-specific initialization. */
+int platform_init(int argc, char **argv) {
+ const char* tap;
+
+ tap = getenv("UV_TAP_OUTPUT");
+ tap_output = (tap != NULL && atoi(tap) > 0);
+
+ /* Disable the "application crashed" popup. */
+ SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
+ SEM_NOOPENFILEERRORBOX);
+#if !defined(__MINGW32__)
+ _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
+ _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
+#endif
+
+ _setmode(0, _O_BINARY);
+ _setmode(1, _O_BINARY);
+ _setmode(2, _O_BINARY);
+
+ /* Disable stdio output buffering. */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ strcpy(executable_path, argv[0]);
+
+ return 0;
+}
+
+
+int process_start(char *name, char *part, process_info_t *p, int is_helper) {
+ HANDLE file = INVALID_HANDLE_VALUE;
+ HANDLE nul = INVALID_HANDLE_VALUE;
+ WCHAR path[MAX_PATH], filename[MAX_PATH];
+ WCHAR image[MAX_PATH + 1];
+ WCHAR args[MAX_PATH * 2];
+ STARTUPINFOW si;
+ PROCESS_INFORMATION pi;
+ DWORD result;
+
+ if (GetTempPathW(sizeof(path) / sizeof(WCHAR), (WCHAR*)&path) == 0)
+ goto error;
+ if (GetTempFileNameW((WCHAR*)&path, L"uv", 0, (WCHAR*)&filename) == 0)
+ goto error;
+
+ file = CreateFileW((WCHAR*)filename,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
+ NULL);
+ if (file == INVALID_HANDLE_VALUE)
+ goto error;
+
+ if (!SetHandleInformation(file, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
+ goto error;
+
+ nul = CreateFileA("nul",
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (nul == INVALID_HANDLE_VALUE)
+ goto error;
+
+ if (!SetHandleInformation(nul, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
+ goto error;
+
+ result = GetModuleFileNameW(NULL,
+ (WCHAR*) &image,
+ sizeof(image) / sizeof(WCHAR));
+ if (result == 0 || result == sizeof(image))
+ goto error;
+
+ if (part) {
+ if (_snwprintf((WCHAR*)args,
+ sizeof(args) / sizeof(WCHAR),
+ L"\"%s\" %S %S",
+ image,
+ name,
+ part) < 0) {
+ goto error;
+ }
+ } else {
+ if (_snwprintf((WCHAR*)args,
+ sizeof(args) / sizeof(WCHAR),
+ L"\"%s\" %S",
+ image,
+ name) < 0) {
+ goto error;
+ }
+ }
+
+ memset((void*)&si, 0, sizeof(si));
+ si.cb = sizeof(si);
+ si.dwFlags = STARTF_USESTDHANDLES;
+ si.hStdInput = nul;
+ si.hStdOutput = file;
+ si.hStdError = file;
+
+ if (!CreateProcessW(image, args, NULL, NULL, TRUE,
+ 0, NULL, NULL, &si, &pi))
+ goto error;
+
+ CloseHandle(pi.hThread);
+
+ SetHandleInformation(nul, HANDLE_FLAG_INHERIT, 0);
+ SetHandleInformation(file, HANDLE_FLAG_INHERIT, 0);
+
+ p->stdio_in = nul;
+ p->stdio_out = file;
+ p->process = pi.hProcess;
+ p->name = part;
+
+ return 0;
+
+error:
+ if (file != INVALID_HANDLE_VALUE)
+ CloseHandle(file);
+ if (nul != INVALID_HANDLE_VALUE)
+ CloseHandle(nul);
+
+ return -1;
+}
+
+
+/* Timeout is is msecs. Set timeout < 0 to never time out. */
+/* Returns 0 when all processes are terminated, -2 on timeout. */
+int process_wait(process_info_t *vec, int n, int timeout) {
+ int i;
+ HANDLE handles[MAXIMUM_WAIT_OBJECTS];
+ DWORD timeout_api, result;
+
+ /* If there's nothing to wait for, return immediately. */
+ if (n == 0)
+ return 0;
+
+ ASSERT(n <= MAXIMUM_WAIT_OBJECTS);
+
+ for (i = 0; i < n; i++)
+ handles[i] = vec[i].process;
+
+ if (timeout >= 0) {
+ timeout_api = (DWORD)timeout;
+ } else {
+ timeout_api = INFINITE;
+ }
+
+ result = WaitForMultipleObjects(n, handles, TRUE, timeout_api);
+
+ if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + n) {
+ /* All processes are terminated. */
+ return 0;
+ }
+ if (result == WAIT_TIMEOUT) {
+ return -2;
+ }
+ return -1;
+}
+
+
+long int process_output_size(process_info_t *p) {
+ LARGE_INTEGER size;
+ if (!GetFileSizeEx(p->stdio_out, &size))
+ return -1;
+ return (long int)size.QuadPart;
+}
+
+
+int process_copy_output(process_info_t *p, int fd) {
+ DWORD read;
+ char buf[1024];
+ char *line, *start;
+
+ if (SetFilePointer(p->stdio_out,
+ 0,
+ 0,
+ FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
+ return -1;
+ }
+
+ if (tap_output)
+ write(fd, "#", 1);
+
+ while (ReadFile(p->stdio_out, (void*)&buf, sizeof(buf), &read, NULL) &&
+ read > 0) {
+ if (tap_output) {
+ start = buf;
+
+ while ((line = strchr(start, '\n')) != NULL) {
+ write(fd, start, line - start + 1);
+ write(fd, "#", 1);
+ start = line + 1;
+ }
+
+ if (start < buf + read)
+ write(fd, start, buf + read - start);
+ } else {
+ write(fd, buf, read);
+ }
+ }
+
+ if (tap_output)
+ write(fd, "\n", 1);
+
+ if (GetLastError() != ERROR_HANDLE_EOF)
+ return -1;
+
+ return 0;
+}
+
+
+int process_read_last_line(process_info_t *p,
+ char * buffer,
+ size_t buffer_len) {
+ DWORD size;
+ DWORD read;
+ DWORD start;
+ OVERLAPPED overlapped;
+
+ ASSERT(buffer_len > 0);
+
+ size = GetFileSize(p->stdio_out, NULL);
+ if (size == INVALID_FILE_SIZE)
+ return -1;
+
+ if (size == 0) {
+ buffer[0] = '\0';
+ return 1;
+ }
+
+ memset(&overlapped, 0, sizeof overlapped);
+ if (size >= buffer_len)
+ overlapped.Offset = size - buffer_len - 1;
+
+ if (!ReadFile(p->stdio_out, buffer, buffer_len - 1, &read, &overlapped))
+ return -1;
+
+ for (start = read - 1; start >= 0; start--) {
+ if (buffer[start] == '\n' || buffer[start] == '\r')
+ break;
+ }
+
+ if (start > 0)
+ memmove(buffer, buffer + start, read - start);
+
+ buffer[read - start] = '\0';
+
+ return 0;
+}
+
+
+char* process_get_name(process_info_t *p) {
+ return p->name;
+}
+
+
+int process_terminate(process_info_t *p) {
+ if (!TerminateProcess(p->process, 1))
+ return -1;
+ return 0;
+}
+
+
+int process_reap(process_info_t *p) {
+ DWORD exitCode;
+ if (!GetExitCodeProcess(p->process, &exitCode))
+ return -1;
+ return (int)exitCode;
+}
+
+
+void process_cleanup(process_info_t *p) {
+ CloseHandle(p->process);
+ CloseHandle(p->stdio_in);
+ CloseHandle(p->stdio_out);
+}
+
+
+static int clear_line() {
+ HANDLE handle;
+ CONSOLE_SCREEN_BUFFER_INFO info;
+ COORD coord;
+ DWORD written;
+
+ handle = (HANDLE)_get_osfhandle(fileno(stderr));
+ if (handle == INVALID_HANDLE_VALUE)
+ return -1;
+
+ if (!GetConsoleScreenBufferInfo(handle, &info))
+ return -1;
+
+ coord = info.dwCursorPosition;
+ if (coord.Y <= 0)
+ return -1;
+
+ coord.X = 0;
+
+ if (!SetConsoleCursorPosition(handle, coord))
+ return -1;
+
+ if (!FillConsoleOutputCharacterW(handle,
+ 0x20,
+ info.dwSize.X,
+ coord,
+ &written)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+void rewind_cursor() {
+ if (clear_line() == -1) {
+ /* If clear_line fails (stdout is not a console), print a newline. */
+ fprintf(stderr, "\n");
+ }
+}
+
+
+/* Pause the calling thread for a number of milliseconds. */
+void uv_sleep(int msec) {
+ Sleep(msec);
+}