Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
diff --git a/Makefile.in b/Makefile.in
index a3040b6..83d525b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -12,6 +12,7 @@ NULL = /dev/null
srcdir = @srcdir@
top_srcdir = $(srcdir)
hdrdir = $(srcdir)/include
+PLATFORM = @PLATFORM@
CC = @CC@
CPP = @CPP@
diff --git a/common.mk b/common.mk
index 88a3552..de22d39 100644
--- a/common.mk
+++ b/common.mk
@@ -572,7 +572,11 @@ dl_os2.$(OBJEXT): {$(VPATH)}dl_os2.c
ia64.$(OBJEXT): {$(VPATH)}ia64.s
$(CC) $(CFLAGS) -c $<
-win32.$(OBJEXT): {$(VPATH)}win32.c $(RUBY_H_INCLUDES)
+make-platform-dir:
+ $(Q) $(MAKEDIRS) $(PLATFORM)
+
+win32/win32.$(OBJEXT): {$(VPATH)}win32/win32.c $(RUBY_H_INCLUDES) make-platform-dir
+$(PLATFORM)/file.$(OBJEXT): {$(VPATH)}$(PLATFORM)/file.c $(RUBY_H_INCLUDES) make-platform-dir
###
diff --git a/configure.in b/configure.in
index b9f3c79..e64135d 100644
--- a/configure.in
+++ b/configure.in
@@ -2589,7 +2589,8 @@ AS_CASE(["$target_os"],
fi
EXPORT_PREFIX=' '
DLDFLAGS="${DLDFLAGS}"' $(DEFFILE)'
- AC_LIBOBJ([win32])
+ AC_LIBOBJ([win32/win32])
+ PLATFORM="win32"
COMMON_LIBS=m
# COMMON_MACROS="WIN32_LEAN_AND_MEAN="
COMMON_HEADERS="winsock2.h windows.h"
@@ -2613,6 +2614,17 @@ AS_CASE(["$target_os"],
])])
MINIOBJS="$MINIDLNOBJ"
+: ${PLATFORM:=posix}
+AC_SUBST(PLATFORM)
+
+AS_CASE(["$PLATFORM"],
+[win32], [
+ AC_LIBOBJ([win32/file])
+ ],
+[
+ AC_LIBOBJ([posix/file])
+])
+
AS_CASE(["$THREAD_MODEL"],
[pthread], [AC_CHECK_HEADERS(pthread.h)],
[win32], [],
diff --git a/file.c b/file.c
index fb62c51..75085b2 100644
--- a/file.c
+++ b/file.c
@@ -5063,31 +5063,6 @@ rb_path_check(const char *path)
}
static int
-file_load_ok(const char *path)
-{
- int ret = 1;
- int fd = rb_cloexec_open(path, O_RDONLY, 0);
- if (fd == -1) return 0;
- rb_update_max_fd(fd);
-#if !defined DOSISH
- {
- struct stat st;
- if (fstat(fd, &st) || !S_ISREG(st.st_mode)) {
- ret = 0;
- }
- }
-#endif
- (void)close(fd);
- return ret;
-}
-
-int
-rb_file_load_ok(const char *path)
-{
- return file_load_ok(path);
-}
-
-static int
is_explicit_relative(const char *path)
{
if (*path++ != '.') return 0;
@@ -5137,7 +5112,7 @@ rb_find_file_ext_safe(VALUE *filep, const char *const *ext, int safe_level)
fnlen = RSTRING_LEN(fname);
for (i=0; ext[i]; i++) {
rb_str_cat2(fname, ext[i]);
- if (file_load_ok(RSTRING_PTR(fname))) {
+ if (rb_file_load_ok(RSTRING_PTR(fname))) {
*filep = copy_path_class(fname, *filep);
return (int)(i+1);
}
@@ -5165,7 +5140,7 @@ rb_find_file_ext_safe(VALUE *filep, const char *const *ext, int safe_level)
RB_GC_GUARD(str) = rb_get_path_check(str, safe_level);
if (RSTRING_LEN(str) == 0) continue;
file_expand_path(fname, str, 0, tmp);
- if (file_load_ok(RSTRING_PTR(tmp))) {
+ if (rb_file_load_ok(RSTRING_PTR(tmp))) {
*filep = copy_path_class(tmp, *filep);
return (int)(j+1);
}
@@ -5204,7 +5179,7 @@ rb_find_file_safe(VALUE path, int safe_level)
if (safe_level >= 1 && !fpath_check(path)) {
rb_raise(rb_eSecurityError, "loading from unsafe path %s", f);
}
- if (!file_load_ok(f)) return 0;
+ if (!rb_file_load_ok(f)) return 0;
if (!expanded)
path = copy_path_class(file_expand_path_1(path), path);
return path;
@@ -5225,7 +5200,7 @@ rb_find_file_safe(VALUE path, int safe_level)
if (RSTRING_LEN(str) > 0) {
file_expand_path(path, str, 0, tmp);
f = RSTRING_PTR(tmp);
- if (file_load_ok(f)) goto found;
+ if (rb_file_load_ok(f)) goto found;
}
}
return 0;
diff --git a/posix/file.c b/posix/file.c
new file mode 100644
index 0000000..f4f2893
--- /dev/null
+++ b/posix/file.c
@@ -0,0 +1,30 @@
+#include "ruby/ruby.h"
+#include "ruby/io.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined(HAVE_FCNTL_H)
+#include <fcntl.h>
+#endif
+
+int
+rb_file_load_ok(const char *path)
+{
+ int ret = 1;
+ int fd = rb_cloexec_open(path, O_RDONLY, 0);
+ if (fd == -1) return 0;
+ rb_update_max_fd(fd);
+ {
+ struct stat st;
+ if (fstat(fd, &st) || !S_ISREG(st.st_mode)) {
+ ret = 0;
+ }
+ }
+ (void)close(fd);
+ return ret;
+}
diff --git a/win32/file.c b/win32/file.c
new file mode 100644
index 0000000..cd89da2
--- /dev/null
+++ b/win32/file.c
@@ -0,0 +1,25 @@
+#include "ruby/ruby.h"
+#include <winbase.h>
+
+int
+rb_file_load_ok(const char *path)
+{
+ int ret = 1;
+ DWORD attr = GetFileAttributes(path);
+ if (attr == INVALID_FILE_ATTRIBUTES ||
+ attr & FILE_ATTRIBUTE_DIRECTORY) {
+ ret = 0;
+ }
+ else {
+ HANDLE h = CreateFile(path, GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h != INVALID_HANDLE_VALUE) {
+ CloseHandle(h);
+ }
+ else {
+ ret = 0;
+ }
+ }
+ return ret;
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment