19 #include <sys/cygwin.h>
33 #ifdef HAVE_SYS_FILE_H
34 # include <sys/file.h>
39 #ifdef HAVE_SYS_PARAM_H
40 # include <sys/param.h>
43 # define MAXPATHLEN 1024
52 #elif defined HAVE_SYS_UTIME_H
53 #include <sys/utime.h>
60 #include <sys/types.h>
63 #ifdef HAVE_SYS_MKDEV_H
64 #include <sys/mkdev.h>
67 #if defined(HAVE_FCNTL_H)
71 #if !defined HAVE_LSTAT && !defined lstat
77 #define STAT(p, s) rb_w32_ustati64((p), (s))
79 #define lstat(p, s) rb_w32_ustati64((p), (s))
81 #define access(p, m) rb_w32_uaccess((p), (m))
83 #define chmod(p, m) rb_w32_uchmod((p), (m))
85 #define chown(p, o, g) rb_w32_uchown((p), (o), (g))
87 #define utime(p, t) rb_w32_uutime((p), (t))
89 #define link(f, t) rb_w32_ulink((f), (t))
91 #define unlink(p) rb_w32_uunlink(p)
93 #define rename(f, t) rb_w32_urename((f), (t))
95 #define STAT(p, s) stat((p), (s))
98 #define rb_sys_fail_path(path) rb_sys_fail_str(path)
100 #if defined(__BEOS__) || defined(__HAIKU__)
102 be_chown(
const char *
path, uid_t owner, gid_t group)
104 if (owner == (uid_t)-1 || group == (gid_t)-1) {
106 if (
STAT(path, &st) < 0)
return -1;
107 if (owner == (uid_t)-1) owner = st.st_uid;
108 if (group == (gid_t)-1) group = st.st_gid;
110 return chown(path, owner, group);
112 #define chown be_chown
114 be_fchown(
int fd, uid_t owner, gid_t group)
116 if (owner == (uid_t)-1 || group == (gid_t)-1) {
118 if (
fstat(fd, &st) < 0)
return -1;
119 if (owner == (uid_t)-1) owner = st.st_uid;
120 if (group == (gid_t)-1) group = st.st_gid;
122 return fchown(fd, owner, group);
124 #define fchown be_fchown
131 #define insecure_obj_p(obj, level) ((level) >= 4 || ((level) > 0 && OBJ_TAINTED(obj)))
229 (*func)(s, path,
arg);
261 return p ?
sizeof(
struct stat) : 0;
272 struct stat *nst = 0;
328 #define ST2UINT(val) ((val) & ~(~1UL << (sizeof(val) * CHAR_BIT - 1)))
331 # define NUM2DEVT(v) NUM2UINT(v)
334 # define DEVT2NUM(v) UINT2NUM(v)
336 #ifndef PRI_DEVT_PREFIX
337 # define PRI_DEVT_PREFIX ""
411 #if SIZEOF_STRUCT_STAT_ST_INO > SIZEOF_LONG
412 return ULL2NUM(
get_stat(
self)->st_ino);
523 #if defined(HAVE_ST_RDEV) && defined(major)
544 #if defined(HAVE_ST_RDEV) && defined(minor)
580 #ifdef HAVE_ST_BLKSIZE
601 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
602 # if SIZEOF_STRUCT_STAT_ST_BLOCKS > SIZEOF_LONG
603 return ULL2NUM(
get_stat(
self)->st_blocks);
617 #if defined(HAVE_STRUCT_STAT_ST_ATIM)
618 ts.
tv_nsec = st->st_atim.tv_nsec;
619 #elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC)
620 ts.
tv_nsec = st->st_atimespec.tv_nsec;
621 #elif defined(HAVE_STRUCT_STAT_ST_ATIMENSEC)
641 #if defined(HAVE_STRUCT_STAT_ST_MTIM)
642 ts.
tv_nsec = st->st_mtim.tv_nsec;
643 #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
644 ts.
tv_nsec = st->st_mtimespec.tv_nsec;
645 #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
665 #if defined(HAVE_STRUCT_STAT_ST_CTIM)
666 ts.
tv_nsec = st->st_ctim.tv_nsec;
667 #elif defined(HAVE_STRUCT_STAT_ST_CTIMESPEC)
668 ts.
tv_nsec = st->st_ctimespec.tv_nsec;
669 #elif defined(HAVE_STRUCT_STAT_ST_CTIMENSEC)
756 static const struct {
785 for (i = 0; i <
sizeof(member)/
sizeof(member[0]); i++) {
793 v = (*member[
i].func)(
self);
797 else if (i == 0 || i == 6) {
830 w32_io_info(
VALUE *file, BY_HANDLE_FILE_INFORMATION *st)
841 if (f == (HANDLE)-1)
return INVALID_HANDLE_VALUE;
851 len = MultiByteToWideChar(CP_UTF8, 0,
RSTRING_PTR(tmp), -1, NULL, 0);
853 MultiByteToWideChar(CP_UTF8, 0,
RSTRING_PTR(tmp), -1, ptr, len);
854 f = CreateFileW(ptr, 0,
855 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
859 if (f == INVALID_HANDLE_VALUE)
return f;
862 if (GetFileType(f) == FILE_TYPE_DISK) {
863 ZeroMemory(st,
sizeof(*st));
864 if (GetFileInformationByHandle(f, st))
return ret;
866 if (ret) CloseHandle(ret);
867 return INVALID_HANDLE_VALUE;
917 if (
fstat(fptr->
fd, &st) == -1) {
998 # ifdef HAVE_GETGROUPS
1001 # define NGROUPS NGROUPS_MAX
1010 gary =
xmalloc(NGROUPS *
sizeof(GETGROUPS_T));
1011 anum = getgroups(NGROUPS, gary);
1012 while (--anum >= 0) {
1013 if (gary[anum] == gid) {
1026 # define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
1029 #if defined(S_IXGRP) && !defined(_WIN32) && !defined(__CYGWIN__)
1030 #define USE_GETEUID 1
1033 #ifndef HAVE_EACCESS
1041 if (
STAT(path, &st) < 0)
1059 if (st.st_uid == euid)
1064 if ((
int)(st.st_mode & mode) == mode)
return 0;
1068 return access(path, mode);
1076 return access(path, mode);
1119 # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
1141 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
1147 if (S_ISFIFO(st.st_mode))
return Qtrue;
1165 # define S_ISLNK(m) _S_ISLNK(m)
1168 # define S_ISLNK(m) (((m) & S_IFMT) == _S_IFLNK)
1171 # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
1202 # define S_ISSOCK(m) _S_ISSOCK(m)
1205 # define S_ISSOCK(m) (((m) & S_IFMT) == _S_IFSOCK)
1208 # define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
1218 if (S_ISSOCK(st.st_mode))
return Qtrue;
1236 # define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
1238 # define S_ISBLK(m) (0)
1262 # define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
1327 # define S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH)
1331 # define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH)
1463 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
1498 if (st.st_size == 0)
return Qtrue;
1516 if (st.st_size == 0)
return Qnil;
1570 #if defined(S_ISUID) || defined(S_ISGID) || defined(S_ISVTX)
1572 check3rdbyte(
VALUE fname,
int mode)
1580 if (st.st_mode & mode)
return Qtrue;
1596 return check3rdbyte(fname, S_ISUID);
1613 return check3rdbyte(fname, S_ISGID);
1630 return check3rdbyte(fname, S_ISVTX);
1657 struct stat st1, st2;
1661 if (st1.st_dev != st2.st_dev)
return Qfalse;
1662 if (st1.st_ino != st2.st_ino)
return Qfalse;
1665 BY_HANDLE_FILE_INFORMATION st1, st2;
1666 HANDLE f1 = 0, f2 = 0;
1671 f1 = w32_io_info(&fname1, &st1);
1672 if (f1 == INVALID_HANDLE_VALUE)
return Qfalse;
1673 f2 = w32_io_info(&fname2, &st2);
1674 if (f1) CloseHandle(f1);
1675 if (f2 == INVALID_HANDLE_VALUE)
return Qfalse;
1676 if (f2) CloseHandle(f2);
1678 if (st1.dwVolumeSerialNumber == st2.dwVolumeSerialNumber &&
1679 st1.nFileIndexHigh == st2.nFileIndexHigh &&
1680 st1.nFileIndexLow == st2.nFileIndexLow)
1682 if (!f1 || !f2)
return Qfalse;
1714 if (
rb_stat(fname, &st) < 0) {
1729 else if (
S_ISDIR(st->st_mode)) {
1732 else if (
S_ISCHR(st->st_mode)) {
1733 t =
"characterSpecial";
1736 else if (
S_ISBLK(st->st_mode)) {
1741 else if (S_ISFIFO(st->st_mode)) {
1746 else if (
S_ISLNK(st->st_mode)) {
1751 else if (S_ISSOCK(st->st_mode)) {
1807 if (
rb_stat(fname, &st) < 0) {
1832 if (
fstat(fptr->
fd, &st) == -1) {
1853 if (
rb_stat(fname, &st) < 0) {
1877 if (
fstat(fptr->
fd, &st) == -1) {
1902 if (
rb_stat(fname, &st) < 0) {
1929 if (
fstat(fptr->
fd, &st) == -1) {
1955 if (
fstat(fptr->
fd, &st) == -1) {
1964 if (chmod(path, *(
int *)mode) < 0)
2024 if (fchmod(fptr->
fd, mode) == -1)
2036 #if defined(HAVE_LCHMOD)
2038 lchmod_internal(
const char *path,
VALUE pathv,
void *mode)
2040 if (lchmod(path, (
int)(
VALUE)mode) < 0)
2065 n =
apply2files(lchmod_internal, rest, (
void *)(
long)mode);
2069 #define rb_file_s_lchmod rb_f_notimplement
2160 if (fchown(fptr->
fd, o, g) == -1)
2167 #if defined(HAVE_LCHOWN)
2169 lchown_internal(
const char *path,
VALUE pathv,
void *
arg)
2172 if (lchown(path, args->
owner, args->
group) < 0)
2213 #define rb_file_s_lchown rb_f_notimplement
2221 #if defined DOSISH || defined __CYGWIN__
2227 if (tsp && errno == EINVAL) {
2230 if (!
NIL_P(atime)) {
2233 if (!
NIL_P(mtime) && mtime != atime && !
rb_equal(atime, mtime)) {
2236 if (
NIL_P(a)) e[0] = m;
2256 #define utime_failed(path, tsp, atime, mtime) rb_sys_fail_path(path)
2259 #if defined(HAVE_UTIMES)
2268 #ifdef HAVE_UTIMENSAT
2269 static int try_utimensat = 1;
2271 if (try_utimensat) {
2272 if (utimensat(AT_FDCWD, path, tsp, 0) < 0) {
2273 if (
errno == ENOSYS) {
2286 tvbuf[0].
tv_usec = (int)(tsp[0].tv_nsec / 1000);
2288 tvbuf[1].
tv_usec = (int)(tsp[1].tv_nsec / 1000);
2291 if (utimes(path, tvp) < 0)
2297 #if !defined HAVE_UTIME_H && !defined HAVE_SYS_UTIME_H
2315 if (utime(path, utp) < 0)
2358 const int max_pathlen = MAX_PATH;
2399 #define rb_file_s_link rb_f_notimplement
2430 #define rb_file_s_symlink rb_f_notimplement
2433 #ifdef HAVE_READLINK
2450 return rb_readlink(path);
2454 rb_readlink(
VALUE path)
2465 while ((rv = readlink(
RSTRING_PTR(path), buf, size)) == size
2467 || (rv < 0 && errno == ERANGE)
2483 #define rb_file_s_readlink rb_f_notimplement
2489 if (unlink(path) < 0)
2526 const char *src, *dst;
2536 #if defined __CYGWIN__
2539 if (rename(src, dst) < 0) {
2543 #if defined (__EMX__)
2546 if (chmod(dst, 0666) == 0 &&
2548 rename(src, dst) == 0)
2583 else if (argc == 1) {
2584 omask = umask(
NUM2INT(argv[0]));
2595 #if defined __CYGWIN__ || defined DOSISH
2597 #define DOSISH_DRIVE_LETTER
2598 #define FILE_ALT_SEPARATOR '\\'
2600 #ifdef FILE_ALT_SEPARATOR
2601 #define isdirsep(x) ((x) == '/' || (x) == FILE_ALT_SEPARATOR)
2602 static const char file_alt_separator[] = {FILE_ALT_SEPARATOR,
'\0'};
2604 #define isdirsep(x) ((x) == '/')
2608 #if defined _WIN32 || defined __CYGWIN__
2616 #define istrailinggarbage(x) ((x) == '.' || (x) == ' ')
2618 #define istrailinggarbage(x) 0
2621 #define Next(p, e, enc) ((p) + rb_enc_mbclen((p), (e), (enc)))
2622 #define Inc(p, e, enc) ((p) = Next((p), (e), (enc)))
2624 #if defined(DOSISH_UNC)
2625 #define has_unc(buf) (isdirsep((buf)[0]) && isdirsep((buf)[1]))
2627 #define has_unc(buf) 0
2630 #ifdef DOSISH_DRIVE_LETTER
2632 has_drive_letter(
const char *buf)
2634 if (
ISALPHA(buf[0]) && buf[1] ==
':') {
2643 getcwdofdrv(
int drv)
2646 char *drvcwd, *oldcwd;
2657 if (chdir(drive) == 0) {
2670 not_same_drive(
VALUE path,
int drive)
2674 if (has_drive_letter(p)) {
2683 static inline char *
2686 #ifdef DOSISH_DRIVE_LETTER
2687 if (path + 2 <= end && has_drive_letter(path)) path += 2;
2689 while (path < end &&
isdirsep(*path)) path++;
2690 return (
char *)path;
2693 #define nextdirsep rb_enc_path_next
2703 #if defined(DOSISH_UNC) || defined(DOSISH_DRIVE_LETTER)
2704 #define skipprefix rb_enc_path_skip_prefix
2706 #define skipprefix(path, end, enc) (path)
2711 #if defined(DOSISH_UNC) || defined(DOSISH_DRIVE_LETTER)
2715 while (path < end &&
isdirsep(*path)) path++;
2718 return (
char *)path;
2721 #ifdef DOSISH_DRIVE_LETTER
2722 if (has_drive_letter(path))
2723 return (
char *)(path + 2);
2726 return (
char *)path;
2729 static inline char *
2732 #if defined(DOSISH_UNC) || defined(DOSISH_DRIVE_LETTER)
2741 #define strrdirsep rb_enc_path_last_separator
2746 while (path < end) {
2748 const char *tmp = path++;
2749 while (path < end &&
isdirsep(*path)) path++;
2750 if (path >= end)
break;
2754 Inc(path, end, enc);
2763 while (path < end) {
2765 const char *
last = path++;
2766 while (path < end &&
isdirsep(*path)) path++;
2767 if (path >= end)
return (
char *)
last;
2770 Inc(path, end, enc);
2773 return (
char *)path;
2779 if (path < end &&
isdirsep(*path)) path++;
2785 ntfs_tail(
const char *path,
const char *end,
rb_encoding *enc)
2787 while (path < end && *path ==
'.') path++;
2788 while (path < end && *path !=
':') {
2790 const char *
last = path++;
2792 if (path >= end || *path ==
':')
return (
char *)
last;
2795 const char *last = path++;
2796 while (path < end &&
isdirsep(*path)) path++;
2797 if (path >= end)
return (
char *)
last;
2798 if (*path ==
':') path++;
2801 Inc(path, end, enc);
2804 return (
char *)path;
2808 #define BUFCHECK(cond) do {\
2811 do {buflen *= 2;} while (cond);\
2812 rb_str_resize(result, buflen);\
2813 buf = RSTRING_PTR(result);\
2815 pend = buf + buflen;\
2819 #define BUFINIT() (\
2820 p = buf = RSTRING_PTR(result),\
2821 buflen = RSTRING_LEN(result),\
2829 #if defined DOSISH || defined __CYGWIN__
2835 if (!user || !*user) {
2836 if (!(dir =
getenv(
"HOME"))) {
2845 struct passwd *pwPtr = getpwnam(user);
2850 dirlen =
strlen(pwPtr->pw_dir);
2852 memcpy(buf =
RSTRING_PTR(result), pwPtr->pw_dir, dirlen + 1);
2860 #if defined DOSISH || defined __CYGWIN__
2861 for (bend = (p = buf) + dirlen; p < bend;
Inc(p, bend, enc)) {
2874 char *
buf, *cwdp = dir;
2879 do {buflen *= 2;}
while (dirlen > buflen);
2882 memcpy(buf, cwdp, dirlen);
2886 return buf + dirlen;
2892 const char *s, *b, *fend;
2893 char *
buf, *
p, *pend, *root;
2894 size_t buflen, bdiff;
2904 if (s[0] ==
'~' && abs_mode == 0) {
2907 if (
isdirsep(s[1]) || s[1] ==
'\0') {
2916 BUFCHECK(bdiff + userlen >= buflen);
2917 memcpy(p, b, userlen);
2936 #ifdef DOSISH_DRIVE_LETTER
2938 else if (has_drive_letter(s)) {
2951 if (!
NIL_P(dname) && !not_same_drive(dname, s[0])) {
2960 char *e =
append_fspath(result, fname, getcwdofdrv(*s), &enc, fsenc);
2975 if (!
NIL_P(dname)) {
2987 #if defined DOSISH || defined __CYGWIN__
3004 memset(buf,
'/', len);
3008 if (p > buf && p[-1] ==
'/')
3031 if (*(s+1) ==
'\0' ||
isdirsep(*(s+1))) {
3050 #if defined DOSISH || defined __CYGWIN__
3075 #if defined DOSISH || defined __CYGWIN__
3079 long rootdiff = root -
buf;
3081 BUFCHECK(bdiff + (s-b+1) >= buflen);
3082 root = buf + rootdiff;
3083 memcpy(++p, b, s-b);
3097 static const char prime[] =
":$DATA";
3098 enum {prime_len =
sizeof(prime) -1};
3100 if (s > b + prime_len &&
strncasecmp(s - prime_len, prime, prime_len) == 0) {
3103 if (*(s - (prime_len+1)) ==
':') {
3106 else if (memchr(b,
':', s - prime_len - b)) {
3113 memcpy(++p, b, s-b);
3117 if (p ==
skiproot(buf, p + !!*p, enc) - 1) p++;
3121 if ((s =
strrdirsep(b = buf, p, enc)) != 0 && !strpbrk(s,
"*?")) {
3126 WIN32_FIND_DATAW wfd;
3129 #ifdef HAVE_CYGWIN_CONV_PATH
3130 char *w32buf =
NULL;
3131 const int flags = CCP_POSIX_TO_WIN_A | CCP_RELATIVE;
3137 int lnk_added = 0, is_symlink = 0;
3143 if (len > 4 &&
STRCASECMP(p + len - 4,
".lnk") != 0) {
3147 path = *buf ? buf :
"/";
3148 #ifdef HAVE_CYGWIN_CONV_PATH
3149 bufsize = cygwin_conv_path(flags, path,
NULL, 0);
3152 if (lnk_added) bufsize += 4;
3154 if (cygwin_conv_path(flags, path, w32buf, bufsize) == 0) {
3160 if (cygwin_conv_to_win32_path(path, w32buf) == 0) {
3164 if (is_symlink && b == w32buf) {
3168 strlcat(w32buf,
".lnk", bufsize);
3184 MultiByteToWideChar(CP_UTF8, 0,
RSTRING_PTR(tmp), -1, wstr, len);
3186 h = FindFirstFileW(wstr, &wfd);
3188 if (h != INVALID_HANDLE_VALUE) {
3191 len = lstrlenW(wfd.cFileName);
3193 if (lnk_added && len > 4 &&
3194 wcscasecmp(wfd.cFileName + len - 4, L
".lnk") == 0) {
3195 wfd.cFileName[len -= 4] = L
'\0';
3202 len = WideCharToMultiByte(CP_UTF8, 0, wfd.cFileName, wlen,
NULL, 0,
NULL,
NULL);
3204 WideCharToMultiByte(CP_UTF8, 0, wfd.cFileName, wlen, p, len + 1,
NULL,
NULL);
3205 if (tmp != result) {
3231 #define EXPAND_PATH_BUFFER() rb_enc_str_new(0, MAXPATHLEN + 2, rb_filesystem_encoding())
3233 #define check_expand_path_args(fname, dname) \
3234 (((fname) = rb_get_path(fname)), \
3235 (void)(NIL_P(dname) ? (dname) : ((dname) = rb_get_path(dname))))
3323 const char *pend = unresolved +
strlen(unresolved);
3327 while (unresolved < pend) {
3328 const char *testname = unresolved;
3330 long testnamelen = unresolved_firstsep - unresolved;
3331 const char *unresolved_nextname = unresolved_firstsep;
3332 while (unresolved_nextname < pend &&
isdirsep(*unresolved_nextname))
3333 unresolved_nextname++;
3334 unresolved = unresolved_nextname;
3335 if (testnamelen == 1 && testname[0] ==
'.') {
3337 else if (testnamelen == 2 && testname[0] ==
'.' && testname[1] ==
'.') {
3339 const char *resolved_str =
RSTRING_PTR(*resolvedp);
3340 const char *resolved_names = resolved_str + *prefixlenp;
3342 long len = lastsep ? lastsep - resolved_names : 0;
3353 if (!
NIL_P(checkval)) {
3354 if (checkval ==
ID2SYM(resolving)) {
3368 if (
errno == ENOENT) {
3369 if (strict || !last || *unresolved_firstsep)
3371 *resolvedp = testpath;
3378 #ifdef HAVE_READLINK
3382 const char *link_prefix, *link_names;
3383 long link_prefixlen;
3385 link = rb_readlink(testpath);
3388 link_prefixlen = link_names - link_prefix;
3389 if (link_prefixlen > 0) {
3396 *prefixlenp = link_prefixlen;
3398 realpath_rec(prefixlenp, resolvedp, link_names, loopcheck, strict, *unresolved_firstsep ==
'\0');
3407 *resolvedp = testpath;
3419 volatile VALUE unresolved_path;
3424 char *path_names =
NULL, *basedir_names =
NULL, *curdir_names =
NULL;
3425 char *ptr, *prefixptr =
NULL, *pend;
3433 if (!
NIL_P(basedir)) {
3440 if (ptr != path_names) {
3441 resolved =
rb_str_subseq(unresolved_path, 0, path_names - ptr);
3445 if (!
NIL_P(basedir)) {
3448 if (ptr != basedir_names) {
3461 pend = prefixptr + prefixlen;
3465 prefixlen = ++ptr - prefixptr;
3468 #ifdef FILE_ALT_SEPARATOR
3469 while (prefixptr < ptr) {
3470 if (*prefixptr == FILE_ALT_SEPARATOR) {
3473 Inc(prefixptr, pend, enc);
3479 realpath_rec(&prefixlen, &resolved, curdir_names, loopcheck, 1, 0);
3481 realpath_rec(&prefixlen, &resolved, basedir_names, loopcheck, 1, 0);
3482 realpath_rec(&prefixlen, &resolved, path_names, loopcheck, strict, 1);
3504 VALUE path, basedir;
3524 VALUE path, basedir;
3534 const char *s, *
last;
3536 if (!e || !l2)
return 0;
3539 if (
rb_enc_ascget(e + len1, e + l2, &len2, enc) ==
'*' && len1 + len2 == l2) {
3540 if (c ==
'.')
return l0;
3550 if (l1 < l2)
return l1;
3554 #if CASEFOLD_FILESYSTEM
3555 #define fncomp strncasecmp
3557 #define fncomp strncmp
3559 if (
fncomp(s, e, l2) == 0) {
3568 const char *
p, *q, *e, *end;
3569 #if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
3574 end = name + *alllen;
3576 #if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
3584 #if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
3588 #ifdef DOSISH_DRIVE_LETTER
3589 else if (*p ==
':') {
3609 n = ntfs_tail(p, end, enc) -
p;
3613 for (q = p; q - p < n && *q ==
'.'; q++);
3614 for (e = 0; q - p < n;
Inc(q, end, enc)) {
3615 if (*q ==
'.') e = q;
3645 VALUE fname, fext, basename;
3646 const char *
name, *
p;
3650 if (
rb_scan_args(argc, argv,
"11", &fname, &fext) == 2) {
3712 const char *
name, *root, *
p, *end;
3722 if (root > name + 1 &&
isdirsep(*name))
3723 root =
skipprefix(name = root - 2, end, enc);
3725 if (root > name + 1)
3734 #ifdef DOSISH_DRIVE_LETTER
3735 if (has_drive_letter(name) &&
isdirsep(*(name + 2))) {
3743 #ifdef DOSISH_DRIVE_LETTER
3744 if (has_drive_letter(name) && root == name + 2 && p - name == 2)
3767 const char *
p, *e, *end = name + (len ? *len : (
long)
strlen(name));
3776 while (*p && *p ==
'.') p++;
3780 const char *last = p++, *dot =
last;
3782 if (*p ==
'.') dot =
p;
3785 if (!*p || *p ==
':') {
3789 if (*last ==
'.' || dot > last) e = dot;
3796 else if (*p ==
':') {
3807 if (!e || e == name)
3834 const char *
name, *e;
3901 const char *
name, *tail;
3923 switch (
TYPE(tmp)) {
3946 else if (!
NIL_P(sep)) {
3978 #if defined(HAVE_TRUNCATE) || defined(HAVE_CHSIZE)
4003 #ifdef HAVE_TRUNCATE
4014 if (chsize(tmpfd, pos) < 0) {
4024 #define rb_file_s_truncate rb_f_notimplement
4027 #if defined(HAVE_FTRUNCATE) || defined(HAVE_CHSIZE)
4055 #ifdef HAVE_FTRUNCATE
4059 if (chsize(fptr->
fd, pos) < 0)
4065 #define rb_file_truncate rb_f_notimplement
4082 #include <winerror.h>
4083 extern unsigned long __attribute__((stdcall)) GetLastError(
void);
4090 int old_errno =
errno;
4092 int *op = data, ret =
flock(op[0], op[1]);
4095 if (GetLastError() == ERROR_NOT_LOCKED) {
4154 op[1] = op1 =
NUM2INT(operation);
4165 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
4174 #if defined(ERESTART)
4195 for (i=1; i<n; i++) {
4196 switch (
TYPE(argv[i])) {
4207 #define CHECK(n) test_check((n), argc, argv)
4275 if (cmd == 0)
goto unknown;
4276 if (
strchr(
"bcdefgGkloOprRsSuwWxXz", cmd)) {
4348 if (
strchr(
"MAC", cmd)) {
4350 VALUE fname = argv[1];
4353 if (
rb_stat(fname, &st) == -1) {
4373 if (
strchr(
"=<>", cmd)) {
4374 struct stat st1, st2;
4382 if (st1.st_mtime == st2.st_mtime)
return Qtrue;
4386 if (st1.st_mtime > st2.st_mtime)
return Qtrue;
4390 if (st1.st_mtime < st2.st_mtime)
return Qtrue;
4438 struct stat st, *nst;
4463 if (copy == orig)
return orig;
4980 if (size == 0)
return Qnil;
5057 #ifdef DOSISH_DRIVE_LETTER
5058 if (has_drive_letter(path) &&
isdirsep(path[2]))
return 1;
5064 if (path[0] ==
'/')
return 1;
5069 #ifndef ENABLE_PATH_CHECK
5070 # if defined DOSISH || defined __CYGWIN__
5071 # define ENABLE_PATH_CHECK 0
5073 # define ENABLE_PATH_CHECK 1
5077 #if ENABLE_PATH_CHECK
5103 # define S_IWOTH 002
5107 && !(p && execpath && (st.st_mode & S_ISVTX))
5110 rb_warn(
"Insecure world writable dir %s in %sPATH, mode 0%"
5111 PRI_MODET_PREFIX
"o",
5112 p0, (execpath ?
"" :
"LOAD_"), st.st_mode);
5119 if (!s || s == p0)
return 1;
5127 #if ENABLE_PATH_CHECK
5128 #define fpath_check(path) path_check_0((path), FALSE)
5130 #define fpath_check(path) 1
5136 #if ENABLE_PATH_CHECK
5137 const char *p0, *
p, *pend;
5140 if (!path)
return 1;
5142 pend = path +
strlen(path);
5152 if (p0 > pend)
break;
5165 int fd = open(path, O_RDONLY);
5166 if (fd == -1)
return 0;
5184 if (*path++ !=
'.')
return 0;
5185 if (*path ==
'.') path++;
5207 VALUE fname = *filep, load_path, tmp;
5211 if (!ext[0])
return 0;
5229 for (i=0; ext[
i]; i++) {
5240 if (safe_level >= 4) {
5245 if (!load_path)
return 0;
5248 RBASIC(fname)->klass = 0;
5252 for (j=0; ext[j]; j++) {
5254 for (i = 0; i <
RARRAY_LEN(load_path); i++) {
5281 VALUE tmp, load_path;
5305 if (safe_level >= 4) {
5315 for (i = 0; i <
RARRAY_LEN(load_path); i++) {
5348 #elif defined AMIGA || defined __amigaos__