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.
pull/554/head
stijn 2014-05-03 10:26:04 +02:00
rodzic bff1ff28ee
commit 4cd21deebc
5 zmienionych plików z 47 dodań i 4 usunięć

Wyświetl plik

@ -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("");

Wyświetl plik

@ -30,6 +30,7 @@ endif
SRC_C = \
unix/main.c \
unix/file.c \
realpath.c \
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))

Wyświetl plik

@ -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"

42
windows/realpath.c 100644
Wyświetl plik

@ -0,0 +1,42 @@
#include <stdlib.h>
#include <errno.h>
#include <io.h>
#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);
}

Wyświetl plik

@ -0,0 +1,2 @@
extern char *realpath(const char *path, char *resolved_path);