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?

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


4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
# File 'file.c', line 4485

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

    rb_secure(2);
    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.

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

Returns:

  • (-1, 0, 1, nil)

338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
# File 'file.c', line 338

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:


722
723
724
725
726
# File 'file.c', line 722

static VALUE
rb_stat_atime(VALUE self)
{
    return stat_atime(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:


604
605
606
607
608
609
610
611
612
# File 'file.c', line 604

static VALUE
rb_stat_blksize(VALUE self)
{
#ifdef HAVE_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)

Returns:

  • (Boolean)

4644
4645
4646
4647
4648
4649
4650
4651
4652
# File 'file.c', line 4644

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:


625
626
627
628
629
630
631
632
633
634
635
636
637
# File 'file.c', line 625

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)

Returns:

  • (Boolean)

4666
4667
4668
4669
4670
4671
4672
# File 'file.c', line 4666

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)

758
759
760
761
762
# File 'file.c', line 758

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

#devFixnum

Returns an integer representing the device on which stat resides.

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

Returns:


377
378
379
380
381
# File 'file.c', line 377

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

#dev_majorFixnum

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:


394
395
396
397
398
399
400
401
402
# File 'file.c', line 394

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

#dev_minorFixnum

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:


415
416
417
418
419
420
421
422
423
# File 'file.c', line 415

static VALUE
rb_stat_dev_minor(VALUE self)
{
#if defined(minor)
    return INT2NUM(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)

Returns:

  • (Boolean)

4558
4559
4560
4561
4562
4563
# File 'file.c', line 4558

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)

Returns:

  • (Boolean)

4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
# File 'file.c', line 4918

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)

Returns:

  • (Boolean)

4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
# File 'file.c', line 4950

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)

Returns:

  • (Boolean)

4985
4986
4987
4988
4989
4990
# File 'file.c', line 4985

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:


4541
4542
4543
4544
4545
# File 'file.c', line 4541

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

#gidFixnum

Returns the numeric group id of the owner of stat.

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

Returns:


508
509
510
511
512
# File 'file.c', line 508

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)

Returns:

  • (Boolean)

4712
4713
4714
4715
4716
4717
4718
4719
# File 'file.c', line 4712

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

#initialize_copyObject

:nodoc:


4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
# File 'file.c', line 4508

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;
}

#inoFixnum

Returns the inode number for stat.

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

Returns:


435
436
437
438
439
440
441
442
443
# File 'file.c', line 435

static VALUE
rb_stat_ino(VALUE self)
{
#if 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>"

Returns:


778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
# File 'file.c', line 778

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},
    };

    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, ">");
    OBJ_INFECT(str, self);

    return str;
}

#modeFixnum

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:


458
459
460
461
462
# File 'file.c', line 458

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)

738
739
740
741
742
# File 'file.c', line 738

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:


476
477
478
479
480
# File 'file.c', line 476

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)

Returns:

  • (Boolean)

4686
4687
4688
4689
4690
4691
# File 'file.c', line 4686

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)

Returns:

  • (Boolean)

4573
4574
4575
4576
4577
4578
4579
4580
4581
# File 'file.c', line 4573

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

#endif
    return Qfalse;
}

#rdevFixnum?

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:


526
527
528
529
530
531
532
533
534
# File 'file.c', line 526

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

#rdev_majorFixnum

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:


547
548
549
550
551
552
553
554
555
# File 'file.c', line 547

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

#rdev_minorFixnum

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:


568
569
570
571
572
573
574
575
576
# File 'file.c', line 568

static VALUE
rb_stat_rdev_minor(VALUE self)
{
#if defined(HAVE_ST_RDEV) && defined(minor)
    return DEVT2NUM(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)

Returns:

  • (Boolean)

4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
# File 'file.c', line 4732

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)

Returns:

  • (Boolean)

4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
# File 'file.c', line 4765

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)

Returns:

  • (Boolean)

5061
5062
5063
5064
5065
5066
5067
5068
# File 'file.c', line 5061

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)

Returns:

  • (Boolean)

5040
5041
5042
5043
5044
5045
5046
5047
# File 'file.c', line 5040

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

#sizeFixnum

Returns the size of stat in bytes.

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

Returns:


587
588
589
590
591
# File 'file.c', line 587

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:

Returns:

  • (Boolean)

5020
5021
5022
5023
5024
5025
5026
5027
# File 'file.c', line 5020

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)

Returns:

  • (Boolean)

4621
4622
4623
4624
4625
4626
4627
4628
4629
# File 'file.c', line 4621

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)

Returns:

  • (Boolean)

5082
5083
5084
5085
5086
5087
5088
5089
# File 'file.c', line 5082

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)

Returns:

  • (Boolean)

4600
4601
4602
4603
4604
4605
4606
4607
# File 'file.c', line 4600

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

#uidFixnum

Returns the numeric user id of the owner of stat.

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

Returns:


492
493
494
495
496
# File 'file.c', line 492

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

#world_readable?Fixnum?

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:

Returns:

  • (Boolean)

4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
# File 'file.c', line 4800

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

#world_writable?Fixnum?

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:

Returns:

  • (Boolean)

4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
# File 'file.c', line 4892

static VALUE
rb_stat_ww(VALUE obj)
{
#ifdef S_IROTH
    if ((get_stat(obj)->st_mode & (S_IWOTH)) == S_IWOTH) {
	return UINT2NUM(get_stat(obj)->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)

Returns:

  • (Boolean)

4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
# File 'file.c', line 4824

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)

Returns:

  • (Boolean)

4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
# File 'file.c', line 4857

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)

Returns:

  • (Boolean)

5003
5004
5005
5006
5007
5008
# File 'file.c', line 5003

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