Skip to content

Commit 4cd21de

Browse files
committed
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.
1 parent bff1ff2 commit 4cd21de

File tree

5 files changed

+47
-4
lines changed

5 files changed

+47
-4
lines changed

unix/main.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -394,11 +394,7 @@ int main(int argc, char **argv) {
394394
return usage(argv);
395395
}
396396
} else {
397-
#ifdef __MINGW32__
398-
char *basedir = _fullpath(NULL, argv[a], _MAX_PATH);
399-
#else
400397
char *basedir = realpath(argv[a], NULL);
401-
#endif
402398
if (basedir == NULL) {
403399
fprintf(stderr, "%s: can't open file '%s': [Errno %d] ", argv[0], argv[1], errno);
404400
perror("");

windows/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ endif
3030
SRC_C = \
3131
unix/main.c \
3232
unix/file.c \
33+
realpath.c \
3334

3435
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
3536

windows/mpconfigport.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,5 @@ typedef const void *machine_const_ptr_t; // must be of pointer size
3636
extern const struct _mp_obj_fun_native_t mp_builtin_open_obj;
3737
#define MICROPY_EXTRA_BUILTINS \
3838
{ MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj },
39+
40+
#include "realpath.h"

windows/realpath.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include <stdlib.h>
2+
#include <errno.h>
3+
#include <io.h>
4+
5+
#ifndef R_OK
6+
#define R_OK 4
7+
#endif
8+
9+
// Make sure a path only has forward slashes.
10+
char *to_unix_path(char *p) {
11+
if (p != NULL) {
12+
char *pp = p;
13+
while (*pp != 0) {
14+
if (*pp == '\\')
15+
*pp = '/';
16+
++pp;
17+
}
18+
}
19+
return p;
20+
}
21+
22+
// Implement realpath() using _fullpath and make it use the same error codes as realpath() on unix.
23+
// Also have it return a path with forward slashes only as some code relies on this,
24+
// but _fullpath() returns backward slashes no matter what.
25+
char *realpath(const char *path, char *resolved_path) {
26+
char *ret = NULL;
27+
if (path == NULL) {
28+
errno = EINVAL;
29+
} else if (access(path, R_OK) == 0) {
30+
ret = resolved_path;
31+
if (ret == NULL)
32+
ret = malloc(_MAX_PATH);
33+
if (ret == NULL) {
34+
errno = ENOMEM;
35+
} else {
36+
ret = _fullpath(ret, path, _MAX_PATH);
37+
if (ret == NULL)
38+
errno = EIO;
39+
}
40+
}
41+
return to_unix_path(ret);
42+
}

windows/realpath.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
extern char *realpath(const char *path, char *resolved_path);

0 commit comments

Comments
 (0)