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:
parent
9da887cf57
commit
f5b96e594c
7 changed files with 115 additions and 2 deletions
|
@ -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
|
||||||
|
|
|
@ -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
2
dir.c
|
@ -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
2
file.c
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
101
win32/win32.c
101
win32/win32.c
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue