source: EcnlProtoTool/trunk/mrbgems/mruby-io/src/file_test.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 7.8 KB
Line 
1/*
2** file.c - File class
3*/
4
5#include "mruby.h"
6#include "mruby/class.h"
7#include "mruby/data.h"
8#include "mruby/string.h"
9#include "mruby/ext/io.h"
10
11#if MRUBY_RELEASE_NO < 10000
12#include "error.h"
13#else
14#include "mruby/error.h"
15#endif
16
17#include <sys/types.h>
18#include <sys/stat.h>
19
20#if defined(_WIN32) || defined(_WIN64)
21 #define LSTAT stat
22 #include <winsock.h>
23#else
24 #define LSTAT lstat
25 #include <sys/file.h>
26 #include <sys/param.h>
27 #include <sys/wait.h>
28 #include <libgen.h>
29 #include <pwd.h>
30 #include <unistd.h>
31#endif
32
33#include <fcntl.h>
34
35#include <errno.h>
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39
40extern struct mrb_data_type mrb_io_type;
41
42static int
43mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat)
44{
45 mrb_value tmp;
46 mrb_value io_klass, str_klass;
47
48 io_klass = mrb_obj_value(mrb_class_get(mrb, "IO"));
49 str_klass = mrb_obj_value(mrb_class_get(mrb, "String"));
50
51 tmp = mrb_funcall(mrb, obj, "is_a?", 1, io_klass);
52 if (mrb_test(tmp)) {
53 struct mrb_io *fptr;
54 fptr = (struct mrb_io *)mrb_get_datatype(mrb, obj, &mrb_io_type);
55
56 if (fptr && fptr->fd >= 0) {
57 return fstat(fptr->fd, st);
58 }
59
60 mrb_raise(mrb, E_IO_ERROR, "closed stream");
61 return -1;
62 }
63
64 tmp = mrb_funcall(mrb, obj, "is_a?", 1, str_klass);
65 if (mrb_test(tmp)) {
66 if (do_lstat) {
67 return LSTAT(mrb_str_to_cstr(mrb, obj), st);
68 } else {
69 return stat(mrb_str_to_cstr(mrb, obj), st);
70 }
71 }
72
73 return -1;
74}
75
76static int
77mrb_stat(mrb_state *mrb, mrb_value obj, struct stat *st)
78{
79 return mrb_stat0(mrb, obj, st, 0);
80}
81
82static int
83mrb_lstat(mrb_state *mrb, mrb_value obj, struct stat *st)
84{
85 return mrb_stat0(mrb, obj, st, 1);
86}
87
88/*
89 * Document-method: directory?
90 *
91 * call-seq:
92 * File.directory?(file_name) -> true or false
93 *
94 * Returns <code>true</code> if the named file is a directory,
95 * or a symlink that points at a directory, and <code>false</code>
96 * otherwise.
97 *
98 * File.directory?(".")
99 */
100
101mrb_value
102mrb_filetest_s_directory_p(mrb_state *mrb, mrb_value klass)
103{
104#ifndef S_ISDIR
105# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
106#endif
107
108 struct stat st;
109 mrb_value obj;
110
111 mrb_get_args(mrb, "o", &obj);
112
113 if (mrb_stat(mrb, obj, &st) < 0)
114 return mrb_false_value();
115 if (S_ISDIR(st.st_mode))
116 return mrb_true_value();
117
118 return mrb_false_value();
119}
120
121/*
122 * call-seq:
123 * File.pipe?(file_name) -> true or false
124 *
125 * Returns <code>true</code> if the named file is a pipe.
126 */
127
128mrb_value
129mrb_filetest_s_pipe_p(mrb_state *mrb, mrb_value klass)
130{
131#if defined(_WIN32) || defined(_WIN64)
132 mrb_raise(mrb, E_NOTIMP_ERROR, "pipe is not supported on this platform");
133#else
134#ifdef S_IFIFO
135# ifndef S_ISFIFO
136# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
137# endif
138
139 struct stat st;
140 mrb_value obj;
141
142 mrb_get_args(mrb, "o", &obj);
143
144 if (mrb_stat(mrb, obj, &st) < 0)
145 return mrb_false_value();
146 if (S_ISFIFO(st.st_mode))
147 return mrb_true_value();
148
149#endif
150 return mrb_false_value();
151#endif
152}
153
154/*
155 * call-seq:
156 * File.symlink?(file_name) -> true or false
157 *
158 * Returns <code>true</code> if the named file is a symbolic link.
159 */
160
161mrb_value
162mrb_filetest_s_symlink_p(mrb_state *mrb, mrb_value klass)
163{
164#if defined(_WIN32) || defined(_WIN64)
165 mrb_raise(mrb, E_NOTIMP_ERROR, "symlink is not supported on this platform");
166#else
167#ifndef S_ISLNK
168# ifdef _S_ISLNK
169# define S_ISLNK(m) _S_ISLNK(m)
170# else
171# ifdef _S_IFLNK
172# define S_ISLNK(m) (((m) & S_IFMT) == _S_IFLNK)
173# else
174# ifdef S_IFLNK
175# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
176# endif
177# endif
178# endif
179#endif
180
181#ifdef S_ISLNK
182 struct stat st;
183 mrb_value obj;
184
185 mrb_get_args(mrb, "o", &obj);
186
187 if (mrb_lstat(mrb, obj, &st) == -1)
188 return mrb_false_value();
189 if (S_ISLNK(st.st_mode))
190 return mrb_true_value();
191#endif
192
193 return mrb_false_value();
194#endif
195}
196
197/*
198 * call-seq:
199 * File.socket?(file_name) -> true or false
200 *
201 * Returns <code>true</code> if the named file is a socket.
202 */
203
204mrb_value
205mrb_filetest_s_socket_p(mrb_state *mrb, mrb_value klass)
206{
207#if defined(_WIN32) || defined(_WIN64)
208 mrb_raise(mrb, E_NOTIMP_ERROR, "socket is not supported on this platform");
209#else
210#ifndef S_ISSOCK
211# ifdef _S_ISSOCK
212# define S_ISSOCK(m) _S_ISSOCK(m)
213# else
214# ifdef _S_IFSOCK
215# define S_ISSOCK(m) (((m) & S_IFMT) == _S_IFSOCK)
216# else
217# ifdef S_IFSOCK
218# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
219# endif
220# endif
221# endif
222#endif
223
224#ifdef S_ISSOCK
225 struct stat st;
226 mrb_value obj;
227
228 mrb_get_args(mrb, "o", &obj);
229
230 if (mrb_stat(mrb, obj, &st) < 0)
231 return mrb_false_value();
232 if (S_ISSOCK(st.st_mode))
233 return mrb_true_value();
234#endif
235
236 return mrb_false_value();
237#endif
238}
239
240/*
241 * call-seq:
242 * File.exist?(file_name) -> true or false
243 * File.exists?(file_name) -> true or false
244 *
245 * Return <code>true</code> if the named file exists.
246 */
247
248mrb_value
249mrb_filetest_s_exist_p(mrb_state *mrb, mrb_value klass)
250{
251 struct stat st;
252 mrb_value obj;
253
254 mrb_get_args(mrb, "o", &obj);
255 if (mrb_stat(mrb, obj, &st) < 0)
256 return mrb_false_value();
257
258 return mrb_true_value();
259}
260
261/*
262 * call-seq:
263 * File.file?(file_name) -> true or false
264 *
265 * Returns <code>true</code> if the named file exists and is a
266 * regular file.
267 */
268
269mrb_value
270mrb_filetest_s_file_p(mrb_state *mrb, mrb_value klass)
271{
272#ifndef S_ISREG
273# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
274#endif
275
276 struct stat st;
277 mrb_value obj;
278
279 mrb_get_args(mrb, "o", &obj);
280
281 if (mrb_stat(mrb, obj, &st) < 0)
282 return mrb_false_value();
283 if (S_ISREG(st.st_mode))
284 return mrb_true_value();
285
286 return mrb_false_value();
287}
288
289/*
290 * call-seq:
291 * File.zero?(file_name) -> true or false
292 *
293 * Returns <code>true</code> if the named file exists and has
294 * a zero size.
295 */
296
297mrb_value
298mrb_filetest_s_zero_p(mrb_state *mrb, mrb_value klass)
299{
300 struct stat st;
301 mrb_value obj;
302
303 mrb_get_args(mrb, "o", &obj);
304
305 if (mrb_stat(mrb, obj, &st) < 0)
306 return mrb_false_value();
307 if (st.st_size == 0)
308 return mrb_true_value();
309
310 return mrb_false_value();
311}
312
313/*
314 * call-seq:
315 * File.size(file_name) -> integer
316 *
317 * Returns the size of <code>file_name</code>.
318 *
319 * _file_name_ can be an IO object.
320 */
321
322mrb_value
323mrb_filetest_s_size(mrb_state *mrb, mrb_value klass)
324{
325 struct stat st;
326 mrb_value obj;
327
328 mrb_get_args(mrb, "o", &obj);
329
330 if (mrb_stat(mrb, obj, &st) < 0)
331 mrb_sys_fail(mrb, "mrb_stat");
332
333 return mrb_fixnum_value(st.st_size);
334}
335
336/*
337 * call-seq:
338 * File.size?(file_name) -> Integer or nil
339 *
340 * Returns +nil+ if +file_name+ doesn't exist or has zero size, the size of the
341 * file otherwise.
342 */
343
344mrb_value
345mrb_filetest_s_size_p(mrb_state *mrb, mrb_value klass)
346{
347 struct stat st;
348 mrb_value obj;
349
350 mrb_get_args(mrb, "o", &obj);
351
352 if (mrb_stat(mrb, obj, &st) < 0)
353 return mrb_nil_value();
354 if (st.st_size == 0)
355 return mrb_nil_value();
356
357 return mrb_fixnum_value(st.st_size);
358}
359
360void
361mrb_init_file_test(mrb_state *mrb)
362{
363 struct RClass *f;
364
365 f = mrb_define_class(mrb, "FileTest", mrb->object_class);
366
367 mrb_define_class_method(mrb, f, "directory?", mrb_filetest_s_directory_p, MRB_ARGS_REQ(1));
368 mrb_define_class_method(mrb, f, "exist?", mrb_filetest_s_exist_p, MRB_ARGS_REQ(1));
369 mrb_define_class_method(mrb, f, "exists?", mrb_filetest_s_exist_p, MRB_ARGS_REQ(1));
370 mrb_define_class_method(mrb, f, "file?", mrb_filetest_s_file_p, MRB_ARGS_REQ(1));
371 mrb_define_class_method(mrb, f, "pipe?", mrb_filetest_s_pipe_p, MRB_ARGS_REQ(1));
372 mrb_define_class_method(mrb, f, "size", mrb_filetest_s_size, MRB_ARGS_REQ(1));
373 mrb_define_class_method(mrb, f, "size?", mrb_filetest_s_size_p, MRB_ARGS_REQ(1));
374 mrb_define_class_method(mrb, f, "socket?", mrb_filetest_s_socket_p, MRB_ARGS_REQ(1));
375 mrb_define_class_method(mrb, f, "symlink?", mrb_filetest_s_symlink_p, MRB_ARGS_REQ(1));
376 mrb_define_class_method(mrb, f, "zero?", mrb_filetest_s_zero_p, MRB_ARGS_REQ(1));
377}
Note: See TracBrowser for help on using the repository browser.