6 #include "mruby/class.h"
7 #include "mruby/data.h"
8 #include "mruby/string.h"
9 #include "mruby/ext/io.h"
11 #if MRUBY_RELEASE_NO < 10000
14 #include "mruby/error.h"
17 #include <sys/types.h>
20 #if defined(_WIN32) || defined(_WIN64)
26 #include <sys/param.h>
40 extern struct mrb_data_type mrb_io_type;
43 mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat)
46 mrb_value io_klass, str_klass;
48 io_klass = mrb_obj_value(mrb_class_get(mrb, "IO"));
49 str_klass = mrb_obj_value(mrb_class_get(mrb, "String"));
51 tmp = mrb_funcall(mrb, obj, "is_a?", 1, io_klass);
54 fptr = (struct mrb_io *)mrb_get_datatype(mrb, obj, &mrb_io_type);
56 if (fptr && fptr->fd >= 0) {
57 return fstat(fptr->fd, st);
60 mrb_raise(mrb, E_IO_ERROR, "closed stream");
64 tmp = mrb_funcall(mrb, obj, "is_a?", 1, str_klass);
66 char *path = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, obj), -1);
69 ret = LSTAT(path, st);
73 mrb_locale_free(path);
81 mrb_stat(mrb_state *mrb, mrb_value obj, struct stat *st)
83 return mrb_stat0(mrb, obj, st, 0);
87 mrb_lstat(mrb_state *mrb, mrb_value obj, struct stat *st)
89 return mrb_stat0(mrb, obj, st, 1);
93 * Document-method: directory?
96 * File.directory?(file_name) -> true or false
98 * Returns <code>true</code> if the named file is a directory,
99 * or a symlink that points at a directory, and <code>false</code>
102 * File.directory?(".")
106 mrb_filetest_s_directory_p(mrb_state *mrb, mrb_value klass)
109 # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
115 mrb_get_args(mrb, "o", &obj);
117 if (mrb_stat(mrb, obj, &st) < 0)
118 return mrb_false_value();
119 if (S_ISDIR(st.st_mode))
120 return mrb_true_value();
122 return mrb_false_value();
127 * File.pipe?(file_name) -> true or false
129 * Returns <code>true</code> if the named file is a pipe.
133 mrb_filetest_s_pipe_p(mrb_state *mrb, mrb_value klass)
135 #if defined(_WIN32) || defined(_WIN64)
136 mrb_raise(mrb, E_NOTIMP_ERROR, "pipe is not supported on this platform");
140 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
146 mrb_get_args(mrb, "o", &obj);
148 if (mrb_stat(mrb, obj, &st) < 0)
149 return mrb_false_value();
150 if (S_ISFIFO(st.st_mode))
151 return mrb_true_value();
154 return mrb_false_value();
160 * File.symlink?(file_name) -> true or false
162 * Returns <code>true</code> if the named file is a symbolic link.
166 mrb_filetest_s_symlink_p(mrb_state *mrb, mrb_value klass)
168 #if defined(_WIN32) || defined(_WIN64)
169 mrb_raise(mrb, E_NOTIMP_ERROR, "symlink is not supported on this platform");
173 # define S_ISLNK(m) _S_ISLNK(m)
176 # define S_ISLNK(m) (((m) & S_IFMT) == _S_IFLNK)
179 # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
189 mrb_get_args(mrb, "o", &obj);
191 if (mrb_lstat(mrb, obj, &st) == -1)
192 return mrb_false_value();
193 if (S_ISLNK(st.st_mode))
194 return mrb_true_value();
197 return mrb_false_value();
203 * File.socket?(file_name) -> true or false
205 * Returns <code>true</code> if the named file is a socket.
209 mrb_filetest_s_socket_p(mrb_state *mrb, mrb_value klass)
211 #if defined(_WIN32) || defined(_WIN64)
212 mrb_raise(mrb, E_NOTIMP_ERROR, "socket is not supported on this platform");
216 # define S_ISSOCK(m) _S_ISSOCK(m)
219 # define S_ISSOCK(m) (((m) & S_IFMT) == _S_IFSOCK)
222 # define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
232 mrb_get_args(mrb, "o", &obj);
234 if (mrb_stat(mrb, obj, &st) < 0)
235 return mrb_false_value();
236 if (S_ISSOCK(st.st_mode))
237 return mrb_true_value();
240 return mrb_false_value();
246 * File.exist?(file_name) -> true or false
247 * File.exists?(file_name) -> true or false
249 * Return <code>true</code> if the named file exists.
253 mrb_filetest_s_exist_p(mrb_state *mrb, mrb_value klass)
258 mrb_get_args(mrb, "o", &obj);
259 if (mrb_stat(mrb, obj, &st) < 0)
260 return mrb_false_value();
262 return mrb_true_value();
267 * File.file?(file_name) -> true or false
269 * Returns <code>true</code> if the named file exists and is a
274 mrb_filetest_s_file_p(mrb_state *mrb, mrb_value klass)
277 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
283 mrb_get_args(mrb, "o", &obj);
285 if (mrb_stat(mrb, obj, &st) < 0)
286 return mrb_false_value();
287 if (S_ISREG(st.st_mode))
288 return mrb_true_value();
290 return mrb_false_value();
295 * File.zero?(file_name) -> true or false
297 * Returns <code>true</code> if the named file exists and has
302 mrb_filetest_s_zero_p(mrb_state *mrb, mrb_value klass)
307 mrb_get_args(mrb, "o", &obj);
309 if (mrb_stat(mrb, obj, &st) < 0)
310 return mrb_false_value();
312 return mrb_true_value();
314 return mrb_false_value();
319 * File.size(file_name) -> integer
321 * Returns the size of <code>file_name</code>.
323 * _file_name_ can be an IO object.
327 mrb_filetest_s_size(mrb_state *mrb, mrb_value klass)
332 mrb_get_args(mrb, "o", &obj);
334 if (mrb_stat(mrb, obj, &st) < 0)
335 mrb_sys_fail(mrb, "mrb_stat");
337 return mrb_fixnum_value(st.st_size);
342 * File.size?(file_name) -> Integer or nil
344 * Returns +nil+ if +file_name+ doesn't exist or has zero size, the size of the
349 mrb_filetest_s_size_p(mrb_state *mrb, mrb_value klass)
354 mrb_get_args(mrb, "o", &obj);
356 if (mrb_stat(mrb, obj, &st) < 0)
357 return mrb_nil_value();
359 return mrb_nil_value();
361 return mrb_fixnum_value(st.st_size);
365 mrb_init_file_test(mrb_state *mrb)
369 f = mrb_define_class(mrb, "FileTest", mrb->object_class);
371 mrb_define_class_method(mrb, f, "directory?", mrb_filetest_s_directory_p, MRB_ARGS_REQ(1));
372 mrb_define_class_method(mrb, f, "exist?", mrb_filetest_s_exist_p, MRB_ARGS_REQ(1));
373 mrb_define_class_method(mrb, f, "exists?", mrb_filetest_s_exist_p, MRB_ARGS_REQ(1));
374 mrb_define_class_method(mrb, f, "file?", mrb_filetest_s_file_p, MRB_ARGS_REQ(1));
375 mrb_define_class_method(mrb, f, "pipe?", mrb_filetest_s_pipe_p, MRB_ARGS_REQ(1));
376 mrb_define_class_method(mrb, f, "size", mrb_filetest_s_size, MRB_ARGS_REQ(1));
377 mrb_define_class_method(mrb, f, "size?", mrb_filetest_s_size_p, MRB_ARGS_REQ(1));
378 mrb_define_class_method(mrb, f, "socket?", mrb_filetest_s_socket_p, MRB_ARGS_REQ(1));
379 mrb_define_class_method(mrb, f, "symlink?", mrb_filetest_s_symlink_p, MRB_ARGS_REQ(1));
380 mrb_define_class_method(mrb, f, "zero?", mrb_filetest_s_zero_p, MRB_ARGS_REQ(1));