From 4cd21deebca0e75b77d62d8d748aa66453532d9b Mon Sep 17 00:00:00 2001 From: stijn Date: Sat, 3 May 2014 10:26:04 +0200 Subject: [PATCH] mingw: Add implementation of realpath() The mingw port used _fullpath() until now, but the behaviour is not exactly the same as realpath()'s on unix; major difference being that it doesn't return an error for non-existing files, which would bypass main's error checking and bail out without any error message. Also realpath() will return forward slashes only since main() relies on that. --- unix/main.c | 4 ---- windows/Makefile | 1 + windows/mpconfigport.h | 2 ++ windows/realpath.c | 42 ++++++++++++++++++++++++++++++++++++++++++ windows/realpath.h | 2 ++ 5 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 windows/realpath.c create mode 100644 windows/realpath.h diff --git a/unix/main.c b/unix/main.c index e677ff65d0..c001bc8109 100644 --- a/unix/main.c +++ b/unix/main.c @@ -394,11 +394,7 @@ int main(int argc, char **argv) { return usage(argv); } } else { -#ifdef __MINGW32__ - char *basedir = _fullpath(NULL, argv[a], _MAX_PATH); -#else char *basedir = realpath(argv[a], NULL); -#endif if (basedir == NULL) { fprintf(stderr, "%s: can't open file '%s': [Errno %d] ", argv[0], argv[1], errno); perror(""); diff --git a/windows/Makefile b/windows/Makefile index 2f5418886f..351aad6f1a 100644 --- a/windows/Makefile +++ b/windows/Makefile @@ -30,6 +30,7 @@ endif SRC_C = \ unix/main.c \ unix/file.c \ + realpath.c \ OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) diff --git a/windows/mpconfigport.h b/windows/mpconfigport.h index 80d8ac89b5..d27c59cb31 100644 --- a/windows/mpconfigport.h +++ b/windows/mpconfigport.h @@ -36,3 +36,5 @@ typedef const void *machine_const_ptr_t; // must be of pointer size extern const struct _mp_obj_fun_native_t mp_builtin_open_obj; #define MICROPY_EXTRA_BUILTINS \ { MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj }, + +#include "realpath.h" diff --git a/windows/realpath.c b/windows/realpath.c new file mode 100644 index 0000000000..550298a7d5 --- /dev/null +++ b/windows/realpath.c @@ -0,0 +1,42 @@ +#include +#include +#include + +#ifndef R_OK + #define R_OK 4 +#endif + +// Make sure a path only has forward slashes. +char *to_unix_path(char *p) { + if (p != NULL) { + char *pp = p; + while (*pp != 0) { + if (*pp == '\\') + *pp = '/'; + ++pp; + } + } + return p; +} + +// Implement realpath() using _fullpath and make it use the same error codes as realpath() on unix. +// Also have it return a path with forward slashes only as some code relies on this, +// but _fullpath() returns backward slashes no matter what. +char *realpath(const char *path, char *resolved_path) { + char *ret = NULL; + if (path == NULL) { + errno = EINVAL; + } else if (access(path, R_OK) == 0) { + ret = resolved_path; + if (ret == NULL) + ret = malloc(_MAX_PATH); + if (ret == NULL) { + errno = ENOMEM; + } else { + ret = _fullpath(ret, path, _MAX_PATH); + if (ret == NULL) + errno = EIO; + } + } + return to_unix_path(ret); +} diff --git a/windows/realpath.h b/windows/realpath.h new file mode 100644 index 0000000000..77798acd57 --- /dev/null +++ b/windows/realpath.h @@ -0,0 +1,2 @@ + +extern char *realpath(const char *path, char *resolved_path);