32# if defined(HAVE_FDOPENDIR) && defined(HAVE_DIRFD) && \
33 defined(HAVE_OPENAT) && defined(HAVE_FSTATAT)
34# define USE_OPENDIR_AT 1
36# define USE_OPENDIR_AT 0
46#undef HAVE_DIRENT_NAMLEN
47#if defined HAVE_DIRENT_H && !defined _WIN32
49# define NAMLEN(dirent) strlen((dirent)->d_name)
50#elif defined HAVE_DIRECT_H && !defined _WIN32
52# define NAMLEN(dirent) strlen((dirent)->d_name)
55# define NAMLEN(dirent) (dirent)->d_namlen
56# define HAVE_DIRENT_NAMLEN 1
85#define vm_initialized rb_cThread
90#define chdir(p) rb_w32_uchdir(p)
92#define mkdir(p, m) rb_w32_umkdir((p), (m))
94#define rmdir(p) rb_w32_urmdir(p)
96#define opendir(p) rb_w32_uopendir(p)
97#define ruby_getcwd() rb_w32_ugetcwd(NULL, 0)
103#ifdef HAVE_SYS_ATTR_H
107#define USE_NAME_ON_FS_REAL_BASENAME 1
109#define USE_NAME_ON_FS_BY_FNMATCH 2
112#ifdef HAVE_GETATTRLIST
113# define USE_NAME_ON_FS USE_NAME_ON_FS_REAL_BASENAME
114# define RUP32(size) ((size)+3/4)
115# define SIZEUP32(type) RUP32(sizeof(type))
117# define USE_NAME_ON_FS USE_NAME_ON_FS_REAL_BASENAME
119# define USE_NAME_ON_FS USE_NAME_ON_FS_BY_FNMATCH
121# define USE_NAME_ON_FS 0
125# define NORMALIZE_UTF8PATH 1
127# define NORMALIZE_UTF8PATH 0
130#if NORMALIZE_UTF8PATH
131#include <sys/param.h>
132#include <sys/mount.h>
133#include <sys/vnode.h>
135# if defined HAVE_FGETATTRLIST || !defined HAVE_GETATTRLIST
136# define need_normalization(dirp, path) need_normalization(dirp)
138# define need_normalization(dirp, path) need_normalization(path)
141need_normalization(
DIR *dirp,
const char *
path)
143# if defined HAVE_FGETATTRLIST || defined HAVE_GETATTRLIST
144 u_int32_t attrbuf[SIZEUP32(fsobj_tag_t)];
145 struct attrlist al = {ATTR_BIT_MAP_COUNT, 0, ATTR_CMN_OBJTAG,};
146# if defined HAVE_FGETATTRLIST
147 int ret = fgetattrlist(dirfd(dirp), &al, attrbuf,
sizeof(attrbuf), 0);
149 int ret = getattrlist(
path, &al, attrbuf,
sizeof(attrbuf), 0);
152 const fsobj_tag_t *tag = (
void *)(attrbuf+1);
164has_nonascii(
const char *
ptr,
size_t len)
174# define IF_NORMALIZE_UTF8PATH(something) something
176# define IF_NORMALIZE_UTF8PATH(something)
180# define IFTODT(m) (((m) & S_IFMT) / ((~S_IFMT & (S_IFMT-1)) + 1))
199#define FNM_NOESCAPE 0x01
200#define FNM_PATHNAME 0x02
201#define FNM_DOTMATCH 0x04
202#define FNM_CASEFOLD 0x08
203#define FNM_EXTGLOB 0x10
204#if CASEFOLD_FILESYSTEM
205#define FNM_SYSCASE FNM_CASEFOLD
210#define FNM_SHORTNAME 0x20
212#define FNM_SHORTNAME 0
218# define Next(p, e, enc) ((p)+ rb_enc_mbclen((p), (e), (enc)))
219# define Inc(p, e, enc) ((p) = Next((p), (e), (enc)))
236 if (p >= pend)
return NULL;
237 if (*p ==
'!' || *p ==
'^') {
244 if (escape && *t1 ==
'\\')
249 if (p >= pend)
return NULL;
250 if (p[0] ==
'-' && p[1] !=
']') {
251 const char *t2 = p + 1;
253 if (escape && *t2 ==
'\\')
259 if ((r <= (send-s) &&
memcmp(t1, s, r) == 0) ||
268 if (c1 < c2)
continue;
271 if (c1 > c2)
continue;
275 if (r <= (send-s) &&
memcmp(t1, s, r) == 0) {
279 if (!nocase)
continue;
282 if (c1 != c2)
continue;
287 return ok == not ?
NULL : (
char *)p + 1;
295#define UNESCAPE(p) (escape && *(p) == '\\' ? (p) + 1 : (p))
296#define ISEND(p) (!*(p) || (pathname && *(p) == '/'))
297#define RETURN(val) return *pcur = p, *scur = s, (val);
311 const char *ptmp = 0;
312 const char *stmp = 0;
314 const char *p = *pcur;
315 const char *pend = p +
strlen(p);
316 const char *s = *scur;
317 const char *send = s +
strlen(s);
321 if (period && *s ==
'.' && *
UNESCAPE(p) !=
'.')
327 do { p++; }
while (*p ==
'*');
349 if ((t = bracket(p + 1, pend, s, send, flags, enc)) != 0) {
367 if (r <= (send-s) &&
memcmp(p, s, r) == 0) {
372 if (!nocase)
goto failed;
383 Inc(stmp, send, enc);
398 const char *p = pattern;
399 const char *s = string;
400 const char *send = s +
strlen(
string);
404 const char *ptmp = 0;
405 const char *stmp = 0;
409 if (p[0] ==
'*' && p[1] ==
'*' && p[2] ==
'/') {
410 do { p += 3; }
while (p[0] ==
'*' && p[1] ==
'*' && p[2] ==
'/');
414 if (fnmatch_helper(&p, &s, flags, enc) == 0) {
415 while (*s && *s !=
'/')
Inc(s, send, enc);
425 if (ptmp && stmp && !(period && *stmp ==
'.')) {
426 while (*stmp && *stmp !=
'/')
Inc(stmp, send, enc);
438 return fnmatch_helper(&p, &s, flags, enc);
466dir_memsize(
const void *
ptr)
473 {dir_mark, dir_free, dir_memsize,},
493nogvl_opendir(
void *
ptr)
501opendir_without_gvl(
const char *
path)
504 union {
const void *in;
void *out; } u;
529 VALUE dirname, opt, orig;
530 static ID keyword_ids[1];
533 if (!keyword_ids[0]) {
560 dp->dir = opendir_without_gvl(
path);
564 dp->dir = opendir_without_gvl(
path);
566#ifdef HAVE_GETATTRLIST
569 struct attrlist al = {ATTR_BIT_MAP_COUNT, 0};
570 if (getattrlist(
path, &al, attrbuf,
sizeof(attrbuf), FSOPT_NOFOLLOW) == 0) {
571 dp->dir = opendir_without_gvl(
path);
614NORETURN(
static void dir_closed(
void));
633 if (!dirp->
dir) dir_closed();
637#define GetDIR(obj, dirp) ((dirp) = dir_check(obj))
666#if defined(__sun) && !defined(HAVE_DIRFD)
667# if defined(HAVE_DIR_D_FD)
668# define dirfd(x) ((x)->d_fd)
670# elif defined(HAVE_DIR_DD_FD)
671# define dirfd(x) ((x)->dd_fd)
698 fd = dirfd(dirp->
dir);
704#define dir_fileno rb_f_notimplement
740# define READDIR(dir, enc) rb_w32_readdir((dir), (enc))
742# define READDIR(dir, enc) readdir((dir))
747to_be_skipped(
const struct dirent *
dp)
749 const char *
name =
dp->d_name;
751#ifdef HAVE_DIRENT_NAMLEN
830 return dir_each_entry(dir, dir_yield,
Qnil,
FALSE);
844 const char *
name =
dp->d_name;
848 if (children_only &&
name[0] ==
'.') {
849 if (namlen == 1)
continue;
850 if (namlen == 2 &&
name[1] ==
'.')
continue;
852#if NORMALIZE_UTF8PATH
853 if (norm_p && has_nonascii(
name, namlen) &&
889#define dir_tell rb_f_notimplement
918#define dir_seek rb_f_notimplement
942#define dir_set_pos rb_f_notimplement
990nogvl_chdir(
void *
ptr)
1004static int chdir_blocking = 0;
1019 if (chdir_thread ==
Qnil)
1030 if (chdir_blocking == 0)
1031 chdir_thread =
Qnil;
1085 const char *dist =
getenv(
"HOME");
1093 if (chdir_blocking > 0) {
1095 rb_warn(
"conflicting chdir during another chdir block");
1125#undef RUBY_UNTYPED_DATA_WARNING
1126#define RUBY_UNTYPED_DATA_WARNING 0
1154#if defined _WIN32 || defined __APPLE__
1175dir_s_getwd(
VALUE dir)
1181check_dirname(
VALUE dir)
1200#if defined(HAVE_CHROOT)
1220#define dir_s_chroot rb_f_notimplement
1229nogvl_mkdir(
void *
ptr)
1274nogvl_rmdir(
void *
ptr)
1296 dir = check_dirname(dir);
1306#ifdef RUBY_FUNCTION_NAME_STRING
1313#ifndef RUBY_FUNCTION_NAME_STRING
1314#define sys_enc_warning_in(func, mesg, enc) sys_enc_warning(mesg, enc)
1318sys_warning_1(
VALUE mesg)
1321#ifdef RUBY_FUNCTION_NAME_STRING
1333#ifdef RUBY_FUNCTION_NAME_STRING
1341#define GLOB_VERBOSE (1U << (sizeof(int) * CHAR_BIT - 1))
1342#define sys_warning(val, enc) \
1343 ((flags & GLOB_VERBOSE) ? sys_enc_warning_in(RUBY_FUNCTION_NAME_STRING, (val), (enc)) :(void)0)
1346glob_alloc_n(
size_t x,
size_t y)
1349 if (rb_mul_size_overflow(x, y,
SSIZE_MAX, &z)) {
1357#define GLOB_ALLOC(type) ((type *)malloc(sizeof(type)))
1358#define GLOB_ALLOC_N(type, n) ((type *)glob_alloc_n(sizeof(type), n))
1359#define GLOB_REALLOC(ptr, size) realloc((ptr), (size))
1360#define GLOB_FREE(ptr) free(ptr)
1361#define GLOB_JUMP_TAG(status) (((status) == -1) ? rb_memerror() : rb_jump_tag(status))
1375#define STAT(p, s) rb_w32_ustati128((p), (s))
1377#define lstat(p, s) rb_w32_ulstati128((p), (s))
1379#define STAT(p, s) stat((p), (s))
1389at_subpath(
int fd,
size_t baselen,
const char *
path)
1392 if (fd != (
int)
AT_FDCWD && baselen > 0) {
1402do_stat(
int fd,
size_t baselen,
const char *
path,
struct stat *pst,
int flags,
rb_encoding *enc)
1405 int ret =
fstatat(fd, at_subpath(fd, baselen,
path), pst, 0);
1409 if (ret < 0 && !to_be_ignored(
errno))
1415#if defined HAVE_LSTAT || defined lstat || USE_OPENDIR_AT
1420 int ret =
fstatat(fd, at_subpath(fd, baselen,
path), pst, AT_SYMLINK_NOFOLLOW);
1424 if (ret < 0 && !to_be_ignored(
errno))
1430#define do_lstat do_stat
1439with_gvl_gc_for_fd(
void *
ptr)
1447gc_for_fd_with_gvl(
int e)
1456nogvl_opendir_at(
void *
ptr)
1462 const int opendir_flags = (O_RDONLY|
O_CLOEXEC|
1467 int fd = openat(oaa->
basefd, oaa->
path, opendir_flags);
1469 dirp = fd >= 0 ? fdopendir(fd) : 0;
1473 switch (gc_for_fd_with_gvl(e)) {
1475 if (fd < 0) fd = openat(oaa->
basefd, oaa->
path, opendir_flags);
1476 if (fd >= 0) dirp = fdopendir(fd);
1477 if (dirp)
return dirp;
1482 if (fd >= 0)
close(fd);
1488 if (!dirp && gc_for_fd_with_gvl(
errno))
1506 return nogvl_opendir_at(&oaa);
1516 if (!fundamental_encoding_p(enc)) {
1527 if (!to_be_ignored(e)) {
1529 *status = (*errfunc)(
path,
arg, enc, e);
1548has_magic(
const char *p,
const char *pend,
int flags,
rb_encoding *enc)
1556 while (p < pend && (c = *p++) != 0) {
1568 if (escape && p++ >= pend)
1587 p =
Next(p-1, pend, enc);
1595find_dirsep(
const char *p,
const char *pend,
int flags,
rb_encoding *enc)
1602 while ((c = *p++) != 0) {
1624 if (escape && !(c = *p++))
1629 p =
Next(p-1, pend, enc);
1637remove_backslashes(
char *p,
register const char *pend,
rb_encoding *enc)
1670glob_make_pattern(
const char *p,
const char *e,
int flags,
rb_encoding *enc)
1676 while (p < e && *p) {
1678 if (!tmp)
goto error;
1679 if (p + 2 < e && p[0] ==
'*' && p[1] ==
'*' && p[2] ==
'/') {
1681 do { p += 3;
while (*p ==
'/') p++; }
while (p[0] ==
'*' && p[1] ==
'*' && p[2] ==
'/');
1688 const char *m = find_dirsep(p, e, flags, enc);
1693 if (!(
FNM_SYSCASE || magic > non_magic) && !recursive && *m) {
1695 while (has_magic(m+1, m2 = find_dirsep(m+1, e, flags, enc), flags, enc) <= non_magic &&
1726 glob_free_pattern(
list);
1750join_path(
const char *
path,
size_t len,
int dirsep,
const char *
name,
size_t namlen)
1764#ifdef HAVE_GETATTRLIST
1765# if defined HAVE_FGETATTRLIST
1766# define is_case_sensitive(dirp, path) is_case_sensitive(dirp)
1768# define is_case_sensitive(dirp, path) is_case_sensitive(path)
1771is_case_sensitive(
DIR *dirp,
const char *
path)
1775 vol_capabilities_attr_t cap[1];
1777 struct attrlist al = {ATTR_BIT_MAP_COUNT, 0, 0, ATTR_VOL_INFO|ATTR_VOL_CAPABILITIES};
1778 const vol_capabilities_attr_t *
const cap = attrbuf[0].cap;
1779 const int idx = VOL_CAPABILITIES_FORMAT;
1782# if defined HAVE_FGETATTRLIST
1783 if (fgetattrlist(dirfd(dirp), &al, attrbuf,
sizeof(attrbuf), FSOPT_NOFOLLOW))
1786 if (getattrlist(
path, &al, attrbuf,
sizeof(attrbuf), FSOPT_NOFOLLOW))
1789 if (!(cap->valid[idx] &
mask))
1791 return (cap->capabilities[idx] &
mask) != 0;
1799 attrreference_t ref[1];
1800 fsobj_type_t objtype;
1803 struct attrlist al = {ATTR_BIT_MAP_COUNT, 0, ATTR_CMN_NAME|ATTR_CMN_OBJTYPE};
1804 const attrreference_t *
const ar = attrbuf[0].ref;
1811 if (getattrlist(
path, &al, attrbuf,
sizeof(attrbuf), FSOPT_NOFOLLOW)) {
1812 if (!to_be_ignored(
errno))
1817 switch (attrbuf[0].objtype) {
1823 name = (
char *)ar + ar->attr_dataoffset;
1824 len = (
long)ar->attr_length - 1;
1825 if (
name +
len > (
char *)attrbuf +
sizeof(attrbuf))
1828# if NORMALIZE_UTF8PATH
1829 if (norm_p && has_nonascii(
name,
len)) {
1830 if (!
NIL_P(utf8str = rb_str_normalize_ospath(
name,
len))) {
1852 char *plainname =
path;
1853 volatile VALUE tmp = 0;
1854 WIN32_FIND_DATAW fd;
1855 WIN32_FILE_ATTRIBUTE_DATA fa;
1857 HANDLE
h = INVALID_HANDLE_VALUE;
1860 if (!fundamental_encoding_p(enc)) {
1867 if (!wplain)
return path;
1868 if (GetFileAttributesExW(wplain, GetFileExInfoStandard, &fa)) {
1869 h = FindFirstFileW(wplain, &fd);
1872 if (fa.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1874 fa.dwFileAttributes &= ~FILE_ATTRIBUTE_REPARSE_POINT;
1877 if (
h == INVALID_HANDLE_VALUE) {
1879 if (e && !to_be_ignored(e)) {
1887 (fa.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) ?
path_symlink :
1888 (fa.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ?
path_directory :
1898 path[base + wlen] = 0;
1904 wlen = WideCharToMultiByte(CP_UTF8, 0, fd.cFileName, -1,
NULL, 0,
NULL,
NULL);
1908 WideCharToMultiByte(CP_UTF8, 0, fd.cFileName, -1, utf8filename, wlen,
NULL,
NULL);
1913 path[base + wlen] = 0;
1920#elif USE_NAME_ON_FS == USE_NAME_ON_FS_REAL_BASENAME
1921# error not implemented
1925# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
1930# define S_ISLNK(m) (0)
1932# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
1945#define glob_call_func(func, path, arg, enc) (*(func))((path), (arg), (void *)(enc))
1948glob_func_caller(
VALUE val)
1963glob_func_warning(
VALUE val)
1986glob_func_error(
VALUE val)
2002 errfunc = glob_func_warning;
2014 if (fnmatch(pat,
enc,
name, flags) == 0)
return 1;
2017 if (fnmatch(pat,
enc,
dp->d_altname, flags) == 0)
return 1;
2042dirent_match_brace(
const char *pattern,
VALUE val,
void *enc)
2046 return dirent_match(pattern, enc,
arg->name,
arg->dp,
arg->flags);
2055 size_t path_len = 0;
2057 for (p = *beg; p; p = p->
next) {
2076 path[path_len] =
'\0';
2085 path[path_len++] =
'/';
2088 path[path_len] =
'\0';
2095static int push_caller(
const char *
path,
VALUE val,
void *enc);
2118 int plain = 0, brace = 0, magical = 0, recursive = 0, match_all = 0, match_dir = 0;
2120 size_t pathlen = baselen + namelen;
2122 for (cur = beg; cur < end; ++cur) {
2133#if USE_NAME_ON_FS == USE_NAME_ON_FS_REAL_BASENAME
2154 rb_bug(
"continuous RECURSIVEs");
2160 char* brace_path = join_path_from_pattern(beg);
2161 if (!brace_path)
return -1;
2171 status = ruby_brace_expand(brace_path,
flags, push_caller, (
VALUE)&args, enc,
Qfalse);
2196 if (status)
return status;
2201 char *tmp = join_path(subpath,
namelen - seplen,
dirsep,
"", 0);
2202 if (!tmp)
return -1;
2205 if (status)
return status;
2211 if (magical || recursive) {
2214# if USE_NAME_ON_FS == USE_NAME_ON_FS_BY_FNMATCH
2215 char *plainname = 0;
2218# if USE_NAME_ON_FS == USE_NAME_ON_FS_BY_FNMATCH
2219 if (cur + 1 == end && (*cur)->type <=
ALPHA) {
2220 plainname = join_path(
path, pathlen, dirsep, (*cur)->str,
strlen((*cur)->str));
2221 if (!plainname)
return -1;
2222 dirp = do_opendir(fd,
basename, plainname, flags, enc, funcs->
error,
arg, &status);
2229 dirp = do_opendir(fd, baselen,
path, flags, enc, funcs->
error,
arg, &status);
2231# if FNM_SYSCASE || NORMALIZE_UTF8PATH
2232 if ((magical < 2) && !recursive && (
errno ==
EACCES)) {
2241# if NORMALIZE_UTF8PATH
2242 if (!(norm_p || magical || recursive)) {
2247# ifdef HAVE_GETATTRLIST
2248 if (is_case_sensitive(dirp,
path) == 0)
2261 if (recursive &&
name[0] ==
'.') {
2269 else if (namlen == 2 &&
name[1] ==
'.') {
2275# if NORMALIZE_UTF8PATH
2276 if (norm_p && has_nonascii(
name, namlen)) {
2277 if (!
NIL_P(utf8str = rb_str_normalize_ospath(
name, namlen))) {
2282 buf = join_path(
path, pathlen, dirsep,
name, namlen);
2288 name =
buf + pathlen + (dirsep != 0);
2292 new_pathtype =
dp->d_type;
2295 if (recursive && dotfile < ((flags &
FNM_DOTMATCH) ? 2 : 1) &&
2311 for (cur = beg; cur < end; ++cur) {
2327 if (ruby_brace_expand(p->
str,
flags, dirent_match_brace,
2329 *new_end++ = p->
next;
2332# if USE_NAME_ON_FS == USE_NAME_ON_FS_BY_FNMATCH
2334 *new_end++ = p->
next;
2341 *new_end++ = p->
next;
2347 status = glob_helper(fd,
buf, baselen,
name -
buf - baselen + namlen, 1,
2348 new_pathtype, new_beg, new_end,
2360# if FNM_SYSCASE || NORMALIZE_UTF8PATH
2364 if (!copy_beg)
return -1;
2365 for (cur = beg; cur < end; ++cur)
2366 *copy_end++ = (*cur)->type <=
ALPHA ? *cur : 0;
2368 for (cur = copy_beg; cur < copy_end; ++cur) {
2389 *new_end++ = (*cur)->
next;
2390 for (cur2 = cur + 1; cur2 < copy_end; ++cur2) {
2391 if (*cur2 && fnmatch((*cur2)->str, enc,
name, flags) == 0) {
2392 *new_end++ = (*cur2)->
next;
2404#if USE_NAME_ON_FS == USE_NAME_ON_FS_REAL_BASENAME
2405 if ((*cur)->type ==
ALPHA) {
2406 buf = replace_real_basename(
buf, pathlen + (dirsep != 0), enc,
2408 flags, &new_pathtype);
2412 status = glob_helper(fd,
buf, baselen,
2414 new_pathtype, new_beg, new_end,
2415 flags, funcs,
arg, enc);
2429push_caller(
const char *
path,
VALUE val,
void *enc)
2439 status = glob_helper(
arg->fd,
arg->path,
arg->baselen,
arg->namelen,
arg->dirsep,
2442 glob_free_pattern(
list);
2446static int ruby_glob0(
const char *
path,
int fd,
const char *base,
int flags,
2458push_glob0_caller(
const char *
path,
VALUE val,
void *enc)
2470 const char *root, *start;
2472 size_t n, baselen = 0;
2473 int status, dirsep =
FALSE;
2475 start = root =
path;
2492 if (*root ==
'/') root++;
2502 if (!
buf)
return -1;
2511 status = glob_helper(
fd,
buf, baselen,
n-baselen, dirsep,
2514 glob_free_pattern(
list);
2531rb_glob_caller(
const char *
path,
VALUE a,
void *enc)
2542 rb_glob_caller, rb_glob_error,
2563#if defined _WIN32 || defined __APPLE__
2578 const char *p =
str;
2579 const char *pend = p +
strlen(p);
2581 const char *lbrace = 0, *rbrace = 0;
2582 int nest = 0, status = 0;
2585 if (*p ==
'{' && nest++ == 0) {
2588 if (*p ==
'}' && lbrace && --nest == 0) {
2592 if (*p ==
'\\' && escape) {
2598 if (lbrace && rbrace) {
2603 if (!
buf)
return -1;
2607 while (p < rbrace) {
2608 const char *t = ++p;
2610 while (p < rbrace && !(*p ==
',' && nest == 0)) {
2611 if (*p ==
'{') nest++;
2612 if (*p ==
'}') nest--;
2613 if (*p ==
'\\' && escape) {
2614 if (++p == rbrace)
break;
2620 status = ruby_brace_expand(
buf, flags,
func,
arg,
enc, var);
2625 else if (!lbrace && !rbrace) {
2640glob_brace(
const char *
path,
VALUE val,
void *enc)
2652 flags &= ~GLOB_VERBOSE;
2673#if defined _WIN32 || defined __APPLE__
2681 args.func = push_pattern;
2689 if (!dirp->
dir) dir_closed();
2691 if ((fd = dirfd(dirp->
dir)) == -1)
2698#if defined _WIN32 || defined __APPLE__
2702 return ruby_glob0(
RSTRING_PTR(
str), fd, args.base, flags, &rb_glob_funcs,
2724 status = push_glob(ary,
str, base, flags);
2740 status = push_glob(ary,
str, base, flags);
2748dir_glob_options(
VALUE opt,
VALUE *base,
int *flags)
2768 if (flags && args[1] !=
Qundef) {
2786 dir_glob_options(opts, &base,
NULL);
2788 return rb_push_glob(
argv[0], base, 0);
2790 return dir_globs(
argc,
argv, base, 0);
2884 VALUE str, rflags, ary, opts, base;
2892 dir_glob_options(opts, &base, &flags);
2896 ary = rb_push_glob(
str, base, flags);
2989 return dir_each_entry(
dir, dir_yield,
Qnil,
TRUE);
3048 return dir_each_entry(
dir, dir_yield,
Qnil,
TRUE);
3095fnmatch_brace(
const char *pattern,
VALUE val,
void *
enc)
3102 if (enc_pattern != enc_path) {
3111 enc_pattern, &cr) !=
len)
3301 rb_warning(
"Dir.exists? is a deprecated name, use Dir.exist? instead");
3306nogvl_dir_empty_p(
void *
ptr)
3315 switch (gc_for_fd_with_gvl(e)) {
3328 if (!to_be_skipped(
dp)) {
3334 return (
void *)result;
3349 enum {false_on_notdir = 1};
3357#if defined HAVE_GETATTRLIST && defined ATTR_DIR_ENTRYCOUNT
3359 u_int32_t attrbuf[SIZEUP32(fsobj_tag_t)];
3360 struct attrlist al = {ATTR_BIT_MAP_COUNT, 0, ATTR_CMN_OBJTAG,};
3361 if (getattrlist(
path, &al, attrbuf,
sizeof(attrbuf), 0) != 0)
3363 if (*(
const fsobj_tag_t *)(attrbuf+1) == VT_HFS) {
3365 al.dirattr = ATTR_DIR_ENTRYCOUNT;
3366 if (getattrlist(
path, &al, attrbuf,
sizeof(attrbuf), 0) == 0) {
3367 if (attrbuf[0] >= 2 *
sizeof(
u_int32_t))
3369 if (false_on_notdir)
return Qfalse;
NORETURN(static void dir_closed(void))
VALUE rb_dir_getwd_ospath(void)
char * strchr(char *, char)
#define READDIR(dir, enc)
#define GLOB_JUMP_TAG(status)
#define sys_enc_warning_in(func, mesg, enc)
#define glob_call_func(func, path, arg, enc)
#define GLOB_ALLOC_N(type, n)
ALWAYS_INLINE(static int to_be_ignored(int e))
int ruby_brace_glob_with_enc(const char *str, int flags, ruby_glob_func *func, VALUE arg, rb_encoding *enc)
#define IF_NORMALIZE_UTF8PATH(something)
int ruby_glob_errfunc(const char *, VALUE, const void *, int)
#define GLOB_REALLOC(ptr, size)
#define sys_warning(val, enc)
#define GetDIR(obj, dirp)
#define ENCINDEX_US_ASCII
struct rb_encoding_entry * list
int rb_enc_precise_mbclen(const char *p, const char *e, rb_encoding *enc)
rb_encoding * rb_utf8_encoding(void)
rb_encoding * rb_ascii8bit_encoding(void)
rb_encoding * rb_filesystem_encoding(void)
rb_encoding * rb_default_internal_encoding(void)
rb_encoding * rb_enc_get(VALUE obj)
int rb_enc_to_index(rb_encoding *enc)
rb_encoding * rb_enc_check(VALUE str1, VALUE str2)
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc)
rb_encoding * rb_enc_compatible(VALUE str1, VALUE str2)
rb_encoding * rb_to_encoding(VALUE enc)
int rb_enc_toupper(int c, rb_encoding *enc)
rb_encoding * rb_usascii_encoding(void)
VALUE rb_enc_from_encoding(rb_encoding *encoding)
VALUE rb_enc_associate_index(VALUE obj, int idx)
#define ENC_CODERANGE_7BIT
VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to)
VALUE rb_enc_str_new_cstr(const char *, rb_encoding *)
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
#define rb_enc_asciicompat(enc)
#define rb_enc_codepoint(p, e, enc)
int rb_enc_str_asciionly_p(VALUE)
long rb_str_coderange_scan_restartable(const char *, const char *, rb_encoding *, int *)
#define MBCLEN_CHARFOUND_P(ret)
VALUE rb_external_str_new_with_enc(const char *ptr, long len, rb_encoding *)
char str[HTML_ESCAPE_MAX_LEN+1]
char * rb_enc_path_end(const char *path, const char *end, rb_encoding *enc)
char * rb_enc_path_skip_prefix(const char *path, const char *end, rb_encoding *enc)
void rb_include_module(VALUE, VALUE)
VALUE rb_define_class(const char *, VALUE)
Defines a top-level class.
int rb_block_given_p(void)
Determines if the current method is given a block.
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *)
void rb_glob(const char *path, void(*func)(const char *, VALUE, void *), VALUE arg)
VALUE rb_cObject
Object class.
int ruby_brace_glob(const char *str, int flags, ruby_glob_func *func, VALUE arg)
int ruby_glob(const char *path, int flags, ruby_glob_func *func, VALUE arg)
void rb_syserr_fail(int e, const char *mesg)
void rb_raise(VALUE exc, const char *fmt,...)
void rb_sys_enc_warning(rb_encoding *enc, const char *fmt,...)
int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
void rb_bug(const char *fmt,...)
void rb_syserr_enc_warning(int err, rb_encoding *enc, const char *fmt,...)
void rb_syserr_fail_str(int e, VALUE mesg)
VALUE rb_protect(VALUE(*)(VALUE), VALUE, int *)
Protects a function call from potential global escapes from the function.
void * rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
void rb_warn(const char *fmt,...)
VALUE rb_ensure(VALUE(*)(VALUE), VALUE, VALUE(*)(VALUE), VALUE)
An equivalent to ensure clause.
void rb_sys_fail(const char *mesg)
VALUE type(ANYARGS)
ANYARGS-ed function type.
VALUE rb_external_str_with_enc(VALUE str, rb_encoding *eenc)
void(* func)(const char *, VALUE, void *)
struct glob_pattern * next
enum glob_pattern_type type
const ruby_glob_funcs_t * funcs
const ruby_glob_funcs_t * funcs
ruby_glob_errfunc * error
RUBY_SYMBOL_EXPORT_BEGIN void * rb_thread_call_with_gvl(void *(*func)(void *), void *data1)
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc)
int rb_w32_reparse_symlink_p(const WCHAR *path)
int rb_w32_map_errno(DWORD)
WCHAR * rb_w32_mbstr_to_wstr(UINT, const char *, int, long *)