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).



5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
# File 'file.c', line 5469

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:



958
959
960
961
962
# File 'file.c', line 958

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)


1023
1024
1025
1026
1027
# File 'file.c', line 1023

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:



824
825
826
827
828
829
830
831
832
# File 'file.c', line 824

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)


5626
5627
5628
5629
5630
5631
5632
5633
5634
# File 'file.c', line 5626

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:



845
846
847
848
849
850
851
852
853
854
855
856
857
# File 'file.c', line 845

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)


5648
5649
5650
5651
5652
5653
5654
# File 'file.c', line 5648

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)


994
995
996
997
998
# File 'file.c', line 994

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)


5541
5542
5543
5544
5545
5546
# File 'file.c', line 5541

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)


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

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)


5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
# File 'file.c', line 5934

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)


5969
5970
5971
5972
5973
5974
# File 'file.c', line 5969

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:



5524
5525
5526
5527
5528
# File 'file.c', line 5524

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:



728
729
730
731
732
# File 'file.c', line 728

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)


5694
5695
5696
5697
5698
5699
5700
5701
# File 'file.c', line 5694

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:



5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
# File 'file.c', line 5491

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:



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
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
# File 'file.c', line 1047

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)


974
975
976
977
978
# File 'file.c', line 974

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
687
688
689
690
691
692
693
694
695
696
697
698
699
700
# File 'file.c', line 682

static VALUE
rb_stat_nlink(VALUE self)
{
    /* struct stat::st_nlink is nlink_t in POSIX.  Not the case for Windows. */
    const struct stat *ptr = get_stat(self);

    if (sizeof(ptr->st_nlink) <= sizeof(int)) {
        return UINT2NUM((unsigned)ptr->st_nlink);
    }
    else if (sizeof(ptr->st_nlink) == sizeof(long)) {
        return ULONG2NUM((unsigned long)ptr->st_nlink);
    }
    else if (sizeof(ptr->st_nlink) == sizeof(LONG_LONG)) {
        return ULL2NUM((unsigned LONG_LONG)ptr->st_nlink);
    }
    else {
        rb_bug(":FIXME: don't know what to do");
    }
}

#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)


5668
5669
5670
5671
5672
5673
# File 'file.c', line 5668

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)


5556
5557
5558
5559
5560
5561
5562
5563
5564
# File 'file.c', line 5556

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:



746
747
748
749
750
751
752
753
754
# File 'file.c', line 746

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:



767
768
769
770
771
772
773
774
775
# File 'file.c', line 767

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:



788
789
790
791
792
793
794
795
796
# File 'file.c', line 788

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)


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 (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)


5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
# File 'file.c', line 5747

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)


6045
6046
6047
6048
6049
6050
6051
6052
# File 'file.c', line 6045

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)


6024
6025
6026
6027
6028
6029
6030
6031
# File 'file.c', line 6024

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:



807
808
809
810
811
# File 'file.c', line 807

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:



6004
6005
6006
6007
6008
6009
6010
6011
# File 'file.c', line 6004

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)


5603
5604
5605
5606
5607
5608
5609
5610
5611
# File 'file.c', line 5603

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)


6066
6067
6068
6069
6070
6071
6072
6073
# File 'file.c', line 6066

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)


5582
5583
5584
5585
5586
5587
5588
5589
# File 'file.c', line 5582

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:



712
713
714
715
716
# File 'file.c', line 712

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:



5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
# File 'file.c', line 5782

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:



5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
# File 'file.c', line 5875

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)


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 (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)


5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
# File 'file.c', line 5840

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)


5987
5988
5989
5990
5991
5992
# File 'file.c', line 5987

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