From da99e407fbf36051bf9ebce01418589bff557298 Mon Sep 17 00:00:00 2001 From: dave Date: Sun, 21 Dec 2003 07:28:54 +0000 Subject: Add file.c comments (and necessary support in parse_c.rb) git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5234 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- file.c | 1182 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1182 insertions(+) (limited to 'file.c') diff --git a/file.c b/file.c index 12adcdab87..f4165b35e0 100644 --- a/file.c +++ b/file.c @@ -91,6 +91,18 @@ apply2files(func, vargs, arg) return args->len; } +/* + * call-seq: + * file.path -> file_ame + * + * Returns the pathname used to create file as a string. Does + * not normalize the name. + * + * File.new("testfile").path #=> "testfile" + * File.new("/tmp/../tmp/xxx", "w").path #=> "/tmp/../tmp/xxx" + * + */ + static VALUE rb_file_path(obj) VALUE obj; @@ -133,6 +145,19 @@ get_stat(self) return st; } +/* + * call-seq: + * stat <=> other_stat => -1, 0, 1 + * + * Compares File::Stat objects by comparing their + * respective modification times. + * + * f1 = File.new("f1", "w") + * sleep 1 + * f2 = File.new("f2", "w") + * f1.stat <=> f2.stat #=> -1 + */ + static VALUE rb_stat_cmp(self, other) VALUE self, other; @@ -150,6 +175,16 @@ rb_stat_cmp(self, other) return Qnil; } +/* + * call-seq: + * stat.dev => fixnum + * + * Returns an integer representing the device on which stat + * resides. + * + * File.stat("testfile").dev #=> 774 + */ + static VALUE rb_stat_dev(self) VALUE self; @@ -157,6 +192,17 @@ rb_stat_dev(self) return INT2NUM(get_stat(self)->st_dev); } + +/* + * call-seq: + * stat.ino => fixnum + * + * Returns the inode number for stat. + * + * File.stat("testfile").ino #=> 1083669 + * + */ + static VALUE rb_stat_ino(self) VALUE self; @@ -168,6 +214,19 @@ rb_stat_ino(self) #endif } +/* + * call-seq: + * stat.mode => fixnum + * + * Returns an integer representing the permission bits of + * stat. The meaning of the bits is platform dependent; on + * Unix systems, see stat(2). + * + * File.chmod(0644, "testfile") #=> 1 + * s = File.stat("testfile") + * sprintf("%o", s.mode) #=> "100644" + */ + static VALUE rb_stat_mode(self) VALUE self; @@ -179,6 +238,18 @@ rb_stat_mode(self) #endif } +/* + * call-seq: + * stat.nlink => fixnum + * + * Returns the number of hard links to stat. + * + * File.stat("testfile").nlink #=> 1 + * File.link("testfile", "testfile.bak") #=> 0 + * File.stat("testfile").nlink #=> 2 + * + */ + static VALUE rb_stat_nlink(self) VALUE self; @@ -186,6 +257,17 @@ rb_stat_nlink(self) return UINT2NUM(get_stat(self)->st_nlink); } + +/* + * call-seq: + * stat.uid => fixnum + * + * Returns the numeric user id of the owner of stat. + * + * File.stat("testfile").uid #=> 501 + * + */ + static VALUE rb_stat_uid(self) VALUE self; @@ -193,6 +275,16 @@ rb_stat_uid(self) return UINT2NUM(get_stat(self)->st_uid); } +/* + * call-seq: + * stat.gid => fixnum + * + * Returns the numeric group id of the owner of stat. + * + * File.stat("testfile").gid #=> 500 + * + */ + static VALUE rb_stat_gid(self) VALUE self; @@ -200,6 +292,19 @@ rb_stat_gid(self) return UINT2NUM(get_stat(self)->st_gid); } + +/* + * call-seq: + * stat.rdev => fixnum or nil + * + * Returns an integer representing the device type on which + * stat resides. Returns nil if the operating + * system doesn't support this feature. + * + * File.stat("/dev/fd1").rdev #=> 513 + * File.stat("/dev/tty").rdev #=> 1280 + */ + static VALUE rb_stat_rdev(self) VALUE self; @@ -211,6 +316,17 @@ rb_stat_rdev(self) #endif } +/* + * call-seq: + * stat.rdev_major => fixnum + * + * Returns the major part of File_Stat#rdev or + * nil. + * + * File.stat("/dev/fd1").rdev_major #=> 2 + * File.stat("/dev/tty").rdev_major #=> 5 + */ + static VALUE rb_stat_rdev_major(self) VALUE self; @@ -223,6 +339,17 @@ rb_stat_rdev_major(self) #endif } +/* + * call-seq: + * stat.rdev_minor => fixnum + * + * Returns the minor part of File_Stat#rdev or + * nil. + * + * File.stat("/dev/fd1").rdev_minor #=> 1 + * File.stat("/dev/tty").rdev_minor #=> 0 + */ + static VALUE rb_stat_rdev_minor(self) VALUE self; @@ -235,6 +362,15 @@ rb_stat_rdev_minor(self) #endif } +/* + * call-seq: + * stat.size => fixnum + * + * Returns the size of stat in bytes. + * + * File.stat("testfile").size #=> 66 + */ + static VALUE rb_stat_size(self) VALUE self; @@ -242,6 +378,17 @@ rb_stat_size(self) return OFFT2NUM(get_stat(self)->st_size); } +/* + * call-seq: + * stat.blksize => integer or nil + * + * Returns the native file system's block size. Will return nil + * on platforms that don't support this information. + * + * File.stat("testfile").blksize #=> 4096 + * + */ + static VALUE rb_stat_blksize(self) VALUE self; @@ -253,6 +400,17 @@ rb_stat_blksize(self) #endif } +/* + * call-seq: + * stat.blocks => integer or nil + * + * Returns the number of native file system blocks allocated for this + * file, or nil if the operating system doesn't + * support this feature. + * + * File.stat("testfile").blocks #=> 2 + */ + static VALUE rb_stat_blocks(self) VALUE self; @@ -264,6 +422,18 @@ rb_stat_blocks(self) #endif } + +/* + * call-seq: + * stat.atime => time + * + * Returns the last access time for this file as an object of class + * Time. + * + * File.stat("testfile").atime #=> Wed Dec 31 18:00:00 CST 1969 + * + */ + static VALUE rb_stat_atime(self) VALUE self; @@ -271,6 +441,16 @@ rb_stat_atime(self) return rb_time_new(get_stat(self)->st_atime, 0); } +/* + * call-seq: + * stat.mtime -> aTime + * + * Returns the modification time of stat. + * + * File.stat("testfile").mtime #=> Wed Apr 09 08:53:14 CDT 2003 + * + */ + static VALUE rb_stat_mtime(self) VALUE self; @@ -278,6 +458,18 @@ rb_stat_mtime(self) return rb_time_new(get_stat(self)->st_mtime, 0); } +/* + * call-seq: + * stat.ctime -> aTime + * + * Returns the change time for stat (that is, the time + * directory information about the file was changed, not the file + * itself). + * + * File.stat("testfile").ctime #=> Wed Apr 09 08:53:14 CDT 2003 + * + */ + static VALUE rb_stat_ctime(self) VALUE self; @@ -285,6 +477,20 @@ rb_stat_ctime(self) return rb_time_new(get_stat(self)->st_ctime, 0); } +/* + * call-seq: + * stat.inspect => string + * + * Produce a nicely formatted descriptin of stat. + * + * File.stat("/etc/passwd").inspect + * #=> "#" + */ + static VALUE rb_stat_inspect(self) VALUE self; @@ -364,6 +570,17 @@ rb_stat(file, st) return stat(StringValueCStr(file), st); } +/* + * call-seq: + * File.stat(file_name) => stat + * + * Returns a File::Stat object for the named file (see + * File::Stat). + * + * File.stat("testfile").mtime #=> Tue Apr 08 12:58:04 CDT 2003 + * + */ + static VALUE rb_file_s_stat(klass, fname) VALUE klass, fname; @@ -377,6 +594,21 @@ rb_file_s_stat(klass, fname) return stat_new(&st); } +/* + * call-seq: + * ios.stat => stat + * + * Returns status information for ios as an object of type + * File::Stat. + * + * f = File.new("testfile") + * s = f.stat + * "%o" % s.mode #=> "100644" + * s.blksize #=> 4096 + * s.atime #=> Wed Apr 09 08:53:54 CDT 2003 + * + */ + static VALUE rb_io_stat(obj) VALUE obj; @@ -391,6 +623,20 @@ rb_io_stat(obj) return stat_new(&st); } +/* + * call-seq: + * File.lstat(file_name) => stat + * + * Same as File::stat, but does not follow the last symbolic + * link. Instead, reports on the link itself. + * + * File.symlink("testfile", "link2test") #=> 0 + * File.stat("testfile").size #=> 66 + * File.lstat("link2test").size #=> 8 + * File.stat("link2test").size #=> 66 + * + */ + static VALUE rb_file_s_lstat(klass, fname) VALUE klass, fname; @@ -408,6 +654,21 @@ rb_file_s_lstat(klass, fname) #endif } + +/* + * call-seq: + * file.lstat => stat + * + * Same as IO#stat, but does not follow the last symbolic + * link. Instead, reports on the link itself. + * + * File.symlink("testfile", "link2test") #=> 0 + * File.stat("testfile").size #=> 66 + * f = File.new("link2test") + * f.lstat.size #=> 8 + * f.stat.size #=> 66 + */ + static VALUE rb_file_lstat(obj) VALUE obj; @@ -501,6 +762,28 @@ eaccess(path, mode) #endif } + +/* + * Document-class: FileTest + * + * FileTest implements file test operations similar to + * those used in File::Stat. It exists as a standalone + * module, and its methods are also insinuated into the File + * class. (Note that this is not done by inclusion: the interpreter cheats). + * + */ + + +/* + * call-seq: + * File.directory?(file_name) => true or false + * + * Returns true if the named file is a directory, + * false otherwise. + * + * File.directory?(".") + */ + static VALUE test_d(obj, fname) VALUE obj, fname; @@ -516,6 +799,13 @@ test_d(obj, fname) return Qfalse; } +/* + * call-seq: + * File.pipe?(file_name) => true or false + * + * Returns true if the named file is a pipe. + */ + static VALUE test_p(obj, fname) VALUE obj, fname; @@ -534,6 +824,13 @@ test_p(obj, fname) return Qfalse; } +/* + * call-seq: + * File.pipe?(file_name) => true or false + * + * Returns true if the named file is a symbolic link. + */ + static VALUE test_l(obj, fname) VALUE obj, fname; @@ -571,6 +868,13 @@ test_l(obj, fname) return Qfalse; } +/* + * call-seq: + * File.pipe?(file_name) => true or false + * + * Returns true if the named file is a socket. + */ + static VALUE test_S(obj, fname) VALUE obj, fname; @@ -607,6 +911,13 @@ test_S(obj, fname) return Qfalse; } +/* + * call-seq: + * File.pipe?(file_name) => true or false + * + * Returns true if the named file is a block device. + */ + static VALUE test_b(obj, fname) VALUE obj, fname; @@ -629,6 +940,12 @@ test_b(obj, fname) return Qfalse; } +/* + * call-seq: + * File.pipe?(file_name) => true or false + * + * Returns true if the named file is a character device. + */ static VALUE test_c(obj, fname) VALUE obj, fname; @@ -645,6 +962,15 @@ test_c(obj, fname) return Qfalse; } + +/* + * call-seq: + * File.exist?(file_name) => true or false + * File.exists?(file_name) => true or false (obsolete) + * + * Return true if the named file exists. + */ + static VALUE test_e(obj, fname) VALUE obj, fname; @@ -655,6 +981,14 @@ test_e(obj, fname) return Qtrue; } +/* + * call-seq: + * File.readable?(file_name) => true or false + * + * Returns true if the named file is readable by the effective + * user id of this process. + */ + static VALUE test_r(obj, fname) VALUE obj, fname; @@ -664,6 +998,14 @@ test_r(obj, fname) return Qtrue; } +/* + * call-seq: + * File.readable_real?(file_name) => true or false + * + * Returns true if the named file is readable by the real + * user id of this process. + */ + static VALUE test_R(obj, fname) VALUE obj, fname; @@ -673,6 +1015,15 @@ test_R(obj, fname) return Qtrue; } + +/* + * call-seq: + * File.writable?(file_name) => true or false + * + * Returns true if the named file is writable by the effective + * user id of this process. + */ + static VALUE test_w(obj, fname) VALUE obj, fname; @@ -682,6 +1033,14 @@ test_w(obj, fname) return Qtrue; } +/* + * call-seq: + * File.writable_real?(file_name) => true or false + * + * Returns true if the named file is writable by the real + * user id of this process. + */ + static VALUE test_W(obj, fname) VALUE obj, fname; @@ -691,6 +1050,14 @@ test_W(obj, fname) return Qtrue; } +/* + * call-seq: + * File.executable?(file_name) => true or false + * + * Returns true if the named file is executable by the effective + * user id of this process. + */ + static VALUE test_x(obj, fname) VALUE obj, fname; @@ -700,6 +1067,14 @@ test_x(obj, fname) return Qtrue; } +/* + * call-seq: + * File.executable_real?(file_name) => true or false + * + * Returns true if the named file is executable by the real + * user id of this process. + */ + static VALUE test_X(obj, fname) VALUE obj, fname; @@ -713,6 +1088,14 @@ test_X(obj, fname) # define S_ISREG(m) ((m & S_IFMT) == S_IFREG) #endif +/* + * call-seq: + * File.file?(file_name) => true or false + * + * Returns true if the named file exists and is a + * regular file. + */ + static VALUE test_f(obj, fname) VALUE obj, fname; @@ -724,6 +1107,14 @@ test_f(obj, fname) return Qfalse; } +/* + * call-seq: + * File.zero?(file_name) => true or false + * + * Returns true if the named file exists and has + * a zero size. + */ + static VALUE test_z(obj, fname) VALUE obj, fname; @@ -735,6 +1126,14 @@ test_z(obj, fname) return Qfalse; } +/* + * call-seq: + * File.file?(file_name) => integer or nil + * + * Returns nil if file_name doesn't + * exist or has zero size, the size of the file otherwise. + */ + static VALUE test_s(obj, fname) VALUE obj, fname; @@ -746,6 +1145,15 @@ test_s(obj, fname) return OFFT2NUM(st.st_size); } +/* + * call-seq: + * File.owned?(file_name) => true or false + * + * Returns true if the named file exists and the + * effective used id of the calling process is the owner of + * the file. + */ + static VALUE test_owned(obj, fname) VALUE obj, fname; @@ -768,6 +1176,15 @@ test_rowned(obj, fname) return Qfalse; } +/* + * call-seq: + * File.grpowned?(file_name) => true or false + * + * Returns true if the named file exists and the + * effective group id of the calling process is the owner of + * the file. Returns false on Windows. + */ + static VALUE test_grpowned(obj, fname) VALUE obj, fname; @@ -796,6 +1213,13 @@ check3rdbyte(fname, mode) } #endif +/* + * call-seq: + * File.pipe?(file_name) => true or false + * + * Returns true if the named file is a has the setuid bit set. + */ + static VALUE test_suid(obj, fname) VALUE obj, fname; @@ -807,6 +1231,13 @@ test_suid(obj, fname) #endif } +/* + * call-seq: + * File.pipe?(file_name) => true or false + * + * Returns true if the named file is a has the setgid bit set. + */ + static VALUE test_sgid(obj, fname) VALUE obj, fname; @@ -818,6 +1249,13 @@ test_sgid(obj, fname) #endif } +/* + * call-seq: + * File.pipe?(file_name) => true or false + * + * Returns true if the named file is a has the sticky bit set. + */ + static VALUE test_sticky(obj, fname) VALUE obj, fname; @@ -829,6 +1267,13 @@ test_sticky(obj, fname) #endif } +/* + * call-seq: + * File.size(file_name) => integer + * + * Returns the size of file_name. + */ + static VALUE rb_file_s_size(klass, fname) VALUE klass, fname; @@ -882,6 +1327,21 @@ rb_file_ftype(st) return rb_str_new2(t); } +/* + * call-seq: + * File.ftype(file_name) => string + * + * Identifies the type of the named file; the return string is one of + * ``file'', ``directory'', + * ``characterSpecial'', ``blockSpecial'', + * ``fifo'', ``link'', + * ``socket'', or ``unknown''. + * + * File.ftype("testfile") #=> "file" + * File.ftype("/dev/tty") #=> "characterSpecial" + * File.ftype("/tmp/.X11-unix/X0") #=> "socket" + */ + static VALUE rb_file_s_ftype(klass, fname) VALUE klass, fname; @@ -896,6 +1356,16 @@ rb_file_s_ftype(klass, fname) return rb_file_ftype(&st); } +/* + * call-seq: + * File.atime(file_name) => time + * + * Returns the last access time for the named file as a Time object). + * + * File.atime("testfile") #=> Wed Apr 09 08:51:48 CDT 2003 + * + */ + static VALUE rb_file_s_atime(klass, fname) VALUE klass, fname; @@ -907,6 +1377,17 @@ rb_file_s_atime(klass, fname) return rb_time_new(st.st_atime, 0); } +/* + * call-seq: + * file.atime => time + * + * Returns the last access time (a Time object) + * for file, or epoch if file has not been accessed. + * + * File.new("testfile").atime #=> Wed Dec 31 18:00:00 CST 1969 + * + */ + static VALUE rb_file_atime(obj) VALUE obj; @@ -921,6 +1402,16 @@ rb_file_atime(obj) return rb_time_new(st.st_atime, 0); } +/* + * call-seq: + * File.mtime(file_name) => time + * + * Returns the modification time for the named file as a Time object. + * + * File.mtime("testfile") #=> Tue Apr 08 12:58:04 CDT 2003 + * + */ + static VALUE rb_file_s_mtime(klass, fname) VALUE klass, fname; @@ -932,6 +1423,16 @@ rb_file_s_mtime(klass, fname) return rb_time_new(st.st_mtime, 0); } +/* + * call-seq: + * file.mtime -> time + * + * Returns the modification time for file. + * + * File.new("testfile").mtime #=> Wed Apr 09 08:53:14 CDT 2003 + * + */ + static VALUE rb_file_mtime(obj) VALUE obj; @@ -946,6 +1447,18 @@ rb_file_mtime(obj) return rb_time_new(st.st_mtime, 0); } +/* + * call-seq: + * File.ctime(file_name) => time + * + * Returns the change time for the named file (the time at which + * directory information about the file was changed, not the file + * itself). + * + * File.ctime("testfile") #=> Wed Apr 09 08:53:13 CDT 2003 + * + */ + static VALUE rb_file_s_ctime(klass, fname) VALUE klass, fname; @@ -957,6 +1470,17 @@ rb_file_s_ctime(klass, fname) return rb_time_new(st.st_ctime, 0); } +/* + * call-seq: + * file.ctime -> time + * + * Returns the change time for file (that is, the time directory + * information about the file was changed, not the file itself). + * + * File.new("testfile").ctime #=> Wed Apr 09 08:53:14 CDT 2003 + * + */ + static VALUE rb_file_ctime(obj) VALUE obj; @@ -980,6 +1504,19 @@ chmod_internal(path, mode) rb_sys_fail(path); } +/* + * call-seq: + * File.chmod(mode_int, file_name, ... ) -> integer + * + * Changes permission bits on the named file(s) to the bit pattern + * represented by mode_int. Actual effects are operating system + * dependent (see the beginning of this section). On Unix systems, see + * chmod(2) for details. Returns the number of files + * processed. + * + * File.chmod(0644, "testfile", "out") #=> 2 + */ + static VALUE rb_file_s_chmod(argc, argv) int argc; @@ -998,6 +1535,19 @@ rb_file_s_chmod(argc, argv) return LONG2FIX(n); } +/* + * call-seq: + * file.chmod(mode_int) => 0 + * + * Changes permission bits on file to the bit pattern + * represented by mode_int. Actual effects are platform + * dependent; on Unix systems, see chmod(2) for details. + * Follows symbolic links. Also see File#lchmod. + * + * f = File.new("out", "w"); + * f.chmod(0644) #=> 0 + */ + static VALUE rb_file_chmod(obj, vmode) VALUE obj, vmode; @@ -1031,6 +1581,16 @@ lchmod_internal(path, mode) rb_sys_fail(path); } +/* + * call-seq: + * File.lchmod(mode_int, file_name, ...) => integer + * + * Equivalent to File::chmod, but does not follow symbolic + * links (so it will change the permissions associated with the link, + * not the file referenced by the link). Often not available. + * + */ + static VALUE rb_file_s_lchmod(argc, argv) int argc; @@ -1072,6 +1632,21 @@ chown_internal(path, args) rb_sys_fail(path); } +/* + * call-seq: + * File.chown(owner_int, group_int, file_name,... ) -> integer + * + * Changes the owner and group of the named file(s) to the given + * numeric owner and group id's. Only a process with superuser + * privileges may change the owner of a file. The current owner of a + * file may change the file's group to any group to which the owner + * belongs. A nil or -1 owner or group id is ignored. + * Returns the number of files processed. + * + * File.chown(nil, 100, "testfile") + * + */ + static VALUE rb_file_s_chown(argc, argv) int argc; @@ -1100,6 +1675,21 @@ rb_file_s_chown(argc, argv) return LONG2FIX(n); } +/* + * call-seq: + * file.chown(owner_int, group_int ) => 0 + * + * Changes the owner and group of file to the given numeric + * owner and group id's. Only a process with superuser privileges may + * change the owner of a file. The current owner of a file may change + * the file's group to any group to which the owner belongs. A + * nil or -1 owner or group id is ignored. Follows + * symbolic links. See also File#lchown. + * + * File.new("testfile").chown(502, 1000) + * + */ + static VALUE rb_file_chown(obj, owner, group) VALUE obj, owner, group; @@ -1130,6 +1720,18 @@ lchown_internal(path, args) rb_sys_fail(path); } + +/* + * call-seq: + * file.lchown(owner_int, group_int, file_name,..) => integer + * + * Equivalent to File::chown, but does not follow symbolic + * links (so it will change the owner associated with the link, not the + * file referenced by the link). Often not available. Returns number + * of files in the argument list. + * + */ + static VALUE rb_file_s_lchown(argc, argv) int argc; @@ -1180,6 +1782,15 @@ utime_internal(path, tvp) rb_sys_fail(path); } +/* + * call-seq: + * File.utime(atime, mtime, file_name,...) => integer + * + * Sets the access and modification times of each + * named file to the first two arguments. Returns + * the number of file names in the argument list. + */ + static VALUE rb_file_s_utime(argc, argv) int argc; @@ -1253,6 +1864,18 @@ sys_fail2(s1, s2) rb_sys_fail(buf); } +/* + * call-seq: + * File.link(old_name, new_name) => 0 + * + * Creates a new name for an existing file using a hard link. Will not + * overwrite new_name if it already exists (raising a subclass + * of SystemCallError). Not available on all platforms. + * + * File.link("testfile", ".testfile") #=> 0 + * IO.readlines(".testfile")[0] #=> "This is line one\n" + */ + static VALUE rb_file_s_link(klass, from, to) VALUE klass, from, to; @@ -1266,6 +1889,18 @@ rb_file_s_link(klass, from, to) return INT2FIX(0); } +/* + * call-seq: + * File.symlink(old_name, new_name) => 0 + * + * Creates a symbolic link called new_name for the existing file + * old_name. Raises a NotImplemented exception on + * platforms that do not support symbolic links. + * + * File.symlink("testfile", "link2test") #=> 0 + * + */ + static VALUE rb_file_s_symlink(klass, from, to) VALUE klass, from, to; @@ -1284,6 +1919,17 @@ rb_file_s_symlink(klass, from, to) #endif } +/* + * call-seq: + * File.readlink(link_name) -> file_name + * + * Returns the name of the file referenced by the given link. + * Not available on all platforms. + * + * File.symlink("testfile", "link2test") #=> 0 + * File.readlink("link2test") #=> "testfile" + */ + static VALUE rb_file_s_readlink(klass, path) VALUE klass, path; @@ -1322,6 +1968,16 @@ unlink_internal(path) rb_sys_fail(path); } +/* + * call-seq: + * File.delete(file_name, ...) => integer + * File.unlink(file_name, ...) => integer + * + * Deletes the named files, returning the number of names + * passed as arguments. Raises an exception on any error. + * See also Dir::rmdir. + */ + static VALUE rb_file_s_unlink(klass, args) VALUE klass, args; @@ -1333,6 +1989,16 @@ rb_file_s_unlink(klass, args) return LONG2FIX(n); } +/* + * call-seq: + * File.rename(old_name, new_name) => 0 + * + * Renames the given file to the new name. Raises a + * SystemCallError if the file cannot be renamed. + * + * File.rename("afile", "afile.bak") #=> 0 + */ + static VALUE rb_file_s_rename(klass, from, to) VALUE klass, from, to; @@ -1365,6 +2031,21 @@ rb_file_s_rename(klass, from, to) return INT2FIX(0); } +/* + * call-seq: + * File.umask() => integer + * File.umask(integer) => integer + * + * Returns the current umask value for this process. If the optional + * argument is given, set the umask to that value and return the + * previous value. Umask values are subtracted from the + * default permissions, so a umask of 0222 would make a + * file read-only for everyone. + * + * File.umask(0006) #=> 18 + * File.umask #=> 6 + */ + static VALUE rb_file_s_umask(argc, argv) int argc; @@ -1758,6 +2439,23 @@ rb_file_expand_path(fname, dname) return file_expand_path(fname, dname, rb_str_new(0, MAXPATHLEN + 2)); } +/* + * call-seq: + * File.expand_path(file_name [, dir_string] ) -> abs_file_name + * + * Converts a pathname to an absolute pathname. Relative paths are + * referenced from the current working directory of the process unless + * dir_string is given, in which case it will be used as the + * starting point. The given pathname may start with a + * ``~'', which expands to the process owner's home + * directory (the environment variable HOME must be set + * correctly). ``~user'' expands to the named + * user's home directory. + * + * File.expand_path("~oracle/bin") #=> "/home/oracle/bin" + * File.expand_path("../../bin", "/tmp/x") #=> "/bin" + */ + VALUE rb_file_s_expand_path(argc, argv) int argc; @@ -1796,6 +2494,20 @@ rmext(p, e) return 0; } +/* + * call-seq: + * File.basename(file_name [, suffix] ) -> base_name + * + * Returns the last component of the filename given in file_name, + * which must be formed using forward slashes (``/'') + * regardless of the separator used on the local file system. If + * suffix is given and present at the end of file_name, + * it is removed. + * + * File.basename("/home/gumby/work/ruby.rb") #=> "ruby.rb" + * File.basename("/home/gumby/work/ruby.rb", ".rb") #=> "ruby" + */ + static VALUE rb_file_s_basename(argc, argv) int argc; @@ -1839,6 +2551,18 @@ rb_file_s_basename(argc, argv) return basename; } +/* + * call-seq: + * File.dirname(file_name ) -> dir_name + * + * Returns all components of the filename given in file_name + * except the last one. The filename must be formed using forward + * slashes (``/'') regardless of the separator used on the + * local file system. + * + * File.dirname("/home/gumby/work/ruby.rb") #=> "/home/gumby/work" + */ + static VALUE rb_file_s_dirname(klass, fname) VALUE klass, fname; @@ -1870,6 +2594,20 @@ rb_file_s_dirname(klass, fname) return dirname; } +/* + * call-seq: + * File.extname(path) -> string + * + * Returns the extension (the portion of file name in path + * after the period). + * + * File.extname("test.rb") #=> ".rb" + * File.extname("a/b/d/test.rb") #=> ".rb" + * File.extname("test") #=> "" + * File.extname(".profile") #=> "" + * + */ + static VALUE rb_file_s_extname(klass, fname) VALUE klass, fname; @@ -1892,6 +2630,17 @@ rb_file_s_extname(klass, fname) return extname; } +/* + * call-seq: + * File.split(file_name) => array + * + * Splits the given string into a directory and a file component and + * returns them in a two-element array. See also + * File::dirname and File::basename. + * + * File.split("/home/gumby/.profile") #=> ["/home/gumby", ".profile"] + */ + static VALUE rb_file_s_split(klass, path) VALUE klass, path; @@ -1969,6 +2718,17 @@ rb_file_join(ary, sep) return result; } +/* + * call-seq: + * File.join(string, ...) -> path + * + * Returns a new string formed by joining the strings using + * File::SEPARATOR. + * + * File.join("usr", "mail", "gumby") #=> "usr/mail/gumby" + * + */ + static VALUE rb_file_s_join(klass, args) VALUE klass, args; @@ -1976,6 +2736,21 @@ rb_file_s_join(klass, args) return rb_file_join(args, separator); } +/* + * call-seq: + * File.truncate(file_name, integer) => 0 + * + * Truncates the file file_name to be at most integer + * bytes long. Not available on all platforms. + * + * f = File.new("out", "w") + * f.write("1234567890") #=> 10 + * f.close #=> nil + * File.truncate("out", 5) #=> 0 + * File.size("out") #=> 5 + * + */ + static VALUE rb_file_s_truncate(klass, path, len) VALUE klass, path, len; @@ -2013,6 +2788,20 @@ rb_file_s_truncate(klass, path, len) return INT2FIX(0); } +/* + * call-seq: + * file.truncate(integer) => 0 + * + * Truncates file to at most integer bytes. The file + * must be opened for writing. Not available on all platforms. + * + * f = File.new("out", "w") + * f.syswrite("1234567890") #=> 10 + * f.truncate(5) #=> 0 + * f.close() #=> nil + * File.size("out") #=> 5 + */ + static VALUE rb_file_truncate(obj, len) VALUE obj, len; @@ -2080,6 +2869,35 @@ rb_thread_flock(fd, op, fptr) #define flock(fd, op) rb_thread_flock(fd, op, fptr) #endif +/* + * call-seq: + * file.flock (locking_constant ) => 0 or false + * + * Locks or unlocks a file according to locking_constant (a + * logical or of the values in the table below). + * Returns false if File::LOCK_NB is + * specified and the operation would otherwise have blocked. Not + * available on all platforms. + * + * Locking constants (in class File): + * + * LOCK_EX | Exclusive lock. Only one process may hold an + * | exclusive lock for a given file at a time. + * ----------+------------------------------------------------ + * LOCK_NB | Don't block when locking. May be combined + * | with other lock options using logical or. + * ----------+------------------------------------------------ + * LOCK_SH | Shared lock. Multiple processes may each hold a + * | shared lock for a given file at the same time. + * ----------+------------------------------------------------ + * LOCK_UN | Unlock. + * + * Example: + * + * File.new("testfile").flock(File::LOCK_UN) #=> 0 + * + */ + static VALUE rb_file_flock(obj, operation) VALUE obj; @@ -2143,6 +2961,65 @@ test_check(n, argc, argv) #define CHECK(n) test_check((n), argc, argv) +/* + * call-seq: + * test(int_cmd, file1 [, file2] ) => obj + * + * Uses the integer aCmd to perform various tests on + * file1 (first table below) or on file1 and + * file2 (second table). + * + * File tests on a single file: + * + * Test Returns Meaning + * ?A | Time | Last access time for file1 + * ?b | boolean | True if file1 is a block device + * ?c | boolean | True if file1 is a character device + * ?C | Time | Last change time for file1 + * ?d | boolean | True if file1 exists and is a directory + * ?e | boolean | True if file1 exists + * ?f | boolean | True if file1 exists and is a regular file + * ?g | boolean | True if files has the \CF{setgid} bit + * | | set (false under NT) + * ?G | boolean | True if file1 exists and has a group + * | | ownership equal to the caller's group + * ?k | boolean | True if file1 exists and has the sticky bit set + * ?l | boolean | True if files exists and is a symbolic link + * ?M | Time | Last modification time for file1 + * ?o | boolean | True if files exists and is owned by + * | | the caller's effective uid + * ?O | boolean | True if file1 exists and is owned by + * | | the caller's real uid + * ?p | boolean | True if file1 exists and is a fifo + * ?r | boolean | True if file1 is readable by the effective + * | | uid/gid of the caller + * ?R | boolean | True if file is readable by the real + * | | uid/gid of the caller + * ?s | int/nil | If files has nonzero size, return the size, + * | | otherwise return nil + * ?S | boolean | True if file1 exists and is a socket + * ?u | boolean | True if file1 has the setuid bit set + * ?w | boolean | True if file1 exists and is writable by + * | | the effective uid/gid + * ?W | boolean | True if file1 exists and is writable by + * | | the real uid/gid + * ?x | boolean | True if file1 exists and is executable by + * | | the effective uid/gid + * ?X | boolean | True if file1 exists and is executable by + * | | the real uid/gid + * ?z | boolean | True if file1 exists and has a zero length + * + * Tests that take two files: + * + * ?- | boolean | True if file1 is a hard link to file2 + * ?= | boolean | True if the modification times of file1 + * | | and file2 are equal + * ?< | boolean | True if the modification time of file1 + * | | is prior to that of file2 + * ?> | boolean | True if the modification time of file1 + * | | is after that of file2 + */ + static VALUE rb_f_test(argc, argv) int argc; @@ -2279,6 +3156,22 @@ rb_f_test(argc, argv) return Qnil; /* not reached */ } + + +/* + * Document-class: File::Stat + * + * Objects of class File::Stat encapsulate common status + * information for File objects. The information is + * recorded at the moment the File::Stat object is + * created; changes made to the file after that point will not be + * reflected. File::Stat objects are returned by + * IO#stat, File::stat, + * File#lstat, and File::lstat. Many of these + * methods return platform-specific values, and not all values are + * meaningful on all systems. See also Kernel#test. + */ + static VALUE rb_stat_s_alloc _((VALUE)); static VALUE rb_stat_s_alloc(klass) @@ -2287,6 +3180,15 @@ rb_stat_s_alloc(klass) return stat_new_0(klass, 0); } +/* + * call-seq: + * + * File::Stat.new(file_name) => stat + * + * Create a File::Stat object for the given file name (raising an + * exception if the file doesn't exist). + */ + static VALUE rb_stat_init(obj, fname) VALUE obj, fname; @@ -2334,6 +3236,20 @@ rb_stat_init_copy(copy, orig) return copy; } +/* + * call-seq: + * stat.ftype => string + * + * Identifies the type of stat. The return string is one of: + * ``file'', ``directory'', + * ``characterSpecial'', ``blockSpecial'', + * ``fifo'', ``link'', + * ``socket'', or ``unknown''. + * + * File.stat("/dev/tty").ftype #=> "characterSpecial" + * + */ + static VALUE rb_stat_ftype(obj) VALUE obj; @@ -2341,6 +3257,17 @@ rb_stat_ftype(obj) return rb_file_ftype(get_stat(obj)); } +/* + * call-seq: + * stat.directory? => true or false + * + * Returns true if stat is a directory, + * false otherwise. + * + * File.stat("testfile").directory? #=> false + * File.stat(".").directory? #=> true + */ + static VALUE rb_stat_d(obj) VALUE obj; @@ -2349,6 +3276,14 @@ rb_stat_d(obj) return Qfalse; } +/* + * call-seq: + * stat.pipe? => true or false + * + * Returns true if the operating system supports pipes and + * stat is a pipe; false otherwise. + */ + static VALUE rb_stat_p(obj) VALUE obj; @@ -2360,6 +3295,23 @@ rb_stat_p(obj) return Qfalse; } +/* + * call-seq: + * stat.symlink? => true or false + * + * Returns true if stat is a symbolic link, + * false if it isn't or if the operating system doesn't + * support this feature. As File::stat automatically + * follows symbolic links, symlink? will always be + * false for an object returned by + * File::stat. + * + * File.symlink("testfile", "alink") #=> 0 + * File.stat("alink").symlink? #=> false + * File.lstat("alink").symlink? #=> true + * + */ + static VALUE rb_stat_l(obj) VALUE obj; @@ -2370,6 +3322,18 @@ rb_stat_l(obj) return Qfalse; } +/* + * call-seq: + * stat.socket? => true or false + * + * Returns true if stat is a socket, + * false if it isn't or if the operating system doesn't + * support this feature. + * + * File.stat("testfile").socket? #=> false + * + */ + static VALUE rb_stat_S(obj) VALUE obj; @@ -2381,6 +3345,19 @@ rb_stat_S(obj) return Qfalse; } +/* + * call-seq: + * stat.blockdev? => true or false + * + * Returns true if the file is a block device, + * false if it isn't or if the operating system doesn't + * support this feature. + * + * File.stat("testfile").blockdev? #=> false + * File.stat("/dev/hda1").blockdev? #=> true + * + */ + static VALUE rb_stat_b(obj) VALUE obj; @@ -2392,6 +3369,18 @@ rb_stat_b(obj) return Qfalse; } +/* + * call-seq: + * stat.chardev? => true or false + * + * Returns true if the file is a character device, + * false if it isn't or if the operating system doesn't + * support this feature. + * + * File.stat("/dev/tty").chardev? #=> true + * + */ + static VALUE rb_stat_c(obj) VALUE obj; @@ -2401,6 +3390,18 @@ rb_stat_c(obj) return Qfalse; } +/* + * call-seq: + * stat.owned? => true or false + * + * Returns true if the effective user id of the process is + * the same as the owner of stat. + * + * File.stat("testfile").owned? #=> true + * File.stat("/etc/passwd").owned? #=> false + * + */ + static VALUE rb_stat_owned(obj) VALUE obj; @@ -2417,6 +3418,18 @@ rb_stat_rowned(obj) return Qfalse; } +/* + * call-seq: + * stat.grpowned? => true or false + * + * Returns true if the effective group id of the process is the same as + * the group id of stat. On Windows NT, returns false. + * + * File.stat("testfile").grpowned? #=> true + * File.stat("/etc/passwd").grpowned? #=> false + * + */ + static VALUE rb_stat_grpowned(obj) VALUE obj; @@ -2427,6 +3440,17 @@ rb_stat_grpowned(obj) return Qfalse; } +/* + * call-seq: + * stat.readable? => true or false + * + * Returns true if stat is readable by the + * effective user id of this process. + * + * File.stat("testfile").readable? #=> true + * + */ + static VALUE rb_stat_r(obj) VALUE obj; @@ -2447,6 +3471,19 @@ rb_stat_r(obj) return Qtrue; } + + +/* + * call-seq: + * stat.readable_real? -> true or false + * + * Returns true if stat is readable by the real + * user id of this process. + * + * File.stat("testfile").readable_real? #=> true + * + */ + static VALUE rb_stat_R(obj) VALUE obj; @@ -2467,6 +3504,17 @@ rb_stat_R(obj) return Qtrue; } +/* + * call-seq: + * stat.writable? -> true or false + * + * Returns true if stat is writable by the + * effective user id of this process. + * + * File.stat("testfile").writable? #=> true + * + */ + static VALUE rb_stat_w(obj) VALUE obj; @@ -2487,6 +3535,17 @@ rb_stat_w(obj) return Qtrue; } +/* + * call-seq: + * stat.writable_real? -> true or false + * + * Returns true if stat is writable by the real + * user id of this process. + * + * File.stat("testfile").writable_real? #=> true + * + */ + static VALUE rb_stat_W(obj) VALUE obj; @@ -2507,6 +3566,19 @@ rb_stat_W(obj) return Qtrue; } +/* + * call-seq: + * stat.executable? => true or false + * + * Returns true if stat is executable or if the + * operating system doesn't distinguish executable files from + * nonexecutable files. The tests are made using the effective owner of + * the process. + * + * File.stat("testfile").executable? #=> false + * + */ + static VALUE rb_stat_x(obj) VALUE obj; @@ -2527,6 +3599,15 @@ rb_stat_x(obj) return Qtrue; } +/* + * call-seq: + * stat.executable_real? => true or false + * + * Same as executable?, but tests using the real owner of + * the process. + */ + + static VALUE rb_stat_X(obj) VALUE obj; @@ -2547,6 +3628,17 @@ rb_stat_X(obj) return Qtrue; } +/* + * call-seq: + * stat.file? => true or false + * + * Returns true if stat is a regular file (not + * a device file, pipe, socket, etc.). + * + * File.stat("testfile").file? #=> true + * + */ + static VALUE rb_stat_f(obj) VALUE obj; @@ -2555,6 +3647,17 @@ rb_stat_f(obj) return Qfalse; } +/* + * call-seq: + * stat.zero? => true or false + * + * Returns true if stat is a zero-length file; + * false otherwise. + * + * File.stat("testfile").zero? #=> false + * + */ + static VALUE rb_stat_z(obj) VALUE obj; @@ -2563,6 +3666,17 @@ rb_stat_z(obj) return Qfalse; } + +/* + * call-seq: + * state.size => integer + * + * Returns the size of stat in bytes. + * + * File.stat("testfile").size #=> 66 + * + */ + static VALUE rb_stat_s(obj) VALUE obj; @@ -2573,6 +3687,17 @@ rb_stat_s(obj) return OFFT2NUM(size); } +/* + * call-seq: + * stat.setuid? => true or false + * + * Returns true if stat has the set-user-id + * permission bit set, false if it doesn't or if the + * operating system doesn't support this feature. + * + * File.stat("/bin/su").setuid? #=> true + */ + static VALUE rb_stat_suid(obj) VALUE obj; @@ -2583,6 +3708,18 @@ rb_stat_suid(obj) return Qfalse; } +/* + * call-seq: + * stat.setgid? => true or false + * + * Returns true if stat has the set-group-id + * permission bit set, false if it doesn't or if the + * operating system doesn't support this feature. + * + * File.stat("/usr/sbin/lpc").setgid? #=> true + * + */ + static VALUE rb_stat_sgid(obj) VALUE obj; @@ -2593,6 +3730,18 @@ rb_stat_sgid(obj) return Qfalse; } +/* + * call-seq: + * stat.sticky? => true or false + * + * Returns true if stat has its sticky bit set, + * false if it doesn't or if the operating system doesn't + * support this feature. + * + * File.stat("testfile").sticky? #=> false + * + */ + static VALUE rb_stat_sticky(obj) VALUE obj; @@ -2863,6 +4012,39 @@ define_filetest_function(name, func, argc) rb_define_singleton_method(rb_cFile, name, func, argc); } + +/* + * A File is an abstraction of any file object accessible + * by the program and is closely associated with class IO + * File includes the methods of module + * FileTest as class methods, allowing you to write (for + * example) File.exist?("foo"). + * + * In the description of File methods, + * permission bits are a platform-specific + * set of bits that indicate permissions of a file. On Unix-based + * systems, permissions are viewed as a set of three octets, for the + * owner, the group, and the rest of the world. For each of these + * entities, permissions may be set to read, write, or execute the + * file: + * + * The permission bits 0644 (in octal) would thus be + * interpreted as read/write for owner, and read-only for group and + * other. Higher-order bits may also be used to indicate the type of + * file (plain, directory, pipe, socket, and so on) and various other + * special features. If the permissions are for a directory, the + * meaning of the execute bit changes; when set the directory can be + * searched. + * + * On non-Posix operating systems, there may be only the ability to + * make a file read-only or read-write. In this case, the remaining + * permission bits will be synthesized to resemble typical values. For + * instance, on Windows NT the default permission bits are + * 0644, which means read/write for owner, read-only for + * all others. The only change that can be made is to make the file + * read-only, which is reported as 0444. + */ + void Init_File() { -- cgit v1.2.3