Class: File::Stat

Inherits:
Object show all
Includes:
Comparable
Defined in:
file.c,
file.c

Overview

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.

Instance Method Summary collapse

Methods included from Comparable

#<, #<=, #==, #>, #>=, #between?, #clamp

Constructor Details

#File::Stat.new(file_name) ⇒ Object

Create a File::Stat object for the given file name (raising an exception if the file doesn't exist).


5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
# File 'file.c', line 5436

static VALUE
rb_stat_init(VALUE obj, VALUE fname)
{
    struct stat st, *nst;

    FilePathValue(fname);
    fname = rb_str_encode_ospath(fname);
    if (STAT(StringValueCStr(fname), &st) == -1) {
	rb_sys_fail_path(fname);
    }
    if (DATA_PTR(obj)) {
	xfree(DATA_PTR(obj));
	DATA_PTR(obj) = NULL;
    }
    nst = ALLOC(struct stat);
    *nst = st;
    DATA_PTR(obj) = nst;

    return Qnil;
}

Instance Method Details

#<=>(other_stat) ⇒ -1, ...

Compares File::Stat objects by comparing their respective modification times.

nil is returned if other_stat is not a File::Stat object

f1 = File.new("f1", "w")
sleep 1
f2 = File.new("f2", "w")
f1.stat <=> f2.stat   #=> -1

Returns:

  • (-1, 0, 1, nil)

538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
# File 'file.c', line 538

static VALUE
rb_stat_cmp(VALUE self, VALUE other)
{
    if (rb_obj_is_kind_of(other, rb_obj_class(self))) {
        struct timespec ts1 = stat_mtimespec(get_stat(self));
        struct timespec ts2 = stat_mtimespec(get_stat(other));
        if (ts1.tv_sec == ts2.tv_sec) {
            if (ts1.tv_nsec == ts2.tv_nsec) return INT2FIX(0);
            if (ts1.tv_nsec < ts2.tv_nsec) return INT2FIX(-1);
            return INT2FIX(1);
        }
        if (ts1.tv_sec < ts2.tv_sec) return INT2FIX(-1);
        return INT2FIX(1);
    }
    return Qnil;
}

#atimeTime

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

Returns:


944
945
946
947
948
# File 'file.c', line 944

static VALUE
rb_stat_atime(VALUE self)
{
    return stat_atime(get_stat(self));
}

#birthtimeaTime

Returns the birth time for stat.

If the platform doesn't have birthtime, raises NotImplementedError.

File.write("testfile", "foo")
sleep 10
File.write("testfile", "bar")
sleep 10
File.chmod(0644, "testfile")
sleep 10
File.read("testfile")
File.stat("testfile").birthtime   #=> 2014-02-24 11:19:17 +0900
File.stat("testfile").mtime       #=> 2014-02-24 11:19:27 +0900
File.stat("testfile").ctime       #=> 2014-02-24 11:19:37 +0900
File.stat("testfile").atime       #=> 2014-02-24 11:19:47 +0900

Returns:

  • (aTime)

1009
1010
1011
1012
1013
# File 'file.c', line 1009

static VALUE
rb_stat_birthtime(VALUE self)
{
    return stat_birthtime(get_stat(self));
}

#blksizeInteger?

Returns the native file system's block size. Will return nil on platforms that don't support this information.

File.stat("testfile").blksize   #=> 4096

Returns:


810
811
812
813
814
815
816
817
818
# File 'file.c', line 810

static VALUE
rb_stat_blksize(VALUE self)
{
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
    return ULONG2NUM(get_stat(self)->st_blksize);
#else
    return Qnil;
#endif
}

#blockdev?Boolean

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

Returns:

  • (Boolean)

5593
5594
5595
5596
5597
5598
5599
5600
5601
# File 'file.c', line 5593

static VALUE
rb_stat_b(VALUE obj)
{
#ifdef S_ISBLK
    if (S_ISBLK(get_stat(obj)->st_mode)) return Qtrue;

#endif
    return Qfalse;
}

#blocksInteger?

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

Returns:


831
832
833
834
835
836
837
838
839
840
841
842
843
# File 'file.c', line 831

static VALUE
rb_stat_blocks(VALUE self)
{
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
# if SIZEOF_STRUCT_STAT_ST_BLOCKS > SIZEOF_LONG
    return ULL2NUM(get_stat(self)->st_blocks);
# else
    return ULONG2NUM(get_stat(self)->st_blocks);
# endif
#else
    return Qnil;
#endif
}

#chardev?Boolean

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

Returns:

  • (Boolean)

5615
5616
5617
5618
5619
5620
5621
# File 'file.c', line 5615

static VALUE
rb_stat_c(VALUE obj)
{
    if (S_ISCHR(get_stat(obj)->st_mode)) return Qtrue;

    return Qfalse;
}

#ctimeaTime

Returns the change time for stat (that is, the time directory information about the file was changed, not the file itself).

Note that on Windows (NTFS), returns creation time (birth time).

File.stat("testfile").ctime   #=> Wed Apr 09 08:53:14 CDT 2003

Returns:

  • (aTime)

980
981
982
983
984
# File 'file.c', line 980

static VALUE
rb_stat_ctime(VALUE self)
{
    return stat_ctime(get_stat(self));
}

#devInteger

Returns an integer representing the device on which stat resides.

File.stat("testfile").dev   #=> 774

Returns:


577
578
579
580
581
# File 'file.c', line 577

static VALUE
rb_stat_dev(VALUE self)
{
    return DEVT2NUM(get_stat(self)->st_dev);
}

#dev_majorInteger

Returns the major part of File_Stat#dev or nil.

File.stat("/dev/fd1").dev_major   #=> 2
File.stat("/dev/tty").dev_major   #=> 5

Returns:


594
595
596
597
598
599
600
601
602
# File 'file.c', line 594

static VALUE
rb_stat_dev_major(VALUE self)
{
#if defined(major)
    return UINT2NUM(major(get_stat(self)->st_dev));
#else
    return Qnil;
#endif
}

#dev_minorInteger

Returns the minor part of File_Stat#dev or nil.

File.stat("/dev/fd1").dev_minor   #=> 1
File.stat("/dev/tty").dev_minor   #=> 0

Returns:


615
616
617
618
619
620
621
622
623
# File 'file.c', line 615

static VALUE
rb_stat_dev_minor(VALUE self)
{
#if defined(minor)
    return UINT2NUM(minor(get_stat(self)->st_dev));
#else
    return Qnil;
#endif
}

#directory?Boolean

Returns true if stat is a directory, false otherwise.

File.stat("testfile").directory?   #=> false
File.stat(".").directory?          #=> true

Returns:

  • (Boolean)

5508
5509
5510
5511
5512
5513
# File 'file.c', line 5508

static VALUE
rb_stat_d(VALUE obj)
{
    if (S_ISDIR(get_stat(obj)->st_mode)) return Qtrue;
    return Qfalse;
}

#executable?Boolean

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

Returns:

  • (Boolean)

5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
# File 'file.c', line 5869

static VALUE
rb_stat_x(VALUE obj)
{
    struct stat *st = get_stat(obj);

#ifdef USE_GETEUID
    if (geteuid() == 0) {
	return st->st_mode & S_IXUGO ? Qtrue : Qfalse;
    }
#endif
#ifdef S_IXUSR
    if (rb_stat_owned(obj))
	return st->st_mode & S_IXUSR ? Qtrue : Qfalse;
#endif
#ifdef S_IXGRP
    if (rb_stat_grpowned(obj))
	return st->st_mode & S_IXGRP ? Qtrue : Qfalse;
#endif
#ifdef S_IXOTH
    if (!(st->st_mode & S_IXOTH)) return Qfalse;
#endif
    return Qtrue;
}

#executable_real?Boolean

Same as executable?, but tests using the real owner of the process.

Returns:

  • (Boolean)

5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
# File 'file.c', line 5901

static VALUE
rb_stat_X(VALUE obj)
{
    struct stat *st = get_stat(obj);

#ifdef USE_GETEUID
    if (getuid() == 0) {
	return st->st_mode & S_IXUGO ? Qtrue : Qfalse;
    }
#endif
#ifdef S_IXUSR
    if (rb_stat_rowned(obj))
	return st->st_mode & S_IXUSR ? Qtrue : Qfalse;
#endif
#ifdef S_IXGRP
    if (rb_group_member(get_stat(obj)->st_gid))
	return st->st_mode & S_IXGRP ? Qtrue : Qfalse;
#endif
#ifdef S_IXOTH
    if (!(st->st_mode & S_IXOTH)) return Qfalse;
#endif
    return Qtrue;
}

#file?Boolean

Returns true if stat is a regular file (not a device file, pipe, socket, etc.).

File.stat("testfile").file?   #=> true

Returns:

  • (Boolean)

5936
5937
5938
5939
5940
5941
# File 'file.c', line 5936

static VALUE
rb_stat_f(VALUE obj)
{
    if (S_ISREG(get_stat(obj)->st_mode)) return Qtrue;
    return Qfalse;
}

#ftypeString

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"

Returns:


5491
5492
5493
5494
5495
# File 'file.c', line 5491

static VALUE
rb_stat_ftype(VALUE obj)
{
    return rb_file_ftype(get_stat(obj));
}

#gidInteger

Returns the numeric group id of the owner of stat.

File.stat("testfile").gid   #=> 500

Returns:


714
715
716
717
718
# File 'file.c', line 714

static VALUE
rb_stat_gid(VALUE self)
{
    return GIDT2NUM(get_stat(self)->st_gid);
}

#grpowned?Boolean

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

Returns:

  • (Boolean)

5661
5662
5663
5664
5665
5666
5667
5668
# File 'file.c', line 5661

static VALUE
rb_stat_grpowned(VALUE obj)
{
#ifndef _WIN32
    if (rb_group_member(get_stat(obj)->st_gid)) return Qtrue;
#endif
    return Qfalse;
}

#initialize_copy(orig) ⇒ Object

:nodoc:


5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
# File 'file.c', line 5458

static VALUE
rb_stat_init_copy(VALUE copy, VALUE orig)
{
    struct stat *nst;

    if (!OBJ_INIT_COPY(copy, orig)) return copy;
    if (DATA_PTR(copy)) {
	xfree(DATA_PTR(copy));
	DATA_PTR(copy) = 0;
    }
    if (DATA_PTR(orig)) {
	nst = ALLOC(struct stat);
	*nst = *(struct stat*)DATA_PTR(orig);
	DATA_PTR(copy) = nst;
    }

    return copy;
}

#inoInteger

Returns the inode number for stat.

File.stat("testfile").ino   #=> 1083669

Returns:


635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
# File 'file.c', line 635

static VALUE
rb_stat_ino(VALUE self)
{
#ifdef HAVE_STRUCT_STAT_ST_INOHIGH
    /* assume INTEGER_PACK_LSWORD_FIRST and st_inohigh is just next of st_ino */
    return rb_integer_unpack(&get_stat(self)->st_ino, 2,
            SIZEOF_STRUCT_STAT_ST_INO, 0,
            INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER|
            INTEGER_PACK_2COMP);
#elif SIZEOF_STRUCT_STAT_ST_INO > SIZEOF_LONG
    return ULL2NUM(get_stat(self)->st_ino);
#else
    return ULONG2NUM(get_stat(self)->st_ino);
#endif
}

#inspectString

Produce a nicely formatted description of stat.

File.stat("/etc/passwd").inspect   #=> "#<File::Stat dev=0xe000005, ino=1078078, mode=0100644,
   #    nlink=1, uid=0, gid=0, rdev=0x0, size=1374, blksize=4096,
   #    blocks=8, atime=Wed Dec 10 10:16:12 CST 2003,
   #    mtime=Fri Sep 12 15:41:41 CDT 2003,
   #    ctime=Mon Oct 27 11:20:27 CST 2003,
   #    birthtime=Mon Aug 04 08:13:49 CDT 2003>"

Returns:


1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
# File 'file.c', line 1033

static VALUE
rb_stat_inspect(VALUE self)
{
    VALUE str;
    size_t i;
    static const struct {
	const char *name;
	VALUE (*func)(VALUE);
    } member[] = {
	{"dev",	    rb_stat_dev},
	{"ino",	    rb_stat_ino},
	{"mode",    rb_stat_mode},
	{"nlink",   rb_stat_nlink},
	{"uid",	    rb_stat_uid},
	{"gid",	    rb_stat_gid},
	{"rdev",    rb_stat_rdev},
	{"size",    rb_stat_size},
	{"blksize", rb_stat_blksize},
	{"blocks",  rb_stat_blocks},
	{"atime",   rb_stat_atime},
	{"mtime",   rb_stat_mtime},
	{"ctime",   rb_stat_ctime},
#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC)
	{"birthtime",   rb_stat_birthtime},
#endif
    };

    struct stat* st;
    TypedData_Get_Struct(self, struct stat, &stat_data_type, st);
    if (!st) {
        return rb_sprintf("#<%s: uninitialized>", rb_obj_classname(self));
    }

    str = rb_str_buf_new2("#<");
    rb_str_buf_cat2(str, rb_obj_classname(self));
    rb_str_buf_cat2(str, " ");

    for (i = 0; i < sizeof(member)/sizeof(member[0]); i++) {
	VALUE v;

	if (i > 0) {
	    rb_str_buf_cat2(str, ", ");
	}
	rb_str_buf_cat2(str, member[i].name);
	rb_str_buf_cat2(str, "=");
	v = (*member[i].func)(self);
	if (i == 2) {		/* mode */
	    rb_str_catf(str, "0%lo", (unsigned long)NUM2ULONG(v));
	}
	else if (i == 0 || i == 6) { /* dev/rdev */
	    rb_str_catf(str, "0x%"PRI_DEVT_PREFIX"x", NUM2DEVT(v));
	}
	else {
	    rb_str_append(str, rb_inspect(v));
	}
    }
    rb_str_buf_cat2(str, ">");

    return str;
}

#modeInteger

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"

Returns:


664
665
666
667
668
# File 'file.c', line 664

static VALUE
rb_stat_mode(VALUE self)
{
    return UINT2NUM(ST2UINT(get_stat(self)->st_mode));
}

#mtimeaTime

Returns the modification time of stat.

File.stat("testfile").mtime   #=> Wed Apr 09 08:53:14 CDT 2003

Returns:

  • (aTime)

960
961
962
963
964
# File 'file.c', line 960

static VALUE
rb_stat_mtime(VALUE self)
{
    return stat_mtime(get_stat(self));
}

Returns the number of hard links to stat.

File.stat("testfile").nlink             #=> 1
File.link("testfile", "testfile.bak")   #=> 0
File.stat("testfile").nlink             #=> 2

Returns:


682
683
684
685
686
# File 'file.c', line 682

static VALUE
rb_stat_nlink(VALUE self)
{
    return UINT2NUM(get_stat(self)->st_nlink);
}

#owned?Boolean

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

Returns:

  • (Boolean)

5635
5636
5637
5638
5639
5640
# File 'file.c', line 5635

static VALUE
rb_stat_owned(VALUE obj)
{
    if (get_stat(obj)->st_uid == geteuid()) return Qtrue;
    return Qfalse;
}

#pipe?Boolean

Returns true if the operating system supports pipes and stat is a pipe; false otherwise.

Returns:

  • (Boolean)

5523
5524
5525
5526
5527
5528
5529
5530
5531
# File 'file.c', line 5523

static VALUE
rb_stat_p(VALUE obj)
{
#ifdef S_IFIFO
    if (S_ISFIFO(get_stat(obj)->st_mode)) return Qtrue;

#endif
    return Qfalse;
}

#rdevInteger?

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

Returns:


732
733
734
735
736
737
738
739
740
# File 'file.c', line 732

static VALUE
rb_stat_rdev(VALUE self)
{
#ifdef HAVE_STRUCT_STAT_ST_RDEV
    return DEVT2NUM(get_stat(self)->st_rdev);
#else
    return Qnil;
#endif
}

#rdev_majorInteger

Returns the major part of File_Stat#rdev or nil.

File.stat("/dev/fd1").rdev_major   #=> 2
File.stat("/dev/tty").rdev_major   #=> 5

Returns:


753
754
755
756
757
758
759
760
761
# File 'file.c', line 753

static VALUE
rb_stat_rdev_major(VALUE self)
{
#if defined(HAVE_STRUCT_STAT_ST_RDEV) && defined(major)
    return UINT2NUM(major(get_stat(self)->st_rdev));
#else
    return Qnil;
#endif
}

#rdev_minorInteger

Returns the minor part of File_Stat#rdev or nil.

File.stat("/dev/fd1").rdev_minor   #=> 1
File.stat("/dev/tty").rdev_minor   #=> 0

Returns:


774
775
776
777
778
779
780
781
782
# File 'file.c', line 774

static VALUE
rb_stat_rdev_minor(VALUE self)
{
#if defined(HAVE_STRUCT_STAT_ST_RDEV) && defined(minor)
    return UINT2NUM(minor(get_stat(self)->st_rdev));
#else
    return Qnil;
#endif
}

#readable?Boolean

Returns true if stat is readable by the effective user id of this process.

File.stat("testfile").readable?   #=> true

Returns:

  • (Boolean)

5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
# File 'file.c', line 5681

static VALUE
rb_stat_r(VALUE obj)
{
    struct stat *st = get_stat(obj);

#ifdef USE_GETEUID
    if (geteuid() == 0) return Qtrue;
#endif
#ifdef S_IRUSR
    if (rb_stat_owned(obj))
	return st->st_mode & S_IRUSR ? Qtrue : Qfalse;
#endif
#ifdef S_IRGRP
    if (rb_stat_grpowned(obj))
	return st->st_mode & S_IRGRP ? Qtrue : Qfalse;
#endif
#ifdef S_IROTH
    if (!(st->st_mode & S_IROTH)) return Qfalse;
#endif
    return Qtrue;
}

#readable_real?Boolean

Returns true if stat is readable by the real user id of this process.

File.stat("testfile").readable_real?   #=> true

Returns:

  • (Boolean)

5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
# File 'file.c', line 5714

static VALUE
rb_stat_R(VALUE obj)
{
    struct stat *st = get_stat(obj);

#ifdef USE_GETEUID
    if (getuid() == 0) return Qtrue;
#endif
#ifdef S_IRUSR
    if (rb_stat_rowned(obj))
	return st->st_mode & S_IRUSR ? Qtrue : Qfalse;
#endif
#ifdef S_IRGRP
    if (rb_group_member(get_stat(obj)->st_gid))
	return st->st_mode & S_IRGRP ? Qtrue : Qfalse;
#endif
#ifdef S_IROTH
    if (!(st->st_mode & S_IROTH)) return Qfalse;
#endif
    return Qtrue;
}

#setgid?Boolean

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

Returns:

  • (Boolean)

6012
6013
6014
6015
6016
6017
6018
6019
# File 'file.c', line 6012

static VALUE
rb_stat_sgid(VALUE obj)
{
#ifdef S_ISGID
    if (get_stat(obj)->st_mode & S_ISGID) return Qtrue;
#endif
    return Qfalse;
}

#setuid?Boolean

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

Returns:

  • (Boolean)

5991
5992
5993
5994
5995
5996
5997
5998
# File 'file.c', line 5991

static VALUE
rb_stat_suid(VALUE obj)
{
#ifdef S_ISUID
    if (get_stat(obj)->st_mode & S_ISUID) return Qtrue;
#endif
    return Qfalse;
}

#sizeInteger

Returns the size of stat in bytes.

File.stat("testfile").size   #=> 66

Returns:


793
794
795
796
797
# File 'file.c', line 793

static VALUE
rb_stat_size(VALUE self)
{
    return OFFT2NUM(get_stat(self)->st_size);
}

#sizeInteger

Returns the size of stat in bytes.

File.stat("testfile").size   #=> 66

Returns:


5971
5972
5973
5974
5975
5976
5977
5978
# File 'file.c', line 5971

static VALUE
rb_stat_s(VALUE obj)
{
    off_t size = get_stat(obj)->st_size;

    if (size == 0) return Qnil;
    return OFFT2NUM(size);
}

#socket?Boolean

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

Returns:

  • (Boolean)

5570
5571
5572
5573
5574
5575
5576
5577
5578
# File 'file.c', line 5570

static VALUE
rb_stat_S(VALUE obj)
{
#ifdef S_ISSOCK
    if (S_ISSOCK(get_stat(obj)->st_mode)) return Qtrue;

#endif
    return Qfalse;
}

#sticky?Boolean

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

Returns:

  • (Boolean)

6033
6034
6035
6036
6037
6038
6039
6040
# File 'file.c', line 6033

static VALUE
rb_stat_sticky(VALUE obj)
{
#ifdef S_ISVTX
    if (get_stat(obj)->st_mode & S_ISVTX) return Qtrue;
#endif
    return Qfalse;
}

#symlink?Boolean

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

Returns:

  • (Boolean)

5549
5550
5551
5552
5553
5554
5555
5556
# File 'file.c', line 5549

static VALUE
rb_stat_l(VALUE obj)
{
#ifdef S_ISLNK
    if (S_ISLNK(get_stat(obj)->st_mode)) return Qtrue;
#endif
    return Qfalse;
}

#uidInteger

Returns the numeric user id of the owner of stat.

File.stat("testfile").uid   #=> 501

Returns:


698
699
700
701
702
# File 'file.c', line 698

static VALUE
rb_stat_uid(VALUE self)
{
    return UIDT2NUM(get_stat(self)->st_uid);
}

#world_readable?Integer?

If stat is readable by others, returns an integer representing the file permission bits of stat. Returns nil otherwise. The meaning of the bits is platform dependent; on Unix systems, see stat(2).

m = File.stat("/etc/passwd").world_readable?  #=> 420
sprintf("%o", m)				    #=> "644"

Returns:


5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
# File 'file.c', line 5749

static VALUE
rb_stat_wr(VALUE obj)
{
#ifdef S_IROTH
    struct stat *st = get_stat(obj);
    if ((st->st_mode & (S_IROTH)) == S_IROTH) {
	return UINT2NUM(st->st_mode & (S_IRUGO|S_IWUGO|S_IXUGO));
    }
    else {
	return Qnil;
    }
#endif
}

#world_writable?Integer?

If stat is writable by others, returns an integer representing the file permission bits of stat. Returns nil otherwise. The meaning of the bits is platform dependent; on Unix systems, see stat(2).

m = File.stat("/tmp").world_writable?	    #=> 511
sprintf("%o", m)				    #=> "777"

Returns:


5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
# File 'file.c', line 5842

static VALUE
rb_stat_ww(VALUE obj)
{
#ifdef S_IROTH
    struct stat *st = get_stat(obj);
    if ((st->st_mode & (S_IWOTH)) == S_IWOTH) {
	return UINT2NUM(st->st_mode & (S_IRUGO|S_IWUGO|S_IXUGO));
    }
    else {
	return Qnil;
    }
#endif
}

#writable?Boolean

Returns true if stat is writable by the effective user id of this process.

File.stat("testfile").writable?   #=> true

Returns:

  • (Boolean)

5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
# File 'file.c', line 5774

static VALUE
rb_stat_w(VALUE obj)
{
    struct stat *st = get_stat(obj);

#ifdef USE_GETEUID
    if (geteuid() == 0) return Qtrue;
#endif
#ifdef S_IWUSR
    if (rb_stat_owned(obj))
	return st->st_mode & S_IWUSR ? Qtrue : Qfalse;
#endif
#ifdef S_IWGRP
    if (rb_stat_grpowned(obj))
	return st->st_mode & S_IWGRP ? Qtrue : Qfalse;
#endif
#ifdef S_IWOTH
    if (!(st->st_mode & S_IWOTH)) return Qfalse;
#endif
    return Qtrue;
}

#writable_real?Boolean

Returns true if stat is writable by the real user id of this process.

File.stat("testfile").writable_real?   #=> true

Returns:

  • (Boolean)

5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
# File 'file.c', line 5807

static VALUE
rb_stat_W(VALUE obj)
{
    struct stat *st = get_stat(obj);

#ifdef USE_GETEUID
    if (getuid() == 0) return Qtrue;
#endif
#ifdef S_IWUSR
    if (rb_stat_rowned(obj))
	return st->st_mode & S_IWUSR ? Qtrue : Qfalse;
#endif
#ifdef S_IWGRP
    if (rb_group_member(get_stat(obj)->st_gid))
	return st->st_mode & S_IWGRP ? Qtrue : Qfalse;
#endif
#ifdef S_IWOTH
    if (!(st->st_mode & S_IWOTH)) return Qfalse;
#endif
    return Qtrue;
}

#zero?Boolean

Returns true if stat is a zero-length file; false otherwise.

File.stat("testfile").zero?   #=> false

Returns:

  • (Boolean)

5954
5955
5956
5957
5958
5959
# File 'file.c', line 5954

static VALUE
rb_stat_z(VALUE obj)
{
    if (get_stat(obj)->st_size == 0) return Qtrue;
    return Qfalse;
}