[前][次][番号順一覧][スレッド一覧]

ruby-changes:37979

From: nobu <ko1@a...>
Date: Mon, 23 Mar 2015 14:41:06 +0900 (JST)
Subject: [ruby-changes:37979] nobu:r50060 (trunk): win32.c: w32_lstati64

nobu	2015-03-23 14:40:48 +0900 (Mon, 23 Mar 2015)

  New Revision: 50060

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=50060

  Log:
    win32.c: w32_lstati64
    
    * win32/win32.c (winnt_stat): stat with following symbolic links.
    * win32/win32.c (winnt_lstat): rename old winnt_stat, which does
      not follow symbolic links.

  Modified files:
    trunk/ChangeLog
    trunk/configure.in
    trunk/dir.c
    trunk/file.c
    trunk/include/ruby/win32.h
    trunk/win32/Makefile.sub
    trunk/win32/win32.c
Index: include/ruby/win32.h
===================================================================
--- include/ruby/win32.h	(revision 50059)
+++ include/ruby/win32.h	(revision 50060)
@@ -215,6 +215,7 @@ typedef int clockid_t; https://github.com/ruby/ruby/blob/trunk/include/ruby/win32.h#L215
 extern int rb_w32_stat(const char *, struct stat *);
 extern int rb_w32_fstat(int, struct stat *);
 #endif
+#define lstat(path,st)		rb_w32_lstati64(path,st)
 #define access(path,mode)	rb_w32_access(path,mode)
 
 #define strcasecmp		_stricmp
@@ -343,6 +344,8 @@ extern int rb_w32_uunlink(const char *); https://github.com/ruby/ruby/blob/trunk/include/ruby/win32.h#L344
 extern int rb_w32_uchmod(const char *, int);
 extern int rb_w32_stati64(const char *, struct stati64 *);
 extern int rb_w32_ustati64(const char *, struct stati64 *);
+extern int rb_w32_lstati64(const char *, struct stati64 *);
+extern int rb_w32_ulstati64(const char *, struct stati64 *);
 extern int rb_w32_access(const char *, int);
 extern int rb_w32_uaccess(const char *, int);
 extern char rb_w32_fd_is_text(int);
Index: configure.in
===================================================================
--- configure.in	(revision 50059)
+++ configure.in	(revision 50060)
@@ -1094,6 +1094,7 @@ main() https://github.com/ruby/ruby/blob/trunk/configure.in#L1094
 		ac_cv_header_sys_time_h=no
 		ac_cv_header_sys_times_h=no
 		ac_cv_header_sys_socket_h=no
+		ac_cv_func_lstat=yes
 		ac_cv_func_times=yes
 		ac_cv_func_waitpid=yes
 		ac_cv_func_fsync=yes
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 50059)
+++ ChangeLog	(revision 50060)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Mon Mar 23 14:40:45 2015  Nobuyoshi Nakada  <nobu@r...>
+
+	* win32/win32.c (winnt_stat): stat with following symbolic links.
+
+	* win32/win32.c (winnt_lstat): rename old winnt_stat, which does
+	  not follow symbolic links.
+
 Mon Mar 23 02:03:28 2015  Nobuyoshi Nakada  <nobu@r...>
 
 	* marshal.c (r_symreal): register symbol names as strings first so
Index: dir.c
===================================================================
--- dir.c	(revision 50059)
+++ dir.c	(revision 50060)
@@ -1135,6 +1135,8 @@ sys_enc_warning_in(const char *func, con https://github.com/ruby/ruby/blob/trunk/dir.c#L1135
 
 #ifdef _WIN32
 #define STAT(p, s)	rb_w32_ustati64((p), (s))
+#undef lstat
+#define lstat(p, s)	rb_w32_ulstati64((p), (s))
 #else
 #define STAT(p, s)	stat((p), (s))
 #endif
Index: win32/win32.c
===================================================================
--- win32/win32.c	(revision 50059)
+++ win32/win32.c	(revision 50060)
@@ -61,6 +61,7 @@ DWORD WINAPI GetFinalPathNameByHandleW(H https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L61
 #endif
 
 static int w32_stati64(const char *path, struct stati64 *st, UINT cp);
+static int w32_lstati64(const char *path, struct stati64 *st, UINT cp);
 static char *w32_getenv(const char *name, UINT cp);
 
 #undef getenv
@@ -111,6 +112,7 @@ static int has_redirection(const char *, https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L112
 int rb_w32_wait_events(HANDLE *events, int num, DWORD timeout);
 static int rb_w32_open_osfhandle(intptr_t osfhandle, int flags);
 static int wstati64(const WCHAR *path, struct stati64 *st);
+static int wlstati64(const WCHAR *path, struct stati64 *st);
 VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc);
 int ruby_brace_glob_with_enc(const char *str, int flags, ruby_glob_func *func, VALUE arg, rb_encoding *enc);
 
@@ -5079,17 +5081,63 @@ path_drive(const WCHAR *path) https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L5081
 	towupper(path[0]) - L'A' : _getdrive() - 1;
 }
 
+static const WCHAR namespace_prefix[] = {L'\\', L'\\', L'?', L'\\'};
+
 /* License: Ruby's */
 static int
 winnt_stat(const WCHAR *path, struct stati64 *st)
 {
+    HANDLE f;
+
+    typedef DWORD (WINAPI *get_final_path_func)(HANDLE, WCHAR*, DWORD, DWORD);
+    static get_final_path_func get_final_path = (get_final_path_func)-1;
+
+    if (get_final_path == (get_final_path_func)-1) {
+	get_final_path = (get_final_path_func)
+	    get_proc_address(NULL, "GetFinalPathNameByHandleW", NULL);
+    }
+
+    memset(st, 0, sizeof(*st));
+    f = CreateFileW(path, 0, 0, NULL, OPEN_EXISTING,
+		    FILE_FLAG_BACKUP_SEMANTICS, NULL);
+    if (f != INVALID_HANDLE_VALUE) {
+	WCHAR finalname[MAX_PATH];
+	const DWORD attr = stati64_handle(f, st);
+	const DWORD len = get_final_path ?
+	    get_final_path(f, finalname, numberof(finalname), 0) : 0;
+	CloseHandle(f);
+	if (attr & FILE_ATTRIBUTE_DIRECTORY) {
+	    if (check_valid_dir(path)) return -1;
+	}
+	st->st_mode = fileattr_to_unixmode(attr, path);
+	if (len) {
+	    finalname[len] = L'\0';
+	    path = finalname;
+	    if (wcsncmp(path, namespace_prefix, numberof(namespace_prefix)) == 0)
+		path += numberof(namespace_prefix);
+	}
+    }
+    else {
+	if (stat_by_find(path, st)) return -1;
+    }
+
+    st->st_dev = st->st_rdev = path_drive(path);
+
+    return 0;
+}
+
+/* License: Ruby's */
+static int
+winnt_lstat(const WCHAR *path, struct stati64 *st)
+{
     WIN32_FILE_ATTRIBUTE_DATA wfa;
     const WCHAR *p = path;
 
     memset(st, 0, sizeof(*st));
     st->st_nlink = 1;
 
-    if (wcsncmp(p, L"\\\\?\\", 4) == 0) p += 4;
+    if (wcsncmp(p, namespace_prefix, numberof(namespace_prefix)) == 0)
+	p += numberof(namespace_prefix);
     if (wcspbrk(p, L"?*")) {
 	errno = ENOENT;
 	return -1;
@@ -5151,6 +5199,29 @@ wstati64(const WCHAR *path, struct stati https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L5199
 }
 
 /* License: Ruby's */
+static int
+wlstati64(const WCHAR *path, struct stati64 *st)
+{
+    WCHAR *buf1;
+    int ret, size;
+    VALUE v;
+
+    if (!path || !st) {
+	errno = EFAULT;
+	return -1;
+    }
+    size = lstrlenW(path) + 2;
+    buf1 = ALLOCV_N(WCHAR, v, size);
+    if (!(path = name_for_stat(buf1, path)))
+	return -1;
+    ret = winnt_lstat(path, st);
+    if (v)
+	ALLOCV_END(v);
+
+    return ret;
+}
+
+/* License: Ruby's */
 static WCHAR *
 name_for_stat(WCHAR *buf1, const WCHAR *path)
 {
@@ -5211,6 +5282,34 @@ w32_stati64(const char *path, struct sta https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L5282
     free(wpath);
     return ret;
 }
+
+/* License: Ruby's */
+int
+rb_w32_ulstati64(const char *path, struct stati64 *st)
+{
+    return w32_lstati64(path, st, CP_UTF8);
+}
+
+/* License: Ruby's */
+int
+rb_w32_lstati64(const char *path, struct stati64 *st)
+{
+    return w32_lstati64(path, st, filecp());
+}
+
+/* License: Ruby's */
+static int
+w32_lstati64(const char *path, struct stati64 *st, UINT cp)
+{
+    WCHAR *wpath;
+    int ret;
+
+    if (!(wpath = mbstr_to_wstr(cp, path, -1, NULL)))
+	return -1;
+    ret = wlstati64(wpath, st);
+    free(wpath);
+    return ret;
+}
 
 /* License: Ruby's */
 int
Index: win32/Makefile.sub
===================================================================
--- win32/Makefile.sub	(revision 50059)
+++ win32/Makefile.sub	(revision 50060)
@@ -708,6 +708,7 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/ https://github.com/ruby/ruby/blob/trunk/win32/Makefile.sub#L708
 #define HAVE_GETCWD 1
 #define HAVE_TRUNCATE 1
 #define HAVE_FTRUNCATE 1
+#define HAVE_LSTAT 1
 #define HAVE_TIMES 1
 #define HAVE_FCNTL 1
 #define HAVE_LINK 1
Index: file.c
===================================================================
--- file.c	(revision 50059)
+++ file.c	(revision 50060)
@@ -95,7 +95,7 @@ int flock(int, int); https://github.com/ruby/ruby/blob/trunk/file.c#L95
 #ifdef _WIN32
 #define STAT(p, s)	rb_w32_ustati64((p), (s))
 #undef lstat
-#define lstat(p, s)	rb_w32_ustati64((p), (s))
+#define lstat(p, s)	rb_w32_ulstati64((p), (s))
 #undef access
 #define access(p, m)	rb_w32_uaccess((p), (m))
 #undef chmod

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]