Kernel#test
static VALUE
rb_f_test(int argc, VALUE *argv, VALUE _)
{
int cmd;
if (argc == 0) rb_check_arity(argc, 2, 3);
cmd = NUM2CHR(argv[0]);
if (cmd == 0) {
goto unknown;
}
if (strchr("bcdefgGkloOprRsSuwWxXz", cmd)) {
CHECK(1);
switch (cmd) {
case 'b':
return rb_file_blockdev_p(0, argv[1]);
case 'c':
return rb_file_chardev_p(0, argv[1]);
case 'd':
return rb_file_directory_p(0, argv[1]);
case 'e':
return rb_file_exist_p(0, argv[1]);
case 'f':
return rb_file_file_p(0, argv[1]);
case 'g':
return rb_file_sgid_p(0, argv[1]);
case 'G':
return rb_file_grpowned_p(0, argv[1]);
case 'k':
return rb_file_sticky_p(0, argv[1]);
case 'l':
return rb_file_symlink_p(0, argv[1]);
case 'o':
return rb_file_owned_p(0, argv[1]);
case 'O':
return rb_file_rowned_p(0, argv[1]);
case 'p':
return rb_file_pipe_p(0, argv[1]);
case 'r':
return rb_file_readable_p(0, argv[1]);
case 'R':
return rb_file_readable_real_p(0, argv[1]);
case 's':
return rb_file_size_p(0, argv[1]);
case 'S':
return rb_file_socket_p(0, argv[1]);
case 'u':
return rb_file_suid_p(0, argv[1]);
case 'w':
return rb_file_writable_p(0, argv[1]);
case 'W':
return rb_file_writable_real_p(0, argv[1]);
case 'x':
return rb_file_executable_p(0, argv[1]);
case 'X':
return rb_file_executable_real_p(0, argv[1]);
case 'z':
return rb_file_zero_p(0, argv[1]);
}
}
if (strchr("MAC", cmd)) {
struct stat st;
VALUE fname = argv[1];
CHECK(1);
if (rb_stat(fname, &st) == -1) {
int e = errno;
FilePathValue(fname);
rb_syserr_fail_path(e, fname);
}
switch (cmd) {
case 'A':
return stat_atime(&st);
case 'M':
return stat_mtime(&st);
case 'C':
return stat_ctime(&st);
}
}
if (cmd == '-') {
CHECK(2);
return rb_file_identical_p(0, argv[1], argv[2]);
}
if (strchr("=<>", cmd)) {
struct stat st1, st2;
stat_timestamp t1, t2;
CHECK(2);
if (rb_stat(argv[1], &st1) < 0) return Qfalse;
if (rb_stat(argv[2], &st2) < 0) return Qfalse;
t1 = stat_mtimespec(&st1);
t2 = stat_mtimespec(&st2);
switch (cmd) {
case '=':
if (t1.tv_sec == t2.tv_sec && t1.tv_nsec == t2.tv_nsec) return Qtrue;
return Qfalse;
case '>':
if (t1.tv_sec > t2.tv_sec) return Qtrue;
if (t1.tv_sec == t2.tv_sec && t1.tv_nsec > t2.tv_nsec) return Qtrue;
return Qfalse;
case '<':
if (t1.tv_sec < t2.tv_sec) return Qtrue;
if (t1.tv_sec == t2.tv_sec && t1.tv_nsec < t2.tv_nsec) return Qtrue;
return Qfalse;
}
}
unknown:
/* unknown command */
if (ISPRINT(cmd)) {
rb_raise(rb_eArgError, "unknown command '%s%c'", cmd == '\'' || cmd == '\\' ? "\\" : "", cmd);
}
else {
rb_raise(rb_eArgError, "unknown command \"\\x%02X\"", cmd);
}
UNREACHABLE_RETURN(Qundef);
}
Performs a test on one or both of the filesystem entities at the given paths path0 and path1:
-
Each path
path0orpath1points to a file, directory, device, pipe, etc. -
Character
charselects a specific test.
The tests:
-
Each of these tests operates only on the entity at
path0, and returnstrueorfalse; for a non-existent entity, returnsfalse(does not raise exception):Character Test 'b'Whether the entity is a block device. 'c'Whether the entity is a character device. 'd'Whether the entity is a directory. 'e'Whether the entity is an existing entity. 'f'Whether the entity is an existing regular file. 'g'Whether the entity’s setgid bit is set. 'G'Whether the entity’s group ownership is equal to the caller’s. 'k'Whether the entity’s sticky bit is set. 'l'Whether the entity is a symbolic link. 'o'Whether the entity is owned by the caller’s effective uid. 'O'Like 'o', but uses the real uid (not the effective uid).'p'Whether the entity is a FIFO device (named pipe). 'r'Whether the entity is readable by the caller’s effective uid/gid. 'R'Like 'r', but uses the real uid/gid (not the effective uid/gid).'S'Whether the entity is a socket. 'u'Whether the entity’s setuid bit is set. 'w'Whether the entity is writable by the caller’s effective uid/gid. 'W'Like 'w', but uses the real uid/gid (not the effective uid/gid).'x'Whether the entity is executable by the caller’s effective uid/gid. 'X'Like 'x', but uses the real uid/gid (not the effective uid/git).'z'Whether the entity exists and is of length zero. -
This test operates only on the entity at
path0, and returns an integer size ornil:Character Test 's'Returns positive integer size if the entity exists and has non-zero length, nilotherwise. -
Each of these tests operates only on the entity at
path0, and returns aTimeobject; raises an exception if the entity does not exist:Character Test 'A'Last access time for the entity. 'C'Last change time for the entity. 'M'Last modification time for the entity. -
Each of these tests operates on the modification time (
mtime) of each of the entities atpath0andpath1, and returns atrueorfalse; returnsfalseif either entity does not exist:Character Test '<'Whether the mtimeatpath0is less than that atpath1.'='Whether the mtimeatpath0is equal to that atpath1.'>'Whether the mtimeatpath0is greater than that atpath1. -
This test operates on the content of each of the entities at
path0andpath1, and returns atrueorfalse; returnsfalseif either entity does not exist:Character Test '-'Whether the entities exist and are identical.