Ruby
2.7.1p83(2020-03-31revisiona0c7c23c9cec0d0ffcba012279cd652d28ad5bf3)
|
Go to the documentation of this file.
19 #include <sys/cygwin.h>
23 # if !(defined(__has_feature) && defined(__has_attribute))
28 # define API_AVAILABLE(...)
29 # define API_DEPRECATED(...)
31 #include <CoreFoundation/CFString.h>
46 #ifdef HAVE_SYS_TIME_H
47 # include <sys/time.h>
50 #ifdef HAVE_SYS_FILE_H
51 # include <sys/file.h>
56 #ifdef HAVE_SYS_PARAM_H
57 # include <sys/param.h>
60 # define MAXPATHLEN 1024
69 #elif defined HAVE_SYS_UTIME_H
70 #include <sys/utime.h>
77 #ifdef HAVE_SYS_SYSMACROS_H
78 #include <sys/sysmacros.h>
81 #include <sys/types.h>
84 #ifdef HAVE_SYS_MKDEV_H
85 #include <sys/mkdev.h>
88 #if defined(HAVE_FCNTL_H)
92 #if defined(HAVE_SYS_TIME_H)
96 #if !defined HAVE_LSTAT && !defined lstat
103 #define STAT(p, s) rb_w32_ustati128((p), (s))
105 #define lstat(p, s) rb_w32_ulstati128((p), (s))
107 #define access(p, m) rb_w32_uaccess((p), (m))
109 #define truncate(p, n) rb_w32_utruncate((p), (n))
111 #define chmod(p, m) rb_w32_uchmod((p), (m))
113 #define chown(p, o, g) rb_w32_uchown((p), (o), (g))
115 #define lchown(p, o, g) rb_w32_ulchown((p), (o), (g))
117 #define utimensat(s, p, t, f) rb_w32_uutimensat((s), (p), (t), (f))
119 #define link(f, t) rb_w32_ulink((f), (t))
121 #define unlink(p) rb_w32_uunlink(p)
123 #define rename(f, t) rb_w32_urename((f), (t))
125 #define symlink(s, l) rb_w32_usymlink((s), (l))
133 #define STAT(p, s) stat((p), (s))
136 #if defined _WIN32 || defined __APPLE__
137 # define USE_OSPATH 1
138 # define TO_OSPATH(str) rb_str_encode_ospath(str)
140 # define USE_OSPATH 0
141 # define TO_OSPATH(str) (str)
145 #if defined DOSISH || defined __CYGWIN__
146 # define UTIME_EINVAL
150 #if defined HAVE_REALPATH && defined __sun && defined __SVR4
213 obj = file_path_convert(
obj);
215 check_path_encoding(
obj);
240 #if 0 && defined _WIN32
255 # define NORMALIZE_UTF8PATH 1
257 rb_str_append_normalized_ospath(
VALUE str,
const char *
ptr,
long len)
261 CFStringRef s = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault,
263 kCFStringEncodingUTF8,
FALSE,
265 CFMutableStringRef m = CFStringCreateMutableCopy(kCFAllocatorDefault,
len, s);
268 CFStringNormalize(m, kCFStringNormalizationFormC);
269 all = CFRangeMake(0, CFStringGetLength(m));
270 CFStringGetBytes(m, all, kCFStringEncodingUTF8,
'?',
FALSE,
NULL, 0, &buflen);
272 CFStringGetBytes(m, all, kCFStringEncodingUTF8,
'?',
FALSE,
281 rb_str_normalize_ospath(
const char *
ptr,
long len)
284 const char *e =
ptr +
len;
295 static const char invalid[3] =
"\xEF\xBF\xBD";
296 rb_str_append_normalized_ospath(
str, p1, p-p1);
304 if ((0x2000 <= c && c <= 0x2FFF) || (0xF900 <= c && c <= 0xFAFF) ||
305 (0x2F800 <= c && c <= 0x2FAFF)) {
307 rb_str_append_normalized_ospath(
str, p1, p-p1);
318 rb_str_append_normalized_ospath(
str, p1, p-p1);
328 if (p+3 > e)
return 0;
329 switch ((
unsigned char)*p) {
331 switch ((
unsigned char)p[1]) {
333 c = (
unsigned char)p[2];
335 if (c >= 0x8c && c <= 0x8f)
return 3;
337 if (c >= 0xaa && c <= 0xae)
return 3;
340 c = (
unsigned char)p[2];
342 if (c >= 0xaa && c <= 0xaf)
return 3;
348 if ((
unsigned char)p[1] == 0xbb &&
349 (
unsigned char)p[2] == 0xbf)
356 # define NORMALIZE_UTF8PATH 0
359 #define apply2args(n) (rb_check_arity(argc, n, UNLIMITED_ARGUMENTS), argc-=n)
376 no_gvl_apply2files(
void *
ptr)
380 for (aa->
i = 0; aa->
i < aa->
argc; aa->
i++) {
391 static int utime_internal(
const char *,
void *);
407 for (aa->
i = 0; aa->
i <
argc; aa->
i++) {
418 if (
func == utime_internal) {
466 stat_memsize(
const void *p)
468 return sizeof(
struct stat);
480 struct stat *nst = 0;
527 struct timespec ts1 = stat_mtimespec(get_stat(
self));
528 struct timespec ts2 = stat_mtimespec(get_stat(other));
540 #define ST2UINT(val) ((val) & ~(~1UL << (sizeof(val) * CHAR_BIT - 1)))
543 # define NUM2DEVT(v) NUM2UINT(v)
546 # define DEVT2NUM(v) UINT2NUM(v)
548 #ifndef PRI_DEVT_PREFIX
549 # define PRI_DEVT_PREFIX ""
563 rb_stat_dev(
VALUE self)
565 return DEVT2NUM(get_stat(
self)->st_dev);
580 rb_stat_dev_major(
VALUE self)
601 rb_stat_dev_minor(
VALUE self)
621 rb_stat_ino(
VALUE self)
623 #ifdef HAVE_STRUCT_STAT_ST_INOHIGH
629 #elif SIZEOF_STRUCT_STAT_ST_INO > SIZEOF_LONG
630 return ULL2NUM(get_stat(
self)->st_ino);
632 return ULONG2NUM(get_stat(
self)->st_ino);
650 rb_stat_mode(
VALUE self)
668 rb_stat_nlink(
VALUE self)
670 return UINT2NUM(get_stat(
self)->st_nlink);
684 rb_stat_uid(
VALUE self)
686 return UIDT2NUM(get_stat(
self)->st_uid);
700 rb_stat_gid(
VALUE self)
702 return GIDT2NUM(get_stat(
self)->st_gid);
718 rb_stat_rdev(
VALUE self)
720 #ifdef HAVE_STRUCT_STAT_ST_RDEV
721 return DEVT2NUM(get_stat(
self)->st_rdev);
739 rb_stat_rdev_major(
VALUE self)
741 #if defined(HAVE_STRUCT_STAT_ST_RDEV) && defined(major)
760 rb_stat_rdev_minor(
VALUE self)
762 #if defined(HAVE_STRUCT_STAT_ST_RDEV) && defined(minor)
779 rb_stat_size(
VALUE self)
781 return OFFT2NUM(get_stat(
self)->st_size);
796 rb_stat_blksize(
VALUE self)
798 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
799 return ULONG2NUM(get_stat(
self)->st_blksize);
817 rb_stat_blocks(
VALUE self)
819 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
820 # if SIZEOF_STRUCT_STAT_ST_BLOCKS > SIZEOF_LONG
821 return ULL2NUM(get_stat(
self)->st_blocks);
823 return ULONG2NUM(get_stat(
self)->st_blocks);
835 #if defined(HAVE_STRUCT_STAT_ST_ATIM)
836 ts.tv_nsec =
st->st_atim.tv_nsec;
837 #elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC)
838 ts.tv_nsec =
st->st_atimespec.tv_nsec;
839 #elif defined(HAVE_STRUCT_STAT_ST_ATIMENSEC)
840 ts.tv_nsec = (
long)
st->st_atimensec;
848 stat_atime(
const struct stat *
st)
859 #if defined(HAVE_STRUCT_STAT_ST_MTIM)
860 ts.tv_nsec =
st->st_mtim.tv_nsec;
861 #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
862 ts.tv_nsec =
st->st_mtimespec.tv_nsec;
863 #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
864 ts.tv_nsec = (
long)
st->st_mtimensec;
872 stat_mtime(
const struct stat *
st)
883 #if defined(HAVE_STRUCT_STAT_ST_CTIM)
884 ts.tv_nsec =
st->st_ctim.tv_nsec;
885 #elif defined(HAVE_STRUCT_STAT_ST_CTIMESPEC)
886 ts.tv_nsec =
st->st_ctimespec.tv_nsec;
887 #elif defined(HAVE_STRUCT_STAT_ST_CTIMENSEC)
888 ts.tv_nsec = (
long)
st->st_ctimensec;
896 stat_ctime(
const struct stat *
st)
902 #define HAVE_STAT_BIRTHTIME
903 #if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC)
904 typedef struct stat statx_data;
906 stat_birthtime(
const struct stat *
st)
908 const struct timespec *ts = &
st->st_birthtimespec;
911 #elif defined(_WIN32)
912 typedef struct stat statx_data;
913 # define stat_birthtime stat_ctime
915 # undef HAVE_STAT_BIRTHTIME
930 rb_stat_atime(
VALUE self)
932 return stat_atime(get_stat(
self));
946 rb_stat_mtime(
VALUE self)
948 return stat_mtime(get_stat(
self));
966 rb_stat_ctime(
VALUE self)
968 return stat_ctime(get_stat(
self));
971 #if defined(HAVE_STAT_BIRTHTIME)
997 return stat_birthtime(get_stat(
self));
1000 # define rb_stat_birthtime rb_f_notimplement
1019 rb_stat_inspect(
VALUE self)
1023 static const struct {
1027 {
"dev", rb_stat_dev},
1028 {
"ino", rb_stat_ino},
1029 {
"mode", rb_stat_mode},
1030 {
"nlink", rb_stat_nlink},
1031 {
"uid", rb_stat_uid},
1032 {
"gid", rb_stat_gid},
1033 {
"rdev", rb_stat_rdev},
1034 {
"size", rb_stat_size},
1035 {
"blksize", rb_stat_blksize},
1036 {
"blocks", rb_stat_blocks},
1037 {
"atime", rb_stat_atime},
1038 {
"mtime", rb_stat_mtime},
1039 {
"ctime", rb_stat_ctime},
1040 #if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC)
1055 for (
i = 0;
i <
sizeof(member)/
sizeof(member[0]);
i++) {
1063 v = (*member[
i].func)(
self);
1067 else if (
i == 0 ||
i == 6) {
1088 no_gvl_fstat(
void *data)
1095 fstat_without_gvl(
int fd,
struct stat *
st)
1106 no_gvl_stat(
void * data)
1113 stat_without_gvl(
const char *
path,
struct stat *
st)
1124 #if !defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC) && \
1125 defined(HAVE_STRUCT_STATX_STX_BTIME)
1128 # ifdef HAVE_SYSCALL_H
1129 # include <syscall.h>
1130 # elif defined HAVE_SYS_SYSCALL_H
1131 # include <sys/syscall.h>
1133 # if defined __linux__
1134 # include <linux/stat.h>
1136 statx(
int dirfd,
const char *pathname,
int flags,
1137 unsigned int mask,
struct statx *statxbuf)
1139 return (
int)syscall(__NR_statx, dirfd, pathname, flags,
mask, statxbuf);
1144 typedef struct no_gvl_statx_data {
1150 } no_gvl_statx_data;
1153 io_blocking_statx(
void *data)
1155 no_gvl_statx_data *
arg = data;
1160 no_gvl_statx(
void *data)
1162 return (
void *)io_blocking_statx(data);
1166 statx_without_gvl(
const char *
path,
struct statx *stx,
unsigned int mask)
1176 fstatx_without_gvl(
int fd,
struct statx *stx,
unsigned int mask)
1178 no_gvl_statx_data data = {stx, fd,
"", AT_EMPTY_PATH,
mask};
1185 rb_statx(
VALUE file,
struct statx *stx,
unsigned int mask)
1194 result = fstatx_without_gvl(fptr->
fd, stx,
mask);
1206 # define statx_has_birthtime(st) ((st)->stx_mask & STATX_BTIME)
1208 NORETURN(
static void statx_notimplement(
const char *field_name));
1213 statx_notimplement(
const char *field_name)
1216 "%s is unimplemented on this filesystem",
1221 statx_birthtime(
const struct statx *stx,
VALUE fname)
1225 statx_notimplement(
"birthtime");
1230 typedef struct statx statx_data;
1231 # define HAVE_STAT_BIRTHTIME
1233 #elif defined(HAVE_STAT_BIRTHTIME)
1234 # define statx_without_gvl(path, st, mask) stat_without_gvl(path, st)
1235 # define fstatx_without_gvl(fd, st, mask) fstat_without_gvl(fd, st)
1236 # define statx_birthtime(st, fname) stat_birthtime(st)
1237 # define statx_has_birthtime(st) 1
1238 # define rb_statx(file, st, mask) rb_stat(file, st)
1240 # define statx_has_birthtime(st) 0
1254 result = fstat_without_gvl(fptr->
fd,
st);
1319 no_gvl_lstat(
void *
ptr)
1326 lstat_without_gvl(
const char *
path,
struct stat *
st)
1365 return rb_file_s_stat(
klass, fname);
1399 return rb_io_stat(
obj);
1406 #if defined(_WIN32) || !defined(HAVE_GETGROUPS)
1426 if (anum != -1 && anum != groups)
1437 while (--anum >= 0) {
1438 if (gary[anum] == gid) {
1451 # define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
1454 #if defined(S_IXGRP) && !defined(_WIN32) && !defined(__CYGWIN__)
1455 #define USE_GETEUID 1
1458 #ifndef HAVE_EACCESS
1488 if (
st.st_uid == euid)
1490 else if (rb_group_member(
st.st_gid))
1493 if ((
int)(
st.st_mode & mode) == mode)
return 0;
1508 nogvl_eaccess(
void *
ptr)
1530 nogvl_access(
void *
ptr)
1580 # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
1585 if (rb_stat(fname, &
st) < 0)
return Qfalse;
1604 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
1609 if (rb_stat(fname, &
st) < 0)
return Qfalse;
1628 # define S_ISLNK(m) _S_ISLNK(m)
1631 # define S_ISLNK(m) (((m) & S_IFMT) == _S_IFLNK)
1634 # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
1666 # define S_ISSOCK(m) _S_ISSOCK(m)
1669 # define S_ISSOCK(m) (((m) & S_IFMT) == _S_IFSOCK)
1672 # define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
1681 if (rb_stat(fname, &
st) < 0)
return Qfalse;
1702 # define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
1704 # define S_ISBLK(m) (0)
1711 if (rb_stat(fname, &
st) < 0)
return Qfalse;
1730 # define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
1735 if (rb_stat(fname, &
st) < 0)
return Qfalse;
1757 if (rb_stat(fname, &
st) < 0)
return Qfalse;
1770 const char *s =
"FileTest#";
1779 rb_warning(
"%sexists? is a deprecated name, use %sexist? instead", s, s);
1780 return rb_file_exist_p(
obj, fname);
1797 if (rb_eaccess(fname,
R_OK) < 0)
return Qfalse;
1815 if (rb_access(fname,
R_OK) < 0)
return Qfalse;
1820 # define S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH)
1824 # define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH)
1849 if (rb_stat(fname, &
st) < 0)
return Qnil;
1871 if (rb_eaccess(fname,
W_OK) < 0)
return Qfalse;
1889 if (rb_access(fname,
W_OK) < 0)
return Qfalse;
1915 if (rb_stat(fname, &
st) < 0)
return Qnil;
1941 if (rb_eaccess(fname,
X_OK) < 0)
return Qfalse;
1963 if (rb_access(fname,
X_OK) < 0)
return Qfalse;
1968 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
1988 if (rb_stat(fname, &
st) < 0)
return Qfalse;
2008 if (rb_stat(fname, &
st) < 0)
return Qfalse;
2009 if (
st.st_size == 0)
return Qtrue;
2028 if (rb_stat(fname, &
st) < 0)
return Qnil;
2029 if (
st.st_size == 0)
return Qnil;
2049 if (rb_stat(fname, &
st) < 0)
return Qfalse;
2059 if (rb_stat(fname, &
st) < 0)
return Qfalse;
2081 if (rb_stat(fname, &
st) < 0)
return Qfalse;
2082 if (rb_group_member(
st.st_gid))
return Qtrue;
2087 #if defined(S_ISUID) || defined(S_ISGID) || defined(S_ISVTX)
2089 check3rdbyte(
VALUE fname,
int mode)
2093 if (rb_stat(fname, &
st) < 0)
return Qfalse;
2094 if (
st.st_mode & mode)
return Qtrue;
2112 return check3rdbyte(fname,
S_ISUID);
2131 return check3rdbyte(fname,
S_ISGID);
2150 return check3rdbyte(fname,
S_ISVTX);
2179 struct stat st1, st2;
2181 if (rb_stat(fname1, &st1) < 0)
return Qfalse;
2182 if (rb_stat(fname2, &st2) < 0)
return Qfalse;
2183 if (st1.st_dev != st2.st_dev)
return Qfalse;
2184 if (st1.st_ino != st2.st_ino)
return Qfalse;
2206 if (rb_stat(fname, &
st) < 0) {
2215 rb_file_ftype(
const struct stat *
st)
2226 t =
"characterSpecial";
2281 return rb_file_ftype(&
st);
2301 if (rb_stat(fname, &
st) < 0) {
2306 return stat_atime(&
st);
2330 return stat_atime(&
st);
2350 if (rb_stat(fname, &
st) < 0) {
2355 return stat_mtime(&
st);
2378 return stat_mtime(&
st);
2402 if (rb_stat(fname, &
st) < 0) {
2407 return stat_ctime(&
st);
2433 return stat_ctime(&
st);
2450 #if defined(HAVE_STAT_BIRTHTIME)
2456 if (rb_statx(fname, &
st, STATX_BTIME) < 0) {
2461 return statx_birthtime(&
st, fname);
2464 # define rb_file_s_birthtime rb_f_notimplement
2467 #if defined(HAVE_STAT_BIRTHTIME)
2487 if (fstatx_without_gvl(fptr->
fd, &
st, STATX_BTIME) == -1) {
2490 return statx_birthtime(&
st, fptr->
pathv);
2493 # define rb_file_birthtime rb_f_notimplement
2523 chmod_internal(
const char *
path,
void *mode)
2549 return apply2files(chmod_internal,
argc,
argv, &mode);
2570 #if !defined HAVE_FCHMOD || !HAVE_FCHMOD
2578 if (
fchmod(fptr->
fd, mode) == -1) {
2586 #if !defined HAVE_FCHMOD || !HAVE_FCHMOD
2596 #if defined(HAVE_LCHMOD)
2598 lchmod_internal(
const char *
path,
void *mode)
2621 return apply2files(lchmod_internal,
argc,
argv, &mode);
2624 #define rb_file_s_lchmod rb_f_notimplement
2651 chown_internal(
const char *
path,
void *
arg)
2681 return apply2files(chown_internal,
argc,
argv, &
arg);
2725 #if defined(HAVE_LCHOWN)
2727 lchown_internal(
const char *
path,
void *
arg)
2753 return apply2files(lchown_internal,
argc,
argv, &
arg);
2756 #define rb_file_s_lchown rb_f_notimplement
2787 if (
NIL_P(a)) e[0] = m;
2807 #if defined(HAVE_UTIMES)
2810 utime_internal(
const char *
path,
void *
arg)
2816 #if defined(HAVE_UTIMENSAT)
2817 static int try_utimensat = 1;
2818 # ifdef AT_SYMLINK_NOFOLLOW
2819 static int try_utimensat_follow = 1;
2821 const int try_utimensat_follow = 0;
2825 if (
v->follow ? try_utimensat_follow : try_utimensat) {
2826 # ifdef AT_SYMLINK_NOFOLLOW
2828 flags = AT_SYMLINK_NOFOLLOW;
2834 # ifdef AT_SYMLINK_NOFOLLOW
2835 try_utimensat_follow = 0;
2849 tvbuf[0].tv_sec = tsp[0].
tv_sec;
2850 tvbuf[0].tv_usec = (
int)(tsp[0].tv_nsec / 1000);
2851 tvbuf[1].tv_sec = tsp[1].
tv_sec;
2852 tvbuf[1].tv_usec = (
int)(tsp[1].tv_nsec / 1000);
2856 if (
v->follow)
return lutimes(
path, tvp);
2858 return utimes(
path, tvp);
2863 #if !defined HAVE_UTIME_H && !defined HAVE_SYS_UTIME_H
2871 utime_internal(
const char *
path,
void *
arg)
2881 return utime(
path, utp);
2893 args.atime = *
argv++;
2894 args.mtime = *
argv++;
2896 args.follow = follow;
2898 if (!
NIL_P(args.atime) || !
NIL_P(args.mtime)) {
2901 if (args.atime == args.mtime)
2908 return apply2files(utime_internal,
argc,
argv, &args);
2928 #if defined(HAVE_UTIMES) && (defined(HAVE_LUTIMES) || (defined(HAVE_UTIMENSAT) && defined(AT_SYMLINK_NOFOLLOW)))
2947 #define rb_file_s_lutime rb_f_notimplement
2950 #ifdef RUBY_FUNCTION_NAME_STRING
2951 # define syserr_fail2(e, s1, s2) syserr_fail2_in(RUBY_FUNCTION_NAME_STRING, e, s1, s2)
2953 # define syserr_fail2_in(func, e, s1, s2) syserr_fail2(e, s1, s2)
2955 #define sys_fail2(s1, s2) syserr_fail2(errno, s1, s2)
2962 const int max_pathlen = MAX_PATH;
2975 #ifdef RUBY_FUNCTION_NAME_STRING
2976 rb_syserr_fail_path_in(func, e,
str);
3009 #define rb_file_s_link rb_f_notimplement
3039 #define rb_file_s_symlink rb_f_notimplement
3042 #ifdef HAVE_READLINK
3061 struct readlink_arg {
3068 nogvl_readlink(
void *
ptr)
3070 struct readlink_arg *ra =
ptr;
3072 return (
void *)(
VALUE)
readlink(ra->path, ra->buf, ra->size);
3078 struct readlink_arg ra;
3118 #define rb_file_s_readlink rb_f_notimplement
3122 unlink_internal(
const char *
path,
void *
arg)
3146 return apply2files(unlink_internal,
argc,
argv, 0);
3155 no_gvl_rename(
void *
ptr)
3184 #if defined __CYGWIN__
3193 if (
chmod(ra.dst, 0666) == 0 &&
3195 rename(ra.src, ra.dst) == 0)
3199 syserr_fail2(e, from, to);
3242 #if defined __CYGWIN__ || defined DOSISH
3244 #define DOSISH_DRIVE_LETTER
3245 #define FILE_ALT_SEPARATOR '\\'
3247 #ifdef FILE_ALT_SEPARATOR
3248 #define isdirsep(x) ((x) == '/' || (x) == FILE_ALT_SEPARATOR)
3250 static const char file_alt_separator[] = {FILE_ALT_SEPARATOR,
'\0'};
3253 #define isdirsep(x) ((x) == '/')
3263 #ifndef USE_NTFS_ADS
3265 # define USE_NTFS_ADS 1
3267 # define USE_NTFS_ADS 0
3272 #define istrailinggarbage(x) ((x) == '.' || (x) == ' ')
3274 #define istrailinggarbage(x) 0
3277 # define isADS(x) ((x) == ':')
3282 #define Next(p, e, enc) ((p) + rb_enc_mbclen((p), (e), (enc)))
3283 #define Inc(p, e, enc) ((p) = Next((p), (e), (enc)))
3285 #if defined(DOSISH_UNC)
3286 #define has_unc(buf) (isdirsep((buf)[0]) && isdirsep((buf)[1]))
3288 #define has_unc(buf) 0
3291 #ifdef DOSISH_DRIVE_LETTER
3293 has_drive_letter(
const char *
buf)
3305 getcwdofdrv(
int drv)
3308 char *drvcwd, *oldcwd;
3319 if (
chdir(drive) == 0) {
3337 if (has_drive_letter(p)) {
3346 static inline char *
3349 #ifdef DOSISH_DRIVE_LETTER
3350 if (
path + 2 <= end && has_drive_letter(
path))
path += 2;
3353 return (
char *)
path;
3356 #define nextdirsep rb_enc_path_next
3366 #if defined(DOSISH_UNC) || defined(DOSISH_DRIVE_LETTER)
3367 #define skipprefix rb_enc_path_skip_prefix
3369 #define skipprefix(path, end, enc) (path)
3374 #if defined(DOSISH_UNC) || defined(DOSISH_DRIVE_LETTER)
3381 return (
char *)
path;
3384 #ifdef DOSISH_DRIVE_LETTER
3385 if (has_drive_letter(
path))
3386 return (
char *)(
path + 2);
3389 return (
char *)
path;
3392 static inline char *
3395 #if defined(DOSISH_UNC) || defined(DOSISH_DRIVE_LETTER)
3400 return skiproot(
path, end, enc);
3404 #define strrdirsep rb_enc_path_last_separator
3409 while (
path < end) {
3411 const char *tmp =
path++;
3413 if (
path >= end)
break;
3426 while (
path < end) {
3430 if (
path >= end)
return (
char *)
last;
3436 return (
char *)
path;
3443 return chompdirsep(
path, end, enc);
3460 if (
path >= end)
return (
char *)
last;
3467 return (
char *)
path;
3471 #define BUFCHECK(cond) do {\
3474 do {buflen *= 2;} while (cond);\
3475 rb_str_resize(result, buflen);\
3476 buf = RSTRING_PTR(result);\
3478 pend = buf + buflen;\
3482 #define BUFINIT() (\
3483 p = buf = RSTRING_PTR(result),\
3484 buflen = RSTRING_LEN(result),\
3488 # define SKIPPATHSEP(p) ((*(p)) ? 1 : 0)
3490 # define SKIPPATHSEP(p) 1
3493 #define BUFCOPY(srcptr, srclen) do { \
3494 const int skip = SKIPPATHSEP(p); \
3495 rb_str_set_len(result, p-buf+skip); \
3496 BUFCHECK(bdiff + ((srclen)+skip) >= buflen); \
3498 memcpy(p, (srcptr), (srclen)); \
3502 #define WITH_ROOTDIFF(stmt) do { \
3503 long rootdiff = root - buf; \
3505 root = buf + rootdiff; \
3509 copy_home_path(
VALUE result,
const char *dir)
3512 #if defined DOSISH || defined __CYGWIN__
3524 #if defined DOSISH || defined __CYGWIN__
3526 for (bend = (p =
buf) + dirlen; p < bend;
Inc(p, bend, enc)) {
3539 struct passwd *pwPtr;
3542 const char *pwPtr = 0;
3543 # define endpwent() ((void)0)
3557 pwPtr = getpwnam(username);
3560 dir = pwPtr =
getenv(
"HOME");
3567 dir = pwPtr->pw_dir;
3569 copy_home_path(result, dir);
3578 const char *dir =
getenv(
"HOME");
3580 #if defined HAVE_PWD_H
3584 struct passwd *pw = getpwnam(login);
3586 copy_home_path(result, pw->pw_dir);
3602 return copy_home_path(result, dir);
3608 #if NORMALIZE_UTF8PATH
3620 char *
buf, *cwdp = dir;
3626 if (direnc != fsenc) {
3635 do {buflen *= 2;}
while (dirlen > buflen);
3642 return buf + dirlen;
3648 const char *s, *b, *fend;
3649 char *
buf, *p, *pend, *root;
3650 size_t buflen, bdiff;
3658 if (s[0] ==
'~' && abs_mode == 0) {
3660 if (
isdirsep(s[1]) || s[1] ==
'\0') {
3671 BUFCHECK(bdiff + userlen >= buflen);
3683 (
int)userlen, b, fname);
3692 #ifdef DOSISH_DRIVE_LETTER
3694 else if (has_drive_letter(s)) {
3707 if (!
NIL_P(dname) && !not_same_drive(dname, s[0])) {
3716 char *e = append_fspath(result, fname, getcwdofdrv(*s), &enc, fsenc);
3724 p = chompdirsep(skiproot(
buf, p, enc), p, enc);
3730 if (!
NIL_P(dname)) {
3737 char *e = append_fspath(result, fname,
ruby_getcwd(), &enc, fsenc);
3741 #if defined DOSISH || defined __CYGWIN__
3749 p = chompdirsep(skiproot(
buf, p, enc), p, enc);
3762 if (p >
buf && p[-1] ==
'/')
3785 if (*(s+1) ==
'\0' ||
isdirsep(*(s+1))) {
3804 #if defined DOSISH || defined __CYGWIN__
3829 #if defined DOSISH || defined __CYGWIN__
3841 int n = ignored_char_p(s, fend, enc);
3860 static const char prime[] =
":$DATA";
3861 enum {prime_len =
sizeof(prime) -1};
3865 if (s > b + prime_len &&
strncasecmp(s - prime_len, prime, prime_len) == 0) {
3868 if (
isADS(*(s - (prime_len+1)))) {
3871 else if (
memchr(b,
':', s - prime_len - b)) {
3880 if (p == skiproot(
buf, p + !!*p, enc) - 1) p++;
3889 WIN32_FIND_DATAW wfd;
3892 #ifdef HAVE_CYGWIN_CONV_PATH
3893 char *w32buf =
NULL;
3894 const int flags = CCP_POSIX_TO_WIN_A | CCP_RELATIVE;
3900 int lnk_added = 0, is_symlink = 0;
3911 #ifdef HAVE_CYGWIN_CONV_PATH
3912 bufsize = cygwin_conv_path(flags,
path,
NULL, 0);
3915 if (lnk_added) bufsize += 4;
3917 if (cygwin_conv_path(flags,
path, w32buf, bufsize) == 0) {
3923 if (cygwin_conv_to_win32_path(
path, w32buf) == 0) {
3927 if (is_symlink && b == w32buf) {
3931 strlcat(w32buf,
".lnk", bufsize);
3947 MultiByteToWideChar(CP_UTF8, 0,
RSTRING_PTR(tmp), -1, wstr,
len);
3949 h = FindFirstFileW(wstr, &wfd);
3951 if (
h != INVALID_HANDLE_VALUE) {
3954 len = lstrlenW(wfd.cFileName);
3956 if (lnk_added &&
len > 4 &&
3957 wcscasecmp(wfd.cFileName +
len - 4,
L".lnk") == 0) {
3958 wfd.cFileName[
len -= 4] =
L'\0';
3965 len = WideCharToMultiByte(CP_UTF8, 0, wfd.cFileName, wlen,
NULL, 0,
NULL,
NULL);
3966 if (tmp == result) {
3968 WideCharToMultiByte(CP_UTF8, 0, wfd.cFileName, wlen, p,
len + 1,
NULL,
NULL);
3995 #define EXPAND_PATH_BUFFER() rb_usascii_str_new(0, MAXPATHLEN + 2)
4004 #define expand_path(fname, dname, abs_mode, long_name, result) \
4005 str_shrink(rb_file_expand_path_internal(fname, dname, abs_mode, long_name, result))
4007 #define check_expand_path_args(fname, dname) \
4008 (((fname) = rb_get_path(fname)), \
4009 (void)(NIL_P(dname) ? (dname) : ((dname) = rb_get_path(dname))))
4012 file_expand_path_1(
VALUE fname)
4131 realpath_rec(
long *prefixlenp,
VALUE *resolvedp,
const char *unresolved,
VALUE fallback,
4134 const char *pend = unresolved +
strlen(unresolved);
4138 while (unresolved < pend) {
4139 const char *testname = unresolved;
4141 long testnamelen = unresolved_firstsep - unresolved;
4142 const char *unresolved_nextname = unresolved_firstsep;
4143 while (unresolved_nextname < pend &&
isdirsep(*unresolved_nextname))
4144 unresolved_nextname++;
4145 unresolved = unresolved_nextname;
4146 if (testnamelen == 1 && testname[0] ==
'.') {
4148 else if (testnamelen == 2 && testname[0] ==
'.' && testname[1] ==
'.') {
4150 const char *resolved_str =
RSTRING_PTR(*resolvedp);
4151 const char *resolved_names = resolved_str + *prefixlenp;
4153 long len = lastsep ? lastsep - resolved_names : 0;
4162 #if defined(DOSISH_UNC) || defined(DOSISH_DRIVE_LETTER)
4163 if (*prefixlenp > 1 && *prefixlenp ==
RSTRING_LEN(testpath)) {
4171 if (!
NIL_P(checkval)) {
4172 if (checkval ==
ID2SYM(resolving)) {
4186 ret = lstat_without_gvl(
RSTRING_PTR(testpath), &sbuf);
4190 if (stat_without_gvl(
RSTRING_PTR(fallback), &sbuf) == 0) {
4199 *resolvedp = testpath;
4206 #ifdef HAVE_READLINK
4210 const char *link_prefix, *link_names;
4211 long link_prefixlen;
4216 link_prefixlen = link_names - link_prefix;
4217 if (link_prefixlen > 0) {
4224 *prefixlenp = link_prefixlen;
4226 if (realpath_rec(prefixlenp, resolvedp, link_names, testpath,
4227 loopcheck, mode, !*unresolved_firstsep))
4237 *resolvedp = testpath;
4250 VALUE unresolved_path;
4255 char *path_names =
NULL, *basedir_names =
NULL, *curdir_names =
NULL;
4256 char *
ptr, *prefixptr =
NULL, *pend;
4261 if (!
NIL_P(basedir)) {
4267 unresolved_path =
TO_OSPATH(unresolved_path);
4270 if (
ptr != path_names) {
4275 if (!
NIL_P(basedir)) {
4278 if (
ptr != basedir_names) {
4291 pend = prefixptr + prefixlen;
4292 ptr = chompdirsep(prefixptr, pend, enc);
4294 prefixlen = ++
ptr - prefixptr;
4297 #ifdef FILE_ALT_SEPARATOR
4298 while (prefixptr <
ptr) {
4299 if (*prefixptr == FILE_ALT_SEPARATOR) {
4302 Inc(prefixptr, pend, enc);
4314 if (realpath_rec(&prefixlen, &resolved, curdir_names,
Qnil, loopcheck, mode, 0))
4317 if (basedir_names) {
4318 if (realpath_rec(&prefixlen, &resolved, basedir_names,
Qnil, loopcheck, mode, 0))
4321 if (realpath_rec(&prefixlen, &resolved, path_names,
Qnil, loopcheck, mode, 1))
4324 if (origenc && origenc !=
rb_enc_get(resolved)) {
4343 #ifdef HAVE_REALPATH
4344 VALUE unresolved_path;
4345 char *resolved_ptr =
NULL;
4350 return rb_check_realpath_emulate(basedir,
path, origenc, mode);
4355 unresolved_path = rb_file_join(
rb_assoc_new(basedir, unresolved_path));
4357 if (origenc) unresolved_path =
TO_OSPATH(unresolved_path);
4366 (
errno ==
ENOENT && rb_file_exist_p(0, unresolved_path))) {
4367 return rb_check_realpath_emulate(basedir,
path, origenc, mode);
4387 if (origenc && origenc !=
rb_enc_get(resolved)) {
4404 return rb_check_realpath_emulate(basedir,
path, origenc, mode);
4466 rmext(
const char *p,
long l0,
long l1,
const char *e,
long l2,
rb_encoding *enc)
4470 const char *s, *
last;
4472 if (!e || !l2)
return 0;
4475 if (
rb_enc_ascget(e + len1, e + l2, &len2, enc) ==
'*' && len1 + len2 == l2) {
4476 if (c ==
'.')
return l0;
4486 if (l1 < l2)
return l1;
4490 #if CASEFOLD_FILESYSTEM
4491 #define fncomp strncasecmp
4493 #define fncomp strncmp
4495 if (
fncomp(s, e, l2) == 0) {
4504 const char *p, *q, *e, *end;
4505 #if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
4512 #if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
4520 #if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
4524 #ifdef DOSISH_DRIVE_LETTER
4525 else if (*p ==
':') {
4545 n = ntfs_tail(p, end, enc) - p;
4547 n = chompdirsep(p, end, enc) - p;
4549 for (q = p; q - p <
n && *q ==
'.'; q++);
4550 for (e = 0; q - p <
n;
Inc(q, end, enc)) {
4551 if (*q ==
'.') e = q;
4585 const char *
name, *p;
4593 enc = check_path_encoding(fext);
4647 const char *
name, *root, *p, *end;
4655 root = skiproot(
name, end, enc);
4660 if (root >
name + 1)
4669 #ifdef DOSISH_DRIVE_LETTER
4671 const char *
top = skiproot(
name + 2, end, enc);
4678 #ifdef DOSISH_DRIVE_LETTER
4679 if (has_drive_letter(
name) && root ==
name + 2 && p -
name == 2)
4710 while (*p && *p ==
'.') p++;
4714 const char *
last = p++, *dot =
last;
4716 if (*p ==
'.') dot = p;
4719 if (!*p ||
isADS(*p)) {
4723 if (*
last ==
'.' || dot >
last) e = dot;
4730 else if (
isADS(*p)) {
4741 if (!e || e ==
name)
4780 const char *
name, *e;
4833 return rb_file_join(
arg);
4837 rb_file_join(
VALUE ary)
4841 const char *
name, *tail;
4851 check_path_encoding(tmp);
4865 if (!checked) check_path_encoding(tmp);
4916 return rb_file_join(args);
4919 #if defined(HAVE_TRUNCATE) || defined(HAVE_CHSIZE)
4920 struct truncate_arg {
4922 #if defined(HAVE_TRUNCATE)
4923 #define NUM2POS(n) NUM2OFFT(n)
4926 #define NUM2POS(n) NUM2LONG(n)
4932 nogvl_truncate(
void *
ptr)
4934 struct truncate_arg *ta =
ptr;
4935 #ifdef HAVE_TRUNCATE
4944 if (chsize(tmpfd, ta->pos) < 0) {
4974 struct truncate_arg ta;
4977 ta.pos = NUM2POS(
len);
4990 #define rb_file_s_truncate rb_f_notimplement
4993 #if defined(HAVE_FTRUNCATE) || defined(HAVE_CHSIZE)
4994 struct ftruncate_arg {
4996 #if defined(HAVE_FTRUNCATE)
4997 #define NUM2POS(n) NUM2OFFT(n)
5000 #define NUM2POS(n) NUM2LONG(n)
5006 nogvl_ftruncate(
void *
ptr)
5008 struct ftruncate_arg *fa =
ptr;
5010 #ifdef HAVE_FTRUNCATE
5013 return (
VALUE)chsize(fa->fd, fa->pos);
5035 struct ftruncate_arg fa;
5037 fa.pos = NUM2POS(
len);
5051 #define rb_file_truncate rb_f_notimplement
5068 #include <winerror.h>
5072 rb_thread_flock(
void *data)
5075 int old_errno =
errno;
5077 int *op = data, ret =
flock(op[0], op[1]);
5080 if (GetLastError() == ERROR_NOT_LOCKED) {
5139 op[1] = op1 =
NUM2INT(operation);
5151 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
5157 time.tv_usec = 100 * 1000;
5163 #if defined(ERESTART)
5182 for (
i=1;
i<
n;
i++) {
5189 #define CHECK(n) test_check((n), argc, argv)
5266 if (
strchr(
"bcdefgGkloOprRsSuwWxXz", cmd)) {
5270 return rb_file_blockdev_p(0,
argv[1]);
5273 return rb_file_chardev_p(0,
argv[1]);
5279 return rb_file_exist_p(0,
argv[1]);
5282 return rb_file_file_p(0,
argv[1]);
5285 return rb_file_sgid_p(0,
argv[1]);
5288 return rb_file_grpowned_p(0,
argv[1]);
5291 return rb_file_sticky_p(0,
argv[1]);
5294 return rb_file_symlink_p(0,
argv[1]);
5297 return rb_file_owned_p(0,
argv[1]);
5300 return rb_file_rowned_p(0,
argv[1]);
5303 return rb_file_pipe_p(0,
argv[1]);
5306 return rb_file_readable_p(0,
argv[1]);
5309 return rb_file_readable_real_p(0,
argv[1]);
5312 return rb_file_size_p(0,
argv[1]);
5315 return rb_file_socket_p(0,
argv[1]);
5318 return rb_file_suid_p(0,
argv[1]);
5321 return rb_file_writable_p(0,
argv[1]);
5324 return rb_file_writable_real_p(0,
argv[1]);
5327 return rb_file_executable_p(0,
argv[1]);
5330 return rb_file_executable_real_p(0,
argv[1]);
5333 return rb_file_zero_p(0,
argv[1]);
5337 if (
strchr(
"MAC", cmd)) {
5342 if (rb_stat(fname, &
st) == -1) {
5350 return stat_atime(&
st);
5352 return stat_mtime(&
st);
5354 return stat_ctime(&
st);
5360 return rb_file_identical_p(0,
argv[1],
argv[2]);
5363 if (
strchr(
"=<>", cmd)) {
5364 struct stat st1, st2;
5368 if (rb_stat(
argv[1], &st1) < 0)
return Qfalse;
5369 if (rb_stat(
argv[2], &st2) < 0)
return Qfalse;
5371 t1 = stat_mtimespec(&st1);
5372 t2 = stat_mtimespec(&st2);
5409 return stat_new_0(
klass, 0);
5479 return rb_file_ftype(get_stat(
obj));
5675 if (rb_stat_owned(
obj))
5679 if (rb_stat_grpowned(
obj))
5708 if (rb_stat_rowned(
obj))
5712 if (rb_group_member(get_stat(
obj)->
st_gid))
5768 if (rb_stat_owned(
obj))
5772 if (rb_stat_grpowned(
obj))
5801 if (rb_stat_rowned(
obj))
5805 if (rb_group_member(get_stat(
obj)->
st_gid))
5865 if (rb_stat_owned(
obj))
5869 if (rb_stat_grpowned(
obj))
5897 if (rb_stat_rowned(
obj))
5901 if (rb_group_member(get_stat(
obj)->
st_gid))
6027 #if !defined HAVE_MKFIFO && defined HAVE_MKNOD && defined S_IFIFO
6028 #define mkfifo(path, mode) mknod(path, (mode)&~S_IFMT|S_IFIFO, 0)
6039 nogvl_mkfifo(
void *
ptr)
6041 struct mkfifo_arg *ma =
ptr;
6060 struct mkfifo_arg ma;
6077 #define rb_file_s_mkfifo rb_f_notimplement
6080 static VALUE rb_mFConst;
6091 #ifdef DOSISH_DRIVE_LETTER
6098 if (
path[0] ==
'/')
return 1;
6103 #ifndef ENABLE_PATH_CHECK
6104 # if defined DOSISH || defined __CYGWIN__
6105 # define ENABLE_PATH_CHECK 0
6107 # define ENABLE_PATH_CHECK 1
6111 #if ENABLE_PATH_CHECK
6137 # define S_IWOTH 002
6141 && !(p && execpath && (
st.st_mode &
S_ISVTX))
6144 rb_enc_warn(enc,
"Insecure world writable dir %s in %sPATH, mode 0%"
6146 p0, (execpath ?
"" :
"LOAD_"),
st.st_mode);
6153 if (!s || s == p0)
return 1;
6161 #if ENABLE_PATH_CHECK
6162 #define fpath_check(path) path_check_0((path), FALSE)
6164 #define fpath_check(path) 1
6170 #if ENABLE_PATH_CHECK
6171 const char *p0, *p, *pend;
6174 if (!
path)
return 1;
6186 if (p0 > pend)
break;
6229 int mode = (O_RDONLY |
6230 #if defined O_NONBLOCK
6232 #elif defined O_NDELAY
6237 if (fd == -1)
return 0;
6246 is_explicit_relative(
const char *
path)
6248 if (*
path++ !=
'.')
return 0;
6265 rb_warn(
"rb_find_file_ext_safe will be removed in Ruby 3.0");
6273 VALUE fname = *filep, load_path, tmp;
6277 if (!ext[0])
return 0;
6280 fname = file_expand_path_1(fname);
6287 if (!expanded) fname = file_expand_path_1(fname);
6289 for (
i=0; ext[
i];
i++) {
6292 *filep = copy_path_class(fname, *filep);
6301 if (!load_path)
return 0;
6308 for (j=0; ext[j]; j++) {
6317 *filep = copy_path_class(tmp, *filep);
6331 rb_warn(
"rb_find_file_safe will be removed in Ruby 3.0");
6338 VALUE tmp, load_path;
6343 tmp = file_expand_path_1(
path);
6352 path = copy_path_class(file_expand_path_1(
path),
path);
6379 return copy_path_class(tmp,
path);
6392 #elif defined AMIGA || defined __amigaos__
6443 define_filetest_function(
"exist?", rb_file_exist_p, 1);
6444 define_filetest_function(
"exists?", rb_file_exists_p, 1);
6445 define_filetest_function(
"readable?", rb_file_readable_p, 1);
6446 define_filetest_function(
"readable_real?", rb_file_readable_real_p, 1);
6447 define_filetest_function(
"world_readable?", rb_file_world_readable_p, 1);
6448 define_filetest_function(
"writable?", rb_file_writable_p, 1);
6449 define_filetest_function(
"writable_real?", rb_file_writable_real_p, 1);
6450 define_filetest_function(
"world_writable?", rb_file_world_writable_p, 1);
6451 define_filetest_function(
"executable?", rb_file_executable_p, 1);
6452 define_filetest_function(
"executable_real?", rb_file_executable_real_p, 1);
6453 define_filetest_function(
"file?", rb_file_file_p, 1);
6454 define_filetest_function(
"zero?", rb_file_zero_p, 1);
6455 define_filetest_function(
"empty?", rb_file_zero_p, 1);
6456 define_filetest_function(
"size?", rb_file_size_p, 1);
6457 define_filetest_function(
"size", rb_file_s_size, 1);
6458 define_filetest_function(
"owned?", rb_file_owned_p, 1);
6459 define_filetest_function(
"grpowned?", rb_file_grpowned_p, 1);
6461 define_filetest_function(
"pipe?", rb_file_pipe_p, 1);
6462 define_filetest_function(
"symlink?", rb_file_symlink_p, 1);
6463 define_filetest_function(
"socket?", rb_file_socket_p, 1);
6465 define_filetest_function(
"blockdev?", rb_file_blockdev_p, 1);
6466 define_filetest_function(
"chardev?", rb_file_chardev_p, 1);
6468 define_filetest_function(
"setuid?", rb_file_suid_p, 1);
6469 define_filetest_function(
"setgid?", rb_file_sgid_p, 1);
6470 define_filetest_function(
"sticky?", rb_file_sticky_p, 1);
6472 define_filetest_function(
"identical?", rb_file_identical_p, 2);
6570 #if defined(O_NDELAY) || defined(O_NONBLOCK)
6572 # define O_NONBLOCK O_NDELAY
6588 #ifndef O_SHARE_DELETE
6589 # define O_SHARE_DELETE 0
VALUE rb_readlink(VALUE path, rb_encoding *resultenc)
VALUE rb_file_directory_p(VALUE obj, VALUE fname)
VALUE rb_str_replace(VALUE, VALUE)
VALUE rb_str_plus(VALUE, VALUE)
int eaccess(const char *path, int mode)
VALUE rb_str_ellipsize(VALUE, long)
Shortens str and adds three dots, an ellipsis, if it is longer than len characters.
struct apply_filename fn[FLEX_ARY_LEN]
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
VALUE rb_home_dir_of(VALUE user, VALUE result)
NORETURN(static void syserr_fail2_in(const char *, int, VALUE, VALUE))
int rb_path_check(const char *path)
#define istrailinggarbage(x)
VALUE rb_check_convert_type_with_id(VALUE, int, const char *, ID)
#define RSTRING_GETMEM(str, ptrvar, lenvar)
RUBY_EXTERN size_t strlcat(char *, const char *, size_t)
void rb_include_module(VALUE klass, VALUE module)
VALUE rb_file_expand_path_fast(VALUE fname, VALUE dname)
int rb_find_file_ext_safe(VALUE *filep, const char *const *ext, int _level)
struct timespec rb_time_timespec(VALUE time)
VALUE rb_assoc_new(VALUE car, VALUE cdr)
VALUE rb_dir_getwd_ospath(void)
rb_encoding * rb_filesystem_encoding(void)
#define rb_enc_mbc_to_codepoint(p, e, enc)
#define statx_has_birthtime(st)
VALUE rb_define_module_under(VALUE outer, const char *name)
void rb_warn(const char *fmt,...)
VALUE rb_str_buf_new(long)
VALUE rb_w32_file_identical_p(VALUE fname1, VALUE fname2)
void rb_warning(const char *fmt,...)
#define RBASIC_CLEAR_CLASS(obj)
char * strchr(char *, char)
#define OBJ_BUILTIN_TYPE(obj)
#define rb_stat_birthtime
union no_gvl_stat_data::@74 file
VALUE rb_hash_aref(VALUE hash, VALUE key)
VALUE rb_equal(VALUE, VALUE)
Same as Object#===, case equality.
VALUE rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_name, VALUE result)
#define offsetof(p_type, field)
#define RB_TYPE_P(obj, type)
VALUE rb_file_s_expand_path(int argc, const VALUE *argv)
VALUE rb_file_s_absolute_path(int argc, const VALUE *argv)
char * rb_str_to_cstr(VALUE str)
rb_encoding * rb_enc_get(VALUE obj)
#define rb_enc_asciicompat(enc)
rb_encoding * rb_enc_check(VALUE str1, VALUE str2)
int rb_enc_precise_mbclen(const char *p, const char *e, rb_encoding *enc)
#define rb_sys_fail_path(path)
VALUE rb_define_module(const char *name)
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
const char * ruby_enc_find_extname(const char *name, long *len, rb_encoding *enc)
void rb_io_check_closed(rb_io_t *)
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
VALUE rb_time_nano_new(time_t, long)
char * rb_enc_path_last_separator(const char *path, const char *end, rb_encoding *enc)
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
RUBY_EXTERN VALUE rb_eIOError
VALUE rb_str_inspect(VALUE)
#define ENC_CODERANGE_CLEAR(obj)
VALUE rb_io_taint_check(VALUE)
VALUE rb_get_path(VALUE obj)
int chown(const char *, int, int)
VALUE rb_check_realpath(VALUE basedir, VALUE path, rb_encoding *enc)
#define RBASIC_SET_CLASS(obj, cls)
VALUE rb_str_cat_conv_enc_opts(VALUE newstr, long ofs, const char *ptr, long len, rb_encoding *from, int ecflags, VALUE ecopts)
int ruby_is_fd_loadable(int fd)
size_t strlen(const char *)
#define RUBY_FUNC_EXPORTED
size_t rb_str_capacity(VALUE str)
VALUE rb_get_expanded_load_path(void)
VALUE rb_str_resize(VALUE, long)
#define RUBY_TYPED_DEFAULT_FREE
void rb_raise(VALUE exc, const char *fmt,...)
#define NORMALIZE_UTF8PATH
VALUE rb_obj_class(VALUE)
Equivalent to Object#class in Ruby.
void rb_io_check_initialized(rb_io_t *)
rb_encoding * rb_ascii8bit_encoding(void)
VALUE rb_find_file_safe(VALUE path, int _level)
#define MBCLEN_CHARFOUND_LEN(ret)
#define sys_fail2(s1, s2)
const typedef OnigEncodingType rb_encoding
#define rb_enc_left_char_head(s, p, e, enc)
VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd)
#define ALLOCV_N(type, v, n)
rb_encoding * rb_enc_from_index(int index)
void rb_file_const(const char *name, VALUE value)
VALUE rb_file_absolute_path(VALUE fname, VALUE dname)
#define rb_str_dup_frozen
#define syserr_fail2_in(func, e, s1, s2)
VALUE rb_realpath_internal(VALUE basedir, VALUE path, int strict)
int rb_file_load_ok(const char *path)
int(* func)(const char *, void *)
void rb_update_max_fd(int fd)
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
const struct timespec * tsp
int rb_enc_to_index(rb_encoding *enc)
#define TypedData_Wrap_Struct(klass, data_type, sval)
VALUE rb_file_dirname(VALUE fname)
VALUE rb_io_flush_raw(VALUE, int)
#define rb_file_s_readlink
VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
#define INTEGER_PACK_NATIVE_BYTE_ORDER
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
#define ALLOCA_N(type, n)
VALUE rb_get_path_check_convert(VALUE obj)
#define RARRAY_AREF(a, i)
#define StringValuePtr(v)
#define RTYPEDDATA_DATA(v)
void rb_enc_copy(VALUE obj1, VALUE obj2)
rb_encoding * rb_enc_compatible(VALUE str1, VALUE str2)
void rb_str_set_len(VALUE, long)
int lchown(const char *path, int owner, int group)
MJIT_STATIC void rb_error_arity(int argc, int min, int max)
VALUE rb_default_home_dir(VALUE result)
rb_encoding * rb_default_internal_encoding(void)
#define expand_path(fname, dname, abs_mode, long_name, result)
#define CONST_ID(var, str)
#define StringValueCStr(v)
#define ENC_CODERANGE_BROKEN
int link(const char *, const char *)
int fchmod(int fd, int mode)
VALUE rb_str_buf_append(VALUE, VALUE)
#define rb_file_s_truncate
#define BUFCOPY(srcptr, srclen)
#define MBCLEN_CHARFOUND_P(ret)
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
RUBY_EXTERN VALUE rb_cObject
int rb_cloexec_open(const char *pathname, int flags, mode_t mode)
unsigned char buf[MIME_BUF_SIZE]
int rb_usascii_encindex(void)
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
#define rb_syserr_fail_path(err, path)
#define TypedData_Get_Struct(obj, type, data_type, sval)
VALUE rb_str_append(VALUE, VALUE)
char * rb_enc_path_next(const char *s, const char *e, rb_encoding *enc)
int rb_enc_str_coderange(VALUE)
char * rb_enc_path_end(const char *path, const char *end, rb_encoding *enc)
#define EXPAND_PATH_BUFFER()
#define check_expand_path_args(fname, dname)
#define OBJ_INIT_COPY(obj, orig)
const char * ruby_enc_find_basename(const char *name, long *baselen, long *alllen, rb_encoding *enc)
#define rb_file_s_symlink
#define ENCODING_GET(obj)
VALUE rb_sprintf(const char *format,...)
VALUE rb_str_subseq(VALUE, long, long)
rb_encoding * rb_utf8_encoding(void)
VALUE rb_get_path_check_to_string(VALUE obj)
char str[HTML_ESCAPE_MAX_LEN+1]
#define STRCASECMP(s1, s2)
#define RUBY_TYPED_FREE_IMMEDIATELY
#define ENC_CODERANGE_7BIT
int rb_enc_ascget(const char *p, const char *e, int *len, rb_encoding *enc)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
RUBY_EXTERN VALUE rb_cString
VALUE rb_str_encode_ospath(VALUE path)
VALUE rb_str_new_shared(VALUE)
void rb_enc_raise(rb_encoding *enc, VALUE exc, const char *fmt,...)
void rb_str_modify_expand(VALUE, long)
ssize_t readlink(const char *, char *, size_t)
void rb_enc_warn(rb_encoding *enc, const char *fmt,...)
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
const char * rb_obj_classname(VALUE)
VALUE rb_check_funcall_default(VALUE, ID, int, const VALUE *, VALUE)
void rb_define_const(VALUE, const char *, VALUE)
VALUE rb_eSystemCallError
#define GetOpenFile(obj, fp)
int rb_filesystem_encindex(void)
#define ENCINDEX_US_ASCII
VALUE rb_str_catf(VALUE str, const char *format,...)
char * rb_enc_path_skip_prefix(const char *path, const char *end, rb_encoding *enc)
VALUE rb_stat_new(const struct stat *st)
#define rb_usascii_str_new2
VALUE rb_class_new_instance(int, const VALUE *, VALUE)
Allocates and initializes an instance of klass.
#define INTEGER_PACK_2COMP
VALUE rb_get_path_no_checksafe(VALUE obj)
#define RBASIC_SET_CLASS_RAW(obj, cls)
void rb_thread_wait_for(struct timeval)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
#define FilePathStringValue(v)
struct no_gvl_stat_data no_gvl_stat_data
int rb_is_absolute_path(const char *path)
VALUE rb_find_file(VALUE path)
#define skipprefix(path, end, enc)
int rb_enc_str_asciionly_p(VALUE)
VALUE rb_file_expand_path(VALUE fname, VALUE dname)
#define rb_file_s_birthtime
#define rb_fstring_lit(str)
#define INTEGER_PACK_LSWORD_FIRST
int rb_find_file_ext(VALUE *filep, const char *const *ext)
VALUE rb_str_tmp_new(long)
VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to)
unsigned int rb_enc_codepoint_len(const char *p, const char *e, int *len_p, rb_encoding *enc)
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
VALUE rb_str_cat(VALUE, const char *, long)
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
const char ruby_null_device[]
int symlink(const char *src, const char *link)
#define WITH_ROOTDIFF(stmt)
VALUE rb_enc_associate_index(VALUE obj, int idx)
int rb_str_cmp(VALUE, VALUE)
VALUE rb_class_inherited_p(VALUE mod, VALUE arg)
Determines if mod inherits arg.
#define rb_file_birthtime