From 136e763211aa4fc7c8c67a68c6597a6535aaf7d8 Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Fri, 16 Sep 2011 00:37:34 +0200 Subject: [PATCH] Add fixtures support for Win32 Oh windows, how I heart thee --- clay.c | 25 +++++++++++++++++-- clay_fs.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ clay_sandbox.c | 37 ++++++++++++++++----------- 3 files changed, 114 insertions(+), 16 deletions(-) diff --git a/clay.c b/clay.c index afe1089..a45b6d7 100644 --- a/clay.c +++ b/clay.c @@ -6,8 +6,29 @@ #include /* required for sandboxing */ +#include #include -#include + +#ifdef _WIN32 +# include +# include +# include +# pragma comment(lib, "shell32") + +# define PLATFORM_SEP '\\' +# define stat(path, st) _stat(path, st) +# define mkdir(path, mode) _mkdir(path) +# define access(path, mode) _access(path, mode) +# define mktemp(path) _mktemp(path) + +# define W_OK 02 +# define S_ISDIR(x) (x & _S_IFDIR) != 0 + typedef struct _stat STAT_T; +#else +# define PLATFORM_SEP '/' +# include + typedef struct stat STAT_T; +#endif #include "clay.h" @@ -308,7 +329,7 @@ clay__assert( if (should_abort) { if (!_clay.trampoline_enabled) { fprintf(stderr, - "Unhandled exception: a cleanup method raised an exception."); + "Fatal error: a cleanup method raised an exception."); exit(-1); } diff --git a/clay_fs.c b/clay_fs.c index fe22337..5521b8d 100644 --- a/clay_fs.c +++ b/clay_fs.c @@ -1,3 +1,70 @@ +#ifdef _WIN32 + +#define FOF_FLAGS (FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR) + +static char * +fileops_path(const char *_path) +{ + char *path = NULL; + size_t length, i; + + if (_path == NULL) + return NULL; + + length = strlen(_path); + path = malloc(length + 2); + + if (path == NULL) + return NULL; + + memcpy(path, _path, length); + path[length] = 0; + path[length + 1] = 0; + + for (i = 0; i < length; ++i) { + if (path[i] == '/') + path[i] = '\\'; + } + + return path; +} + +static void +fileops(int mode, const char *_source, const char *_dest) +{ + SHFILEOPSTRUCT fops; + + char *source = fileops_path(_source); + char *dest = fileops_path(_dest); + + ZeroMemory(&fops, sizeof(SHFILEOPSTRUCT)); + + fops.wFunc = mode; + fops.pFrom = source; + fops.pTo = dest; + fops.fFlags = FOF_FLAGS; + + cl_assert_( + SHFileOperation(&fops) == 0, + "Windows SHFileOperation failed" + ); + + free(source); +} + +static void +fs_rm(const char *_source) +{ + fileops(FO_DELETE, _source, NULL); +} + +static void +fs_copy(const char *_source, const char *_dest) +{ + fileops(FO_COPY, _source, _dest); +} + +#else static int shell_out(char * const argv[]) { @@ -62,3 +129,4 @@ fs_rm(const char *source) "Failed to cleanup the sandbox" ); } +#endif diff --git a/clay_sandbox.c b/clay_sandbox.c index 7944de1..222a696 100644 --- a/clay_sandbox.c +++ b/clay_sandbox.c @@ -1,19 +1,17 @@ -#ifdef _WIN32 -# define PLATFORM_SEP '\\' -#else -# define PLATFORM_SEP '/' -#endif - static char _clay_path[4096]; static int is_valid_tmp_path(const char *path) { - struct stat st; - return (lstat(path, &st) == 0 && - (S_ISDIR(st.st_mode) || - S_ISLNK(st.st_mode)) && - access(path, W_OK) == 0); + STAT_T st; + + if (stat(path, &st) != 0) + return 0; + + if (!S_ISDIR(st.st_mode)) + return 0; + + return (access(path, W_OK) == 0); } static int @@ -62,21 +60,32 @@ static void clay_unsandbox(void) if (_clay_path[0] == '\0') return; +#ifdef _WIN32 + chdir(".."); +#endif + fs_rm(_clay_path); } static int clay_sandbox(void) { const char path_tail[] = "clay_tmp_XXXXXX"; - size_t len; + size_t len, i; if (!find_tmp_path(_clay_path, sizeof(_clay_path))) return 0; len = strlen(_clay_path); - if (_clay_path[len - 1] != PLATFORM_SEP) { - _clay_path[len++] = PLATFORM_SEP; +#ifdef _WIN32 + for (i = 0; i < len; ++i) { + if (_clay_path[i] == '\\') + _clay_path[i] = '/'; + } +#endif + + if (_clay_path[len - 1] != '/') { + _clay_path[len++] = '/'; } strcpy(_clay_path + len, path_tail);