mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
dir.c: replace_real_basename
* dir.c (replace_real_basename): get the real name and replace the base name with it by getattrlist(2) if available. suggested by Matthew Draper at [ruby-core:67116]. [Bug #10015] * dir.c (glob_helper): get the real name of the whole path, not only the last name. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48990 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
913943270d
commit
0ebfc6f216
4 changed files with 74 additions and 12 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
Thu Dec 25 15:36:15 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* dir.c (replace_real_basename): get the real name and replace the
|
||||||
|
base name with it by getattrlist(2) if available.
|
||||||
|
suggested by Matthew Draper at [ruby-core:67116]. [Bug #10015]
|
||||||
|
|
||||||
|
* dir.c (glob_helper): get the real name of the whole path, not
|
||||||
|
only the last name.
|
||||||
|
|
||||||
Thu Dec 25 13:59:17 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Thu Dec 25 13:59:17 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* configure.in (NET_LUID): include also ifdef.h as a workaround of
|
* configure.in (NET_LUID): include also ifdef.h as a workaround of
|
||||||
|
|
|
@ -1188,6 +1188,7 @@ AC_CHECK_HEADERS( \
|
||||||
malloc_np.h \
|
malloc_np.h \
|
||||||
malloc/malloc.h \
|
malloc/malloc.h \
|
||||||
setjmpex.h \
|
setjmpex.h \
|
||||||
|
sys/attr.h \
|
||||||
sys/id.h
|
sys/id.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2038,6 +2039,7 @@ AC_CHECK_FUNCS(fmod)
|
||||||
AC_CHECK_FUNCS(fsync)
|
AC_CHECK_FUNCS(fsync)
|
||||||
AC_CHECK_FUNCS(ftruncate)
|
AC_CHECK_FUNCS(ftruncate)
|
||||||
AC_CHECK_FUNCS(ftruncate64) # used for Win32 platform
|
AC_CHECK_FUNCS(ftruncate64) # used for Win32 platform
|
||||||
|
AC_CHECK_FUNCS(getattrlist)
|
||||||
AC_CHECK_FUNCS(getcwd)
|
AC_CHECK_FUNCS(getcwd)
|
||||||
AC_CHECK_FUNCS(getgidx)
|
AC_CHECK_FUNCS(getgidx)
|
||||||
AC_CHECK_FUNCS(getgrnam)
|
AC_CHECK_FUNCS(getgrnam)
|
||||||
|
|
63
dir.c
63
dir.c
|
@ -73,6 +73,16 @@ char *strchr(char*,char);
|
||||||
#define opendir(p) rb_w32_uopendir(p)
|
#define opendir(p) rb_w32_uopendir(p)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_ATTR_H
|
||||||
|
#include <sys/attr.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_GETATTRLIST
|
||||||
|
# define USE_NAME_ON_FS 1
|
||||||
|
#else
|
||||||
|
# define USE_NAME_ON_FS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
# define HAVE_HFS 1
|
# define HAVE_HFS 1
|
||||||
#else
|
#else
|
||||||
|
@ -1053,6 +1063,7 @@ sys_warning_1(VALUE mesg)
|
||||||
|
|
||||||
#define GLOB_ALLOC(type) ((type *)malloc(sizeof(type)))
|
#define GLOB_ALLOC(type) ((type *)malloc(sizeof(type)))
|
||||||
#define GLOB_ALLOC_N(type, n) ((type *)malloc(sizeof(type) * (n)))
|
#define GLOB_ALLOC_N(type, n) ((type *)malloc(sizeof(type) * (n)))
|
||||||
|
#define GLOB_REALLOC(ptr, size) realloc((ptr), (size))
|
||||||
#define GLOB_FREE(ptr) free(ptr)
|
#define GLOB_FREE(ptr) free(ptr)
|
||||||
#define GLOB_JUMP_TAG(status) (((status) == -1) ? rb_memerror() : rb_jump_tag(status))
|
#define GLOB_JUMP_TAG(status) (((status) == -1) ? rb_memerror() : rb_jump_tag(status))
|
||||||
|
|
||||||
|
@ -1241,8 +1252,7 @@ glob_make_pattern(const char *p, const char *e, int flags, rb_encoding *enc)
|
||||||
else {
|
else {
|
||||||
const char *m = find_dirsep(p, e, flags, enc);
|
const char *m = find_dirsep(p, e, flags, enc);
|
||||||
const enum glob_pattern_type magic = has_magic(p, m, flags, enc);
|
const enum glob_pattern_type magic = has_magic(p, m, flags, enc);
|
||||||
const enum glob_pattern_type non_magic =
|
const enum glob_pattern_type non_magic = (USE_NAME_ON_FS || FNM_SYSCASE) ? PLAIN : ALPHA;
|
||||||
((HAVE_HFS || FNM_SYSCASE) && (m == e || (m+1 == e && *m == '/'))) ? PLAIN : ALPHA;
|
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
if (!(FNM_SYSCASE || magic > non_magic) && !recursive && *m) {
|
if (!(FNM_SYSCASE || magic > non_magic) && !recursive && *m) {
|
||||||
|
@ -1316,6 +1326,45 @@ join_path(const char *path, long len, int dirsep, const char *name, size_t namle
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_GETATTRLIST
|
||||||
|
static char *
|
||||||
|
replace_real_basename(char *path, long base, int hfs_p)
|
||||||
|
{
|
||||||
|
u_int32_t attrbuf[(sizeof(attrreference_t) + MAXPATHLEN * 3 + sizeof(u_int32_t) - 1) / sizeof(u_int32_t) + 1];
|
||||||
|
struct attrlist al = {ATTR_BIT_MAP_COUNT, 0, ATTR_CMN_NAME};
|
||||||
|
const attrreference_t *ar = (void *)(attrbuf+1);
|
||||||
|
const char *name;
|
||||||
|
long len;
|
||||||
|
char *tmp;
|
||||||
|
IF_HAVE_HFS(VALUE utf8str = Qnil);
|
||||||
|
|
||||||
|
if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), FSOPT_NOFOLLOW))
|
||||||
|
return path;
|
||||||
|
|
||||||
|
name = (char *)ar + ar->attr_dataoffset;
|
||||||
|
len = (long)ar->attr_length - 1;
|
||||||
|
if (name + len > (char *)attrbuf + sizeof(attrbuf))
|
||||||
|
return path;
|
||||||
|
|
||||||
|
# if HAVE_HFS
|
||||||
|
if (hfs_p && has_nonascii(name, len)) {
|
||||||
|
if (!NIL_P(utf8str = rb_str_normalize_ospath(name, len))) {
|
||||||
|
RSTRING_GETMEM(utf8str, name, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
tmp = GLOB_REALLOC(path, base + len + 1);
|
||||||
|
if (tmp) {
|
||||||
|
path = tmp;
|
||||||
|
memcpy(path + base, name, len);
|
||||||
|
path[base + len] = '\0';
|
||||||
|
}
|
||||||
|
IF_HAVE_HFS(if (!NIL_P(utf8str)) rb_str_resize(utf8str, 0));
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
enum answer {UNKNOWN = -1, NO, YES};
|
enum answer {UNKNOWN = -1, NO, YES};
|
||||||
|
|
||||||
#ifndef S_ISDIR
|
#ifndef S_ISDIR
|
||||||
|
@ -1379,7 +1428,11 @@ glob_helper(
|
||||||
plain = 1;
|
plain = 1;
|
||||||
break;
|
break;
|
||||||
case ALPHA:
|
case ALPHA:
|
||||||
|
#ifdef HAVE_GETATTRLIST
|
||||||
|
plain = 1;
|
||||||
|
#else
|
||||||
magical = 1;
|
magical = 1;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case MAGICAL:
|
case MAGICAL:
|
||||||
magical = 2;
|
magical = 2;
|
||||||
|
@ -1602,6 +1655,12 @@ glob_helper(
|
||||||
status = -1;
|
status = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_GETATTRLIST
|
||||||
|
if ((*cur)->type == ALPHA) {
|
||||||
|
long base = pathlen + (dirsep != 0);
|
||||||
|
buf = replace_real_basename(buf, base, IF_HAVE_HFS(1)+0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
status = glob_helper(buf, 1, UNKNOWN, UNKNOWN, new_beg,
|
status = glob_helper(buf, 1, UNKNOWN, UNKNOWN, new_beg,
|
||||||
new_end, flags, func, arg, enc);
|
new_end, flags, func, arg, enc);
|
||||||
GLOB_FREE(buf);
|
GLOB_FREE(buf);
|
||||||
|
|
|
@ -237,16 +237,8 @@ class TestDir < Test::Unit::TestCase
|
||||||
return unless File.exist?("filewithcases")
|
return unless File.exist?("filewithcases")
|
||||||
assert_equal(%w"FileWithCases", Dir.glob("filewithcases"), feature5994)
|
assert_equal(%w"FileWithCases", Dir.glob("filewithcases"), feature5994)
|
||||||
end
|
end
|
||||||
Dir.chdir(File.join(@root, "c")) do
|
Dir.chdir(@root) do
|
||||||
open("FileWithCases", "w") {}
|
assert_equal(%w"a/FileWithCases", Dir.glob("A/filewithcases"), feature5994)
|
||||||
mode = File.stat(".").mode
|
|
||||||
begin
|
|
||||||
File.chmod(mode & ~0444, ".")
|
|
||||||
return if mode == File.stat(".").mode
|
|
||||||
assert_equal(%w"filewithcases", Dir.glob("filewithcases"), feature5994)
|
|
||||||
ensure
|
|
||||||
File.chmod(mode, ".")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue