summaryrefslogtreecommitdiff
path: root/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'file.c')
-rw-r--r--file.c174
1 files changed, 113 insertions, 61 deletions
diff --git a/file.c b/file.c
index 98098f9047..b246762a8c 100644
--- a/file.c
+++ b/file.c
@@ -67,7 +67,7 @@ char *strrchr _((const char*,const char));
#include <sys/stat.h>
#ifndef HAVE_LSTAT
-#define lstat stat
+#define lstat rb_sys_stat
#endif
VALUE rb_cFile;
@@ -113,7 +113,8 @@ rb_file_path(obj)
#endif
static VALUE
-stat_new(st)
+stat_new_0(klass, st)
+ VALUE klass;
struct stat *st;
{
struct stat *nst;
@@ -121,7 +122,14 @@ stat_new(st)
nst = ALLOC(struct stat);
*nst = *st;
- return Data_Wrap_Struct(rb_cStat, NULL, free, nst);
+ return Data_Wrap_Struct(klass, NULL, free, nst);
+}
+
+static VALUE
+stat_new(st)
+ struct stat *st;
+{
+ return stat_new_0(rb_cStat, st);
}
static struct stat*
@@ -152,42 +160,42 @@ static VALUE
rb_stat_dev(self)
VALUE self;
{
- return INT2FIX((int)get_stat(self)->st_dev);
+ return INT2NUM(get_stat(self)->st_dev);
}
static VALUE
rb_stat_ino(self)
VALUE self;
{
- return INT2FIX((int)get_stat(self)->st_ino);
+ return UINT2NUM(get_stat(self)->st_ino);
}
static VALUE
rb_stat_mode(self)
VALUE self;
{
- return INT2FIX((int)get_stat(self)->st_mode);
+ return UINT2NUM(get_stat(self)->st_mode);
}
static VALUE
rb_stat_nlink(self)
VALUE self;
{
- return INT2FIX((int)get_stat(self)->st_nlink);
+ return UINT2NUM(get_stat(self)->st_nlink);
}
static VALUE
rb_stat_uid(self)
VALUE self;
{
- return INT2FIX((int)get_stat(self)->st_uid);
+ return UINT2NUM(get_stat(self)->st_uid);
}
static VALUE
rb_stat_gid(self)
VALUE self;
{
- return INT2FIX((int)get_stat(self)->st_gid);
+ return UINT2NUM(get_stat(self)->st_gid);
}
static VALUE
@@ -195,7 +203,7 @@ rb_stat_rdev(self)
VALUE self;
{
#ifdef HAVE_ST_RDEV
- return INT2FIX((int)get_stat(self)->st_rdev);
+ return INT2NUM(get_stat(self)->st_rdev);
#else
return INT2FIX(0);
#endif
@@ -205,7 +213,7 @@ static VALUE
rb_stat_size(self)
VALUE self;
{
- return INT2FIX((int)get_stat(self)->st_size);
+ return INT2NUM(get_stat(self)->st_size);
}
static VALUE
@@ -213,7 +221,7 @@ rb_stat_blksize(self)
VALUE self;
{
#ifdef HAVE_ST_BLKSIZE
- return INT2FIX((int)get_stat(self)->st_blksize);
+ return UINT2NUM(get_stat(self)->st_blksize);
#else
return INT2FIX(0);
#endif
@@ -224,7 +232,7 @@ rb_stat_blocks(self)
VALUE self;
{
#ifdef HAVE_ST_BLOCKS
- return INT2FIX((int)get_stat(self)->st_blocks);
+ return UINT2NUM(get_stat(self)->st_blocks);
#else
return INT2FIX(0);
#endif
@@ -314,17 +322,17 @@ rb_stat(file, st)
#if defined DJGPP
if (RSTRING(file)->len == 0) return -1;
#endif
- return stat(RSTRING(file)->ptr, st);
+ return rb_sys_stat(RSTRING(file)->ptr, st);
}
static VALUE
-rb_file_s_stat(obj, fname)
- VALUE obj, fname;
+rb_file_s_stat(klass, fname)
+ VALUE klass, fname;
{
struct stat st;
Check_SafeStr(fname);
- if (stat(RSTRING(fname)->ptr, &st) == -1) {
+ if (rb_sys_stat(RSTRING(fname)->ptr, &st) == -1) {
rb_sys_fail(RSTRING(fname)->ptr);
}
return stat_new(&st);
@@ -345,8 +353,8 @@ rb_io_stat(obj)
}
static VALUE
-rb_file_s_lstat(obj, fname)
- VALUE obj, fname;
+rb_file_s_lstat(klass, fname)
+ VALUE klass, fname;
{
#ifdef HAVE_LSTAT
struct stat st;
@@ -357,7 +365,7 @@ rb_file_s_lstat(obj, fname)
}
return stat_new(&st);
#else
- return rb_file_s_stat(obj, fname);
+ return rb_file_s_stat(klass, fname);
#endif
}
@@ -420,7 +428,7 @@ eaccess(path, mode)
struct stat st;
static int euid = -1;
- if (stat(path, &st) < 0) return (-1);
+ if (rb_sys_stat(path, &st) < 0) return (-1);
if (euid == -1)
euid = geteuid ();
@@ -722,7 +730,7 @@ check3rdbyte(file, mode)
{
struct stat st;
- if (stat(file, &st) < 0) return Qfalse;
+ if (rb_sys_stat(file, &st) < 0) return Qfalse;
if (st.st_mode & mode) return Qtrue;
return Qfalse;
}
@@ -757,15 +765,16 @@ test_sticky(obj, fname)
VALUE obj, fname;
{
#ifdef S_ISVTX
- return check3rdbyte(STR2CSTR(fname), S_ISVTX);
+ Check_SafeStr(fname);
+ return check3rdbyte(RSTRING(fname)->ptr, S_ISVTX);
#else
return Qnil;
#endif
}
static VALUE
-rb_file_s_size(obj, fname)
- VALUE obj, fname;
+rb_file_s_size(klass, fname)
+ VALUE klass, fname;
{
struct stat st;
@@ -815,8 +824,8 @@ rb_file_ftype(st)
}
static VALUE
-rb_file_s_ftype(obj, fname)
- VALUE obj, fname;
+rb_file_s_ftype(klass, fname)
+ VALUE klass, fname;
{
struct stat st;
@@ -829,8 +838,8 @@ rb_file_s_ftype(obj, fname)
}
static VALUE
-rb_file_s_atime(obj, fname)
- VALUE obj, fname;
+rb_file_s_atime(klass, fname)
+ VALUE klass, fname;
{
struct stat st;
@@ -854,8 +863,8 @@ rb_file_atime(obj)
}
static VALUE
-rb_file_s_mtime(obj, fname)
- VALUE obj, fname;
+rb_file_s_mtime(klass, fname)
+ VALUE klass, fname;
{
struct stat st;
@@ -879,8 +888,8 @@ rb_file_mtime(obj)
}
static VALUE
-rb_file_s_ctime(obj, fname)
- VALUE obj, fname;
+rb_file_s_ctime(klass, fname)
+ VALUE klass, fname;
{
struct stat st;
@@ -1097,8 +1106,8 @@ rb_file_s_utime(argc, argv)
#endif
static VALUE
-rb_file_s_link(obj, from, to)
- VALUE obj, from, to;
+rb_file_s_link(klass, from, to)
+ VALUE klass, from, to;
{
Check_SafeStr(from);
Check_SafeStr(to);
@@ -1109,8 +1118,8 @@ rb_file_s_link(obj, from, to)
}
static VALUE
-rb_file_s_symlink(obj, from, to)
- VALUE obj, from, to;
+rb_file_s_symlink(klass, from, to)
+ VALUE klass, from, to;
{
#ifdef HAVE_SYMLINK
Check_SafeStr(from);
@@ -1126,8 +1135,8 @@ rb_file_s_symlink(obj, from, to)
}
static VALUE
-rb_file_s_readlink(obj, path)
- VALUE obj, path;
+rb_file_s_readlink(klass, path)
+ VALUE klass, path;
{
#ifdef HAVE_READLINK
char buf[MAXPATHLEN];
@@ -1154,24 +1163,30 @@ unlink_internal(path)
}
static VALUE
-rb_file_s_unlink(obj, args)
- VALUE obj, args;
+rb_file_s_unlink(klass, args)
+ VALUE klass, args;
{
int n;
+ rb_secure(2);
n = apply2files(unlink_internal, args, 0);
return INT2FIX(n);
}
static VALUE
-rb_file_s_rename(obj, from, to)
- VALUE obj, from, to;
+rb_file_s_rename(klass, from, to)
+ VALUE klass, from, to;
{
Check_SafeStr(from);
Check_SafeStr(to);
- if (rename(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0)
+ if (rename(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0) {
+#if defined __CYGWIN__
+ extern unsigned long __attribute__((stdcall)) GetLastError();
+ errno = GetLastError(); /* This is a Cygwin bug */
+#endif
rb_sys_fail(RSTRING(from)->ptr);
+ }
return INT2FIX(0);
}
@@ -1253,7 +1268,7 @@ rb_file_s_expand_path(argc, argv)
}
#if defined DOSISH
/* skip drive letter */
- else if (isalpha(s[0]) && s[1] == ':' && isdirsep(s[2])) {
+ else if (ISALPHA(s[0]) && s[1] == ':' && isdirsep(s[2])) {
while (*s && !isdirsep(*s)) {
*p++ = *s++;
}
@@ -1388,8 +1403,8 @@ rb_file_s_basename(argc, argv)
}
static VALUE
-rb_file_s_dirname(obj, fname)
- VALUE obj, fname;
+rb_file_s_dirname(klass, fname)
+ VALUE klass, fname;
{
char *name, *p;
VALUE dirname;
@@ -1407,8 +1422,8 @@ rb_file_s_dirname(obj, fname)
}
static VALUE
-rb_file_s_split(obj, path)
- VALUE obj, path;
+rb_file_s_split(klass, path)
+ VALUE klass, path;
{
return rb_assoc_new(rb_file_s_dirname(Qnil, path), rb_file_s_basename(1,&path));
}
@@ -1416,15 +1431,15 @@ rb_file_s_split(obj, path)
static VALUE separator;
static VALUE
-rb_file_s_join(obj, args)
- VALUE obj, args;
+rb_file_s_join(klass, args)
+ VALUE klass, args;
{
return rb_ary_join(args, separator);
}
static VALUE
-rb_file_s_truncate(obj, path, len)
- VALUE obj, path, len;
+rb_file_s_truncate(klass, path, len)
+ VALUE klass, path, len;
{
rb_secure(2);
Check_SafeStr(path);
@@ -1509,11 +1524,14 @@ rb_thread_flock(fd, op, fptr)
op |= LOCK_NB;
while (flock(fd, op) < 0) {
switch (errno) {
- case EINTR: /* can be happen? */
+ case EAGAIN:
+ case EACCES:
+#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
+#endif
rb_thread_polling(); /* busy wait */
rb_io_check_closed(fptr);
- break;
+ continue;
default:
return -1;
}
@@ -1542,11 +1560,14 @@ rb_file_flock(obj, operation)
ret = flock(fileno(fptr->f), NUM2INT(operation));
TRAP_END;
if (ret < 0) {
-#ifdef EWOULDBLOCK
- if (errno == EWOULDBLOCK) {
- return Qfalse;
- }
+ switch (errno) {
+ case EAGAIN:
+ case EACCES:
+#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
+ case EWOULDBLOCK:
#endif
+ return Qfalse;
+ }
rb_sys_fail(fptr->path);
}
#endif
@@ -1716,6 +1737,30 @@ rb_f_test(argc, argv)
}
static VALUE
+rb_stat_s_new(klass, fname)
+ VALUE klass, fname;
+{
+ VALUE s;
+ struct stat st;
+
+ Check_SafeStr(fname);
+ if (rb_sys_stat(RSTRING(fname)->ptr, &st) == -1) {
+ rb_sys_fail(RSTRING(fname)->ptr);
+ }
+ s = stat_new_0(klass, &st);
+ rb_obj_call_init(s, 1, &fname);
+ return s;
+}
+
+static VALUE
+rb_stat_init(klass, fname)
+ VALUE klass, fname;
+{
+ /* do nothing */
+ return Qnil;
+}
+
+static VALUE
rb_stat_ftype(obj)
VALUE obj;
{
@@ -2029,6 +2074,7 @@ path_check_1(path)
}
for (;;) {
if (stat(path, &st) == 0 && (st.st_mode & 002)) {
+ if (p) *p = '/';
return 0;
}
s = strrchr(path, '/');
@@ -2056,7 +2102,10 @@ rb_path_check(path)
if (pend) *pend = '\0';
safe = path_check_1(p);
- if (!safe) return 0;
+ if (!safe) {
+ if (pend) *pend = sep;
+ return 0;
+ }
if (!pend) break;
*pend = sep;
p = pend + 1;
@@ -2089,7 +2138,7 @@ rb_find_file(file)
if (is_macos_native_path(file)) {
FILE *f;
- if (safe_level >= 2 && !rb_path_check(file)) {
+ if (rb_safe_level() >= 2 && !rb_path_check(file)) {
rb_raise(rb_eSecurityError, "loading from unsafe file %s", file);
}
f= fopen(file, "r");
@@ -2159,6 +2208,7 @@ define_filetest_function(name, func, argc)
rb_define_singleton_method(rb_cFile, name, func, argc);
}
+void
Init_File()
{
rb_mFileTest = rb_define_module("FileTest");
@@ -2254,6 +2304,8 @@ Init_File()
rb_define_global_function("test", rb_f_test, -1);
rb_cStat = rb_define_class_under(rb_cFile, "Stat", rb_cObject);
+ rb_define_singleton_method(rb_cStat, "new", rb_stat_s_new, 1);
+ rb_define_method(rb_cStat, "initialize", rb_stat_init, 1);
rb_include_module(rb_cStat, rb_mComparable);