1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50060 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2015-03-23 05:40:48 +00:00
parent 9da887cf57
commit f5b96e594c
7 changed files with 115 additions and 2 deletions

View file

@ -1,3 +1,10 @@
Mon Mar 23 14:40:45 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* 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@ruby-lang.org> Mon Mar 23 02:03:28 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* marshal.c (r_symreal): register symbol names as strings first so * marshal.c (r_symreal): register symbol names as strings first so

View file

@ -1094,6 +1094,7 @@ main()
ac_cv_header_sys_time_h=no ac_cv_header_sys_time_h=no
ac_cv_header_sys_times_h=no ac_cv_header_sys_times_h=no
ac_cv_header_sys_socket_h=no ac_cv_header_sys_socket_h=no
ac_cv_func_lstat=yes
ac_cv_func_times=yes ac_cv_func_times=yes
ac_cv_func_waitpid=yes ac_cv_func_waitpid=yes
ac_cv_func_fsync=yes ac_cv_func_fsync=yes

2
dir.c
View file

@ -1135,6 +1135,8 @@ sys_enc_warning_in(const char *func, const char *mesg, rb_encoding *enc)
#ifdef _WIN32 #ifdef _WIN32
#define STAT(p, s) rb_w32_ustati64((p), (s)) #define STAT(p, s) rb_w32_ustati64((p), (s))
#undef lstat
#define lstat(p, s) rb_w32_ulstati64((p), (s))
#else #else
#define STAT(p, s) stat((p), (s)) #define STAT(p, s) stat((p), (s))
#endif #endif

2
file.c
View file

@ -95,7 +95,7 @@ int flock(int, int);
#ifdef _WIN32 #ifdef _WIN32
#define STAT(p, s) rb_w32_ustati64((p), (s)) #define STAT(p, s) rb_w32_ustati64((p), (s))
#undef lstat #undef lstat
#define lstat(p, s) rb_w32_ustati64((p), (s)) #define lstat(p, s) rb_w32_ulstati64((p), (s))
#undef access #undef access
#define access(p, m) rb_w32_uaccess((p), (m)) #define access(p, m) rb_w32_uaccess((p), (m))
#undef chmod #undef chmod

View file

@ -215,6 +215,7 @@ typedef int clockid_t;
extern int rb_w32_stat(const char *, struct stat *); extern int rb_w32_stat(const char *, struct stat *);
extern int rb_w32_fstat(int, struct stat *); extern int rb_w32_fstat(int, struct stat *);
#endif #endif
#define lstat(path,st) rb_w32_lstati64(path,st)
#define access(path,mode) rb_w32_access(path,mode) #define access(path,mode) rb_w32_access(path,mode)
#define strcasecmp _stricmp #define strcasecmp _stricmp
@ -343,6 +344,8 @@ extern int rb_w32_uunlink(const char *);
extern int rb_w32_uchmod(const char *, int); extern int rb_w32_uchmod(const char *, int);
extern int rb_w32_stati64(const char *, struct stati64 *); extern int rb_w32_stati64(const char *, struct stati64 *);
extern int rb_w32_ustati64(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_access(const char *, int);
extern int rb_w32_uaccess(const char *, int); extern int rb_w32_uaccess(const char *, int);
extern char rb_w32_fd_is_text(int); extern char rb_w32_fd_is_text(int);

View file

@ -708,6 +708,7 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub
#define HAVE_GETCWD 1 #define HAVE_GETCWD 1
#define HAVE_TRUNCATE 1 #define HAVE_TRUNCATE 1
#define HAVE_FTRUNCATE 1 #define HAVE_FTRUNCATE 1
#define HAVE_LSTAT 1
#define HAVE_TIMES 1 #define HAVE_TIMES 1
#define HAVE_FCNTL 1 #define HAVE_FCNTL 1
#define HAVE_LINK 1 #define HAVE_LINK 1

View file

@ -61,6 +61,7 @@ DWORD WINAPI GetFinalPathNameByHandleW(HANDLE, LPWSTR, DWORD, DWORD);
#endif #endif
static int w32_stati64(const char *path, struct stati64 *st, UINT cp); 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); static char *w32_getenv(const char *name, UINT cp);
#undef getenv #undef getenv
@ -111,6 +112,7 @@ static int has_redirection(const char *, UINT);
int rb_w32_wait_events(HANDLE *events, int num, DWORD timeout); int rb_w32_wait_events(HANDLE *events, int num, DWORD timeout);
static int rb_w32_open_osfhandle(intptr_t osfhandle, int flags); static int rb_w32_open_osfhandle(intptr_t osfhandle, int flags);
static int wstati64(const WCHAR *path, struct stati64 *st); 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); 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); int ruby_brace_glob_with_enc(const char *str, int flags, ruby_glob_func *func, VALUE arg, rb_encoding *enc);
@ -5079,9 +5081,54 @@ path_drive(const WCHAR *path)
towupper(path[0]) - L'A' : _getdrive() - 1; towupper(path[0]) - L'A' : _getdrive() - 1;
} }
static const WCHAR namespace_prefix[] = {L'\\', L'\\', L'?', L'\\'};
/* License: Ruby's */ /* License: Ruby's */
static int static int
winnt_stat(const WCHAR *path, struct stati64 *st) 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; WIN32_FILE_ATTRIBUTE_DATA wfa;
const WCHAR *p = path; const WCHAR *p = path;
@ -5089,7 +5136,8 @@ winnt_stat(const WCHAR *path, struct stati64 *st)
memset(st, 0, sizeof(*st)); memset(st, 0, sizeof(*st));
st->st_nlink = 1; 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"?*")) { if (wcspbrk(p, L"?*")) {
errno = ENOENT; errno = ENOENT;
return -1; return -1;
@ -5150,6 +5198,29 @@ wstati64(const WCHAR *path, struct stati64 *st)
return ret; return ret;
} }
/* 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 */ /* License: Ruby's */
static WCHAR * static WCHAR *
name_for_stat(WCHAR *buf1, const WCHAR *path) name_for_stat(WCHAR *buf1, const WCHAR *path)
@ -5212,6 +5283,34 @@ w32_stati64(const char *path, struct stati64 *st, UINT cp)
return ret; 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 */ /* License: Ruby's */
int int
rb_w32_access(const char *path, int mode) rb_w32_access(const char *path, int mode)