2 ** file_test.c - FileTest class
6 #include "mruby/class.h"
7 #include "mruby/data.h"
8 #include "mruby/string.h"
9 #include "mruby/ext/io.h"
10 #include "mruby/error.h"
12 #include <sys/types.h>
15 #if defined(_WIN32) || defined(_WIN64)
21 #include <sys/param.h>
34 extern struct mrb_data_type mrb_io_type;
37 mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat)
39 if (mrb_obj_is_kind_of(mrb, obj, mrb_class_get(mrb, "IO"))) {
41 fptr = (struct mrb_io *)mrb_data_get_ptr(mrb, obj, &mrb_io_type);
43 if (fptr && fptr->fd >= 0) {
44 return fstat(fptr->fd, st);
47 mrb_raise(mrb, E_IO_ERROR, "closed stream");
51 char *path = mrb_locale_from_utf8(RSTRING_CSTR(mrb, obj), -1);
54 ret = LSTAT(path, st);
58 mrb_locale_free(path);
64 mrb_stat(mrb_state *mrb, mrb_value obj, struct stat *st)
66 return mrb_stat0(mrb, obj, st, 0);
70 mrb_lstat(mrb_state *mrb, mrb_value obj, struct stat *st)
72 return mrb_stat0(mrb, obj, st, 1);
76 * Document-method: directory?
79 * File.directory?(file_name) -> true or false
81 * Returns <code>true</code> if the named file is a directory,
82 * or a symlink that points at a directory, and <code>false</code>
85 * File.directory?(".")
89 mrb_filetest_s_directory_p(mrb_state *mrb, mrb_value klass)
92 # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
96 mrb_value obj = mrb_get_arg1(mrb);
98 if (mrb_stat(mrb, obj, &st) < 0)
99 return mrb_false_value();
100 if (S_ISDIR(st.st_mode))
101 return mrb_true_value();
103 return mrb_false_value();
108 * File.pipe?(file_name) -> true or false
110 * Returns <code>true</code> if the named file is a pipe.
114 mrb_filetest_s_pipe_p(mrb_state *mrb, mrb_value klass)
116 #if defined(_WIN32) || defined(_WIN64)
117 mrb_raise(mrb, E_NOTIMP_ERROR, "pipe is not supported on this platform");
121 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
125 mrb_value obj = mrb_get_arg1(mrb);
127 if (mrb_stat(mrb, obj, &st) < 0)
128 return mrb_false_value();
129 if (S_ISFIFO(st.st_mode))
130 return mrb_true_value();
133 return mrb_false_value();
139 * File.symlink?(file_name) -> true or false
141 * Returns <code>true</code> if the named file is a symbolic link.
145 mrb_filetest_s_symlink_p(mrb_state *mrb, mrb_value klass)
147 #if defined(_WIN32) || defined(_WIN64)
148 mrb_raise(mrb, E_NOTIMP_ERROR, "symlink is not supported on this platform");
152 # define S_ISLNK(m) _S_ISLNK(m)
155 # define S_ISLNK(m) (((m) & S_IFMT) == _S_IFLNK)
158 # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
166 mrb_value obj = mrb_get_arg1(mrb);
168 if (mrb_lstat(mrb, obj, &st) == -1)
169 return mrb_false_value();
170 if (S_ISLNK(st.st_mode))
171 return mrb_true_value();
174 return mrb_false_value();
180 * File.socket?(file_name) -> true or false
182 * Returns <code>true</code> if the named file is a socket.
186 mrb_filetest_s_socket_p(mrb_state *mrb, mrb_value klass)
188 #if defined(_WIN32) || defined(_WIN64)
189 mrb_raise(mrb, E_NOTIMP_ERROR, "socket is not supported on this platform");
193 # define S_ISSOCK(m) _S_ISSOCK(m)
196 # define S_ISSOCK(m) (((m) & S_IFMT) == _S_IFSOCK)
199 # define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
207 mrb_value obj = mrb_get_arg1(mrb);
209 if (mrb_stat(mrb, obj, &st) < 0)
210 return mrb_false_value();
211 if (S_ISSOCK(st.st_mode))
212 return mrb_true_value();
215 return mrb_false_value();
221 * File.exist?(file_name) -> true or false
222 * File.exists?(file_name) -> true or false
224 * Return <code>true</code> if the named file exists.
228 mrb_filetest_s_exist_p(mrb_state *mrb, mrb_value klass)
231 mrb_value obj = mrb_get_arg1(mrb);
233 if (mrb_stat(mrb, obj, &st) < 0)
234 return mrb_false_value();
236 return mrb_true_value();
241 * File.file?(file_name) -> true or false
243 * Returns <code>true</code> if the named file exists and is a
248 mrb_filetest_s_file_p(mrb_state *mrb, mrb_value klass)
251 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
255 mrb_value obj = mrb_get_arg1(mrb);
257 if (mrb_stat(mrb, obj, &st) < 0)
258 return mrb_false_value();
259 if (S_ISREG(st.st_mode))
260 return mrb_true_value();
262 return mrb_false_value();
267 * File.zero?(file_name) -> true or false
269 * Returns <code>true</code> if the named file exists and has
274 mrb_filetest_s_zero_p(mrb_state *mrb, mrb_value klass)
277 mrb_value obj = mrb_get_arg1(mrb);
279 if (mrb_stat(mrb, obj, &st) < 0)
280 return mrb_false_value();
282 return mrb_true_value();
284 return mrb_false_value();
289 * File.size(file_name) -> integer
291 * Returns the size of <code>file_name</code>.
293 * _file_name_ can be an IO object.
297 mrb_filetest_s_size(mrb_state *mrb, mrb_value klass)
300 mrb_value obj = mrb_get_arg1(mrb);
302 if (mrb_stat(mrb, obj, &st) < 0)
303 mrb_sys_fail(mrb, "mrb_stat");
305 return mrb_fixnum_value(st.st_size);
310 * File.size?(file_name) -> Integer or nil
312 * Returns +nil+ if +file_name+ doesn't exist or has zero size, the size of the
317 mrb_filetest_s_size_p(mrb_state *mrb, mrb_value klass)
320 mrb_value obj = mrb_get_arg1(mrb);
322 if (mrb_stat(mrb, obj, &st) < 0)
323 return mrb_nil_value();
325 return mrb_nil_value();
327 return mrb_fixnum_value(st.st_size);
331 mrb_init_file_test(mrb_state *mrb)
335 f = mrb_define_class(mrb, "FileTest", mrb->object_class);
337 mrb_define_class_method(mrb, f, "directory?", mrb_filetest_s_directory_p, MRB_ARGS_REQ(1));
338 mrb_define_class_method(mrb, f, "exist?", mrb_filetest_s_exist_p, MRB_ARGS_REQ(1));
339 mrb_define_class_method(mrb, f, "exists?", mrb_filetest_s_exist_p, MRB_ARGS_REQ(1));
340 mrb_define_class_method(mrb, f, "file?", mrb_filetest_s_file_p, MRB_ARGS_REQ(1));
341 mrb_define_class_method(mrb, f, "pipe?", mrb_filetest_s_pipe_p, MRB_ARGS_REQ(1));
342 mrb_define_class_method(mrb, f, "size", mrb_filetest_s_size, MRB_ARGS_REQ(1));
343 mrb_define_class_method(mrb, f, "size?", mrb_filetest_s_size_p, MRB_ARGS_REQ(1));
344 mrb_define_class_method(mrb, f, "socket?", mrb_filetest_s_socket_p, MRB_ARGS_REQ(1));
345 mrb_define_class_method(mrb, f, "symlink?", mrb_filetest_s_symlink_p, MRB_ARGS_REQ(1));
346 mrb_define_class_method(mrb, f, "zero?", mrb_filetest_s_zero_p, MRB_ARGS_REQ(1));