source: EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-io/src/file.c@ 439

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

mrubyを2.1.1に更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 18.6 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#include "mruby/error.h"
11
12#include <sys/types.h>
13#if !defined(AZURE_SPHERE)
14#include <sys/stat.h>
15#else
16mode_t umask(mode_t);
17int chmod(const char *, mode_t);
18#endif
19
20#include <fcntl.h>
21#include <limits.h>
22
23#include <errno.h>
24#include <stdlib.h>
25#include <string.h>
26#if defined(_WIN32) || defined(_WIN64)
27 #include <windows.h>
28 #include <io.h>
29 #define NULL_FILE "NUL"
30 #define UNLINK _unlink
31 #define GETCWD _getcwd
32 #define CHMOD(a, b) 0
33 #define MAXPATHLEN 1024
34 #if !defined(PATH_MAX)
35 #define PATH_MAX _MAX_PATH
36 #endif
37 #define realpath(N,R) _fullpath((R),(N),_MAX_PATH)
38 #include <direct.h>
39#else
40 #define NULL_FILE "/dev/null"
41 #include <unistd.h>
42 #define UNLINK unlink
43 #define GETCWD getcwd
44 #define CHMOD(a, b) chmod(a,b)
45#if !defined(AZURE_SPHERE)
46 #include <sys/file.h>
47 #include <libgen.h>
48#else
49char *basename(char *);
50#endif
51 #include <sys/param.h>
52#if !defined(AZURE_SPHERE)
53 #include <pwd.h>
54#endif
55#endif
56
57#if defined(AZURE_SPHERE)
58 #include <time.h>
59int unlink(const char *);
60ssize_t readlink(const char *__restrict, char *__restrict, size_t);
61int symlink(const char *, const char *);
62int rename(const char *, const char *);
63int ftruncate(int, off_t);
64char *realpath (const char *__restrict, char *__restrict);
65char *getcwd(char *, size_t);
66struct passwd {
67 char *pw_dir;
68};
69struct passwd *getpwnam (const char *);
70struct stat {
71 mode_t st_mode;
72 struct timespec st_mtim;
73 off_t st_size;
74};
75#define st_mtime st_mtim.tv_sec
76int fstat(int, struct stat *);
77int flock(int, int);
78char *dirname(char *);
79#endif
80
81#define FILE_SEPARATOR "/"
82
83#if defined(_WIN32) || defined(_WIN64)
84 #define PATH_SEPARATOR ";"
85 #define FILE_ALT_SEPARATOR "\\"
86 #define VOLUME_SEPARATOR ":"
87#else
88 #define PATH_SEPARATOR ":"
89#endif
90
91#ifndef LOCK_SH
92#define LOCK_SH 1
93#endif
94#ifndef LOCK_EX
95#define LOCK_EX 2
96#endif
97#ifndef LOCK_NB
98#define LOCK_NB 4
99#endif
100#ifndef LOCK_UN
101#define LOCK_UN 8
102#endif
103
104#ifndef _WIN32
105typedef struct stat mrb_stat;
106# define mrb_stat(path, sb) stat(path, sb)
107# define mrb_fstat(fd, sb) fstat(fd, sb)
108#else
109typedef struct __stat64 mrb_stat;
110# define mrb_stat(path, sb) _stat64(path, sb)
111# define mrb_fstat(fd, sb) _fstat64(fd, sb)
112#endif
113
114#ifdef _WIN32
115static int
116flock(int fd, int operation) {
117 OVERLAPPED ov;
118 HANDLE h = (HANDLE)_get_osfhandle(fd);
119 DWORD flags;
120 flags = ((operation & LOCK_NB) ? LOCKFILE_FAIL_IMMEDIATELY : 0)
121 | ((operation & LOCK_SH) ? LOCKFILE_EXCLUSIVE_LOCK : 0);
122 memset(&ov, 0, sizeof(ov));
123 return LockFileEx(h, flags, 0, 0xffffffff, 0xffffffff, &ov) ? 0 : -1;
124}
125#endif
126
127mrb_value
128mrb_file_s_umask(mrb_state *mrb, mrb_value klass)
129{
130#if defined(_WIN32) || defined(_WIN64)
131 /* nothing to do on windows */
132 return mrb_fixnum_value(0);
133
134#else
135 mrb_int mask, omask;
136 if (mrb_get_args(mrb, "|i", &mask) == 0) {
137 omask = umask(0);
138 umask(omask);
139 } else {
140 omask = umask(mask);
141 }
142 return mrb_fixnum_value(omask);
143#endif
144}
145
146static mrb_value
147mrb_file_s_unlink(mrb_state *mrb, mrb_value obj)
148{
149 mrb_value *argv;
150 mrb_value pathv;
151 mrb_int argc, i;
152 char *path;
153
154 mrb_get_args(mrb, "*", &argv, &argc);
155 for (i = 0; i < argc; i++) {
156 const char *utf8_path;
157 pathv = mrb_ensure_string_type(mrb, argv[i]);
158 utf8_path = RSTRING_CSTR(mrb, pathv);
159 path = mrb_locale_from_utf8(utf8_path, -1);
160 if (UNLINK(path) < 0) {
161 mrb_locale_free(path);
162 mrb_sys_fail(mrb, utf8_path);
163 }
164 mrb_locale_free(path);
165 }
166 return mrb_fixnum_value(argc);
167}
168
169static mrb_value
170mrb_file_s_rename(mrb_state *mrb, mrb_value obj)
171{
172 mrb_value from, to;
173 char *src, *dst;
174
175 mrb_get_args(mrb, "SS", &from, &to);
176 src = mrb_locale_from_utf8(RSTRING_CSTR(mrb, from), -1);
177 dst = mrb_locale_from_utf8(RSTRING_CSTR(mrb, to), -1);
178 if (rename(src, dst) < 0) {
179#if defined(_WIN32) || defined(_WIN64)
180 if (CHMOD(dst, 0666) == 0 && UNLINK(dst) == 0 && rename(src, dst) == 0) {
181 mrb_locale_free(src);
182 mrb_locale_free(dst);
183 return mrb_fixnum_value(0);
184 }
185#endif
186 mrb_locale_free(src);
187 mrb_locale_free(dst);
188 mrb_sys_fail(mrb, RSTRING_CSTR(mrb, mrb_format(mrb, "(%v, %v)", from, to)));
189 return mrb_fixnum_value(-1); /* not reached */
190 }
191 mrb_locale_free(src);
192 mrb_locale_free(dst);
193 return mrb_fixnum_value(0);
194}
195
196static mrb_value
197mrb_file_dirname(mrb_state *mrb, mrb_value klass)
198{
199#if defined(_WIN32) || defined(_WIN64)
200 char dname[_MAX_DIR], vname[_MAX_DRIVE];
201 char buffer[_MAX_DRIVE + _MAX_DIR];
202 const char *utf8_path;
203 char *path;
204 size_t ridx;
205 mrb_get_args(mrb, "z", &utf8_path);
206 path = mrb_locale_from_utf8(utf8_path, -1);
207 _splitpath(path, vname, dname, NULL, NULL);
208 snprintf(buffer, _MAX_DRIVE + _MAX_DIR, "%s%s", vname, dname);
209 mrb_locale_free(path);
210 ridx = strlen(buffer);
211 if (ridx == 0) {
212 strncpy(buffer, ".", 2); /* null terminated */
213 } else if (ridx > 1) {
214 ridx--;
215 while (ridx > 0 && (buffer[ridx] == '/' || buffer[ridx] == '\\')) {
216 buffer[ridx] = '\0'; /* remove last char */
217 ridx--;
218 }
219 }
220 return mrb_str_new_cstr(mrb, buffer);
221#else
222 char *dname, *path;
223 mrb_value s;
224 mrb_get_args(mrb, "S", &s);
225 path = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, s), -1);
226
227 if ((dname = dirname(path)) == NULL) {
228 mrb_locale_free(path);
229 mrb_sys_fail(mrb, "dirname");
230 }
231 mrb_locale_free(path);
232 return mrb_str_new_cstr(mrb, dname);
233#endif
234}
235
236static mrb_value
237mrb_file_basename(mrb_state *mrb, mrb_value klass)
238{
239 // NOTE: Do not use mrb_locale_from_utf8 here
240#if defined(_WIN32) || defined(_WIN64)
241 char bname[_MAX_DIR];
242 char extname[_MAX_EXT];
243 char *path;
244 size_t ridx;
245 char buffer[_MAX_DIR + _MAX_EXT];
246 mrb_value s;
247
248 mrb_get_args(mrb, "S", &s);
249 path = mrb_str_to_cstr(mrb, s);
250 ridx = strlen(path);
251 if (ridx > 0) {
252 ridx--;
253 while (ridx > 0 && (path[ridx] == '/' || path[ridx] == '\\')) {
254 path[ridx] = '\0';
255 ridx--;
256 }
257 if (strncmp(path, "/", 2) == 0) {
258 return mrb_str_new_cstr(mrb, path);
259 }
260 }
261 _splitpath((const char*)path, NULL, NULL, bname, extname);
262 snprintf(buffer, _MAX_DIR + _MAX_EXT, "%s%s", bname, extname);
263 return mrb_str_new_cstr(mrb, buffer);
264#else
265 char *bname, *path;
266 mrb_value s;
267 mrb_get_args(mrb, "S", &s);
268 path = mrb_str_to_cstr(mrb, s);
269 if ((bname = basename(path)) == NULL) {
270 mrb_sys_fail(mrb, "basename");
271 }
272 if (strncmp(bname, "//", 3) == 0) bname[1] = '\0'; /* patch for Cygwin */
273 return mrb_str_new_cstr(mrb, bname);
274#endif
275}
276
277static mrb_value
278mrb_file_realpath(mrb_state *mrb, mrb_value klass)
279{
280 mrb_value pathname, dir_string, s, result;
281 mrb_int argc;
282 char *cpath;
283
284 argc = mrb_get_args(mrb, "S|S", &pathname, &dir_string);
285 if (argc == 2) {
286 s = mrb_str_dup(mrb, dir_string);
287 s = mrb_str_append(mrb, s, mrb_str_new_cstr(mrb, FILE_SEPARATOR));
288 s = mrb_str_append(mrb, s, pathname);
289 pathname = s;
290 }
291 cpath = mrb_locale_from_utf8(RSTRING_CSTR(mrb, pathname), -1);
292 result = mrb_str_buf_new(mrb, PATH_MAX);
293 if (realpath(cpath, RSTRING_PTR(result)) == NULL) {
294 mrb_locale_free(cpath);
295 mrb_sys_fail(mrb, cpath);
296 return result; /* not reached */
297 }
298 mrb_locale_free(cpath);
299 mrb_str_resize(mrb, result, strlen(RSTRING_PTR(result)));
300 return result;
301}
302
303mrb_value
304mrb_file__getwd(mrb_state *mrb, mrb_value klass)
305{
306 mrb_value path;
307 char buf[MAXPATHLEN], *utf8;
308
309 if (GETCWD(buf, MAXPATHLEN) == NULL) {
310 mrb_sys_fail(mrb, "getcwd(2)");
311 }
312 utf8 = mrb_utf8_from_locale(buf, -1);
313 path = mrb_str_new_cstr(mrb, utf8);
314 mrb_utf8_free(utf8);
315 return path;
316}
317
318#ifdef _WIN32
319#define IS_FILESEP(x) (x == (*(char*)(FILE_SEPARATOR)) || x == (*(char*)(FILE_ALT_SEPARATOR)))
320#define IS_VOLSEP(x) (x == (*(char*)(VOLUME_SEPARATOR)))
321#define IS_DEVICEID(x) (x == '.' || x == '?')
322#define CHECK_UNCDEV_PATH (IS_FILESEP(path[0]) && IS_FILESEP(path[1]))
323
324static int
325is_absolute_traditional_path(const char *path, size_t len)
326{
327 if (len < 3) return 0;
328 return (ISALPHA(path[0]) && IS_VOLSEP(path[1]) && IS_FILESEP(path[2]));
329}
330
331static int
332is_aboslute_unc_path(const char *path, size_t len) {
333 if (len < 2) return 0;
334 return (CHECK_UNCDEV_PATH && !IS_DEVICEID(path[2]));
335}
336
337static int
338is_absolute_device_path(const char *path, size_t len) {
339 if (len < 4) return 0;
340 return (CHECK_UNCDEV_PATH && IS_DEVICEID(path[2]) && IS_FILESEP(path[3]));
341}
342
343static int
344mrb_file_is_absolute_path(const char *path)
345{
346 size_t len = strlen(path);
347 if (IS_FILESEP(path[0])) return 1;
348 if (len > 0)
349 return (
350 is_absolute_traditional_path(path, len) ||
351 is_aboslute_unc_path(path, len) ||
352 is_absolute_device_path(path, len)
353 );
354 else
355 return 0;
356}
357
358#undef IS_FILESEP
359#undef IS_VOLSEP
360#undef IS_DEVICEID
361#undef CHECK_UNCDEV_PATH
362
363#else
364static int
365mrb_file_is_absolute_path(const char *path)
366{
367 return (path[0] == *(char*)(FILE_SEPARATOR));
368}
369#endif
370
371static mrb_value
372mrb_file__gethome(mrb_state *mrb, mrb_value klass)
373{
374 mrb_int argc;
375 char *home;
376 mrb_value path;
377
378#ifndef _WIN32
379 mrb_value username;
380
381 argc = mrb_get_args(mrb, "|S", &username);
382 if (argc == 0) {
383 home = getenv("HOME");
384 if (home == NULL) {
385 return mrb_nil_value();
386 }
387 if (!mrb_file_is_absolute_path(home)) {
388 mrb_raise(mrb, E_ARGUMENT_ERROR, "non-absolute home");
389 }
390 } else {
391 const char *cuser = RSTRING_CSTR(mrb, username);
392 struct passwd *pwd = getpwnam(cuser);
393 if (pwd == NULL) {
394 return mrb_nil_value();
395 }
396 home = pwd->pw_dir;
397 if (!mrb_file_is_absolute_path(home)) {
398 mrb_raisef(mrb, E_ARGUMENT_ERROR, "non-absolute home of ~%v", username);
399 }
400 }
401 home = mrb_locale_from_utf8(home, -1);
402 path = mrb_str_new_cstr(mrb, home);
403 mrb_locale_free(home);
404 return path;
405#else /* _WIN32 */
406 argc = mrb_get_argc(mrb);
407 if (argc == 0) {
408 home = getenv("USERPROFILE");
409 if (home == NULL) {
410 return mrb_nil_value();
411 }
412 if (!mrb_file_is_absolute_path(home)) {
413 mrb_raise(mrb, E_ARGUMENT_ERROR, "non-absolute home");
414 }
415 } else {
416 return mrb_nil_value();
417 }
418 home = mrb_locale_from_utf8(home, -1);
419 path = mrb_str_new_cstr(mrb, home);
420 mrb_locale_free(home);
421 return path;
422#endif
423}
424
425static mrb_value
426mrb_file_mtime(mrb_state *mrb, mrb_value self)
427{
428 mrb_value obj;
429 struct stat st;
430 int fd;
431
432 obj = mrb_obj_value(mrb_class_get(mrb, "Time"));
433 fd = mrb_io_fileno(mrb, self);
434 if (fstat(fd, &st) == -1)
435 return mrb_false_value();
436 return mrb_funcall(mrb, obj, "at", 1, mrb_fixnum_value(st.st_mtime));
437}
438
439mrb_value
440mrb_file_flock(mrb_state *mrb, mrb_value self)
441{
442#if defined(sun)
443 mrb_raise(mrb, E_NOTIMP_ERROR, "flock is not supported on Illumos/Solaris/Windows");
444#else
445 mrb_int operation;
446 int fd;
447
448 mrb_get_args(mrb, "i", &operation);
449 fd = mrb_io_fileno(mrb, self);
450
451 while (flock(fd, (int)operation) == -1) {
452 switch (errno) {
453 case EINTR:
454 /* retry */
455 break;
456 case EAGAIN: /* NetBSD */
457#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
458 case EWOULDBLOCK: /* FreeBSD OpenBSD Linux */
459#endif
460 if (operation & LOCK_NB) {
461 return mrb_false_value();
462 }
463 /* FALLTHRU - should not happen */
464 default:
465 mrb_sys_fail(mrb, "flock failed");
466 break;
467 }
468 }
469#endif
470 return mrb_fixnum_value(0);
471}
472
473static mrb_value
474mrb_file_size(mrb_state *mrb, mrb_value self)
475{
476 mrb_stat st;
477 int fd;
478
479 fd = mrb_io_fileno(mrb, self);
480 if (mrb_fstat(fd, &st) == -1) {
481 mrb_raise(mrb, E_RUNTIME_ERROR, "fstat failed");
482 }
483
484 if (st.st_size > MRB_INT_MAX) {
485#ifdef MRB_WITHOUT_FLOAT
486 mrb_raise(mrb, E_RUNTIME_ERROR, "File#size too large for MRB_WITHOUT_FLOAT");
487#else
488 return mrb_float_value(mrb, (mrb_float)st.st_size);
489#endif
490 }
491
492 return mrb_fixnum_value((mrb_int)st.st_size);
493}
494
495static int
496mrb_ftruncate(int fd, int64_t length)
497{
498#ifndef _WIN32
499 return ftruncate(fd, (off_t)length);
500#else
501 HANDLE file;
502 __int64 cur;
503
504 file = (HANDLE)_get_osfhandle(fd);
505 if (file == INVALID_HANDLE_VALUE) {
506 return -1;
507 }
508
509 cur = _lseeki64(fd, 0, SEEK_CUR);
510 if (cur == -1) return -1;
511
512 if (_lseeki64(fd, (__int64)length, SEEK_SET) == -1) return -1;
513
514 if (!SetEndOfFile(file)) {
515 errno = EINVAL; /* TODO: GetLastError to errno */
516 return -1;
517 }
518
519 if (_lseeki64(fd, cur, SEEK_SET) == -1) return -1;
520
521 return 0;
522#endif /* _WIN32 */
523}
524
525static mrb_value
526mrb_file_truncate(mrb_state *mrb, mrb_value self)
527{
528 int fd;
529 int64_t length;
530 mrb_value lenv;
531
532 fd = mrb_io_fileno(mrb, self);
533 mrb_get_args(mrb, "o", &lenv);
534 switch (mrb_type(lenv)) {
535#ifndef MRB_WITHOUT_FLOAT
536 case MRB_TT_FLOAT:
537 {
538 mrb_float lenf = mrb_float(lenv);
539 if (lenf > INT64_MAX) {
540 mrb_raise(mrb, E_ARGUMENT_ERROR, "length too large");
541 }
542 length = (int64_t)lenf;
543 }
544 break;
545#endif
546 case MRB_TT_FIXNUM:
547 default:
548 {
549 mrb_int leni = mrb_int(mrb, lenv);
550 length = (int64_t)leni;
551 }
552 break;
553 }
554
555 if (mrb_ftruncate(fd, length) != 0) {
556 mrb_raise(mrb, E_IO_ERROR, "ftruncate failed");
557 }
558
559 return mrb_fixnum_value(0);
560}
561
562static mrb_value
563mrb_file_s_symlink(mrb_state *mrb, mrb_value klass)
564{
565#if defined(_WIN32) || defined(_WIN64)
566 mrb_raise(mrb, E_NOTIMP_ERROR, "symlink is not supported on this platform");
567#else
568 mrb_value from, to;
569 const char *src, *dst;
570 int ai = mrb_gc_arena_save(mrb);
571
572 mrb_get_args(mrb, "SS", &from, &to);
573 src = mrb_locale_from_utf8(RSTRING_CSTR(mrb, from), -1);
574 dst = mrb_locale_from_utf8(RSTRING_CSTR(mrb, to), -1);
575 if (symlink(src, dst) == -1) {
576 mrb_locale_free(src);
577 mrb_locale_free(dst);
578 mrb_sys_fail(mrb, RSTRING_CSTR(mrb, mrb_format(mrb, "(%v, %v)", from, to)));
579 }
580 mrb_locale_free(src);
581 mrb_locale_free(dst);
582 mrb_gc_arena_restore(mrb, ai);
583#endif
584 return mrb_fixnum_value(0);
585}
586
587static mrb_value
588mrb_file_s_chmod(mrb_state *mrb, mrb_value klass) {
589 mrb_int mode;
590 mrb_int argc, i;
591 mrb_value *filenames;
592 int ai = mrb_gc_arena_save(mrb);
593
594 mrb_get_args(mrb, "i*", &mode, &filenames, &argc);
595 for (i = 0; i < argc; i++) {
596 const char *utf8_path = RSTRING_CSTR(mrb, filenames[i]);
597 char *path = mrb_locale_from_utf8(utf8_path, -1);
598 if (CHMOD(path, mode) == -1) {
599 mrb_locale_free(path);
600 mrb_sys_fail(mrb, utf8_path);
601 }
602 mrb_locale_free(path);
603 mrb_gc_arena_restore(mrb, ai);
604 }
605
606 return mrb_fixnum_value(argc);
607}
608
609static mrb_value
610mrb_file_s_readlink(mrb_state *mrb, mrb_value klass) {
611#if defined(_WIN32) || defined(_WIN64)
612 mrb_raise(mrb, E_NOTIMP_ERROR, "readlink is not supported on this platform");
613 return mrb_nil_value(); // unreachable
614#else
615 char *path, *buf, *tmp;
616 size_t bufsize = 100;
617 ssize_t rc;
618 mrb_value ret;
619 int ai = mrb_gc_arena_save(mrb);
620
621 mrb_get_args(mrb, "z", &path);
622 tmp = mrb_locale_from_utf8(path, -1);
623
624 buf = (char *)mrb_malloc(mrb, bufsize);
625 while ((rc = readlink(tmp, buf, bufsize)) == (ssize_t)bufsize && rc != -1) {
626 bufsize *= 2;
627 buf = (char *)mrb_realloc(mrb, buf, bufsize);
628 }
629 mrb_locale_free(tmp);
630 if (rc == -1) {
631 mrb_free(mrb, buf);
632 mrb_sys_fail(mrb, path);
633 }
634 tmp = mrb_utf8_from_locale(buf, -1);
635 ret = mrb_str_new(mrb, tmp, rc);
636 mrb_locale_free(tmp);
637 mrb_free(mrb, buf);
638
639 mrb_gc_arena_restore(mrb, ai);
640 return ret;
641#endif
642}
643
644void
645mrb_init_file(mrb_state *mrb)
646{
647 struct RClass *io, *file, *cnst;
648
649 io = mrb_class_get(mrb, "IO");
650 file = mrb_define_class(mrb, "File", io);
651 MRB_SET_INSTANCE_TT(file, MRB_TT_DATA);
652 mrb_define_class_method(mrb, file, "umask", mrb_file_s_umask, MRB_ARGS_OPT(1));
653 mrb_define_class_method(mrb, file, "delete", mrb_file_s_unlink, MRB_ARGS_ANY());
654 mrb_define_class_method(mrb, file, "unlink", mrb_file_s_unlink, MRB_ARGS_ANY());
655 mrb_define_class_method(mrb, file, "rename", mrb_file_s_rename, MRB_ARGS_REQ(2));
656 mrb_define_class_method(mrb, file, "symlink", mrb_file_s_symlink, MRB_ARGS_REQ(2));
657 mrb_define_class_method(mrb, file, "chmod", mrb_file_s_chmod, MRB_ARGS_REQ(1) | MRB_ARGS_REST());
658 mrb_define_class_method(mrb, file, "readlink", mrb_file_s_readlink, MRB_ARGS_REQ(1));
659
660 mrb_define_class_method(mrb, file, "dirname", mrb_file_dirname, MRB_ARGS_REQ(1));
661 mrb_define_class_method(mrb, file, "basename", mrb_file_basename, MRB_ARGS_REQ(1));
662 mrb_define_class_method(mrb, file, "realpath", mrb_file_realpath, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1));
663 mrb_define_class_method(mrb, file, "_getwd", mrb_file__getwd, MRB_ARGS_NONE());
664 mrb_define_class_method(mrb, file, "_gethome", mrb_file__gethome, MRB_ARGS_OPT(1));
665
666 mrb_define_method(mrb, file, "flock", mrb_file_flock, MRB_ARGS_REQ(1));
667 mrb_define_method(mrb, file, "mtime", mrb_file_mtime, MRB_ARGS_NONE());
668 mrb_define_method(mrb, file, "size", mrb_file_size, MRB_ARGS_NONE());
669 mrb_define_method(mrb, file, "truncate", mrb_file_truncate, MRB_ARGS_REQ(1));
670
671 cnst = mrb_define_module_under(mrb, file, "Constants");
672 mrb_define_const(mrb, cnst, "LOCK_SH", mrb_fixnum_value(LOCK_SH));
673 mrb_define_const(mrb, cnst, "LOCK_EX", mrb_fixnum_value(LOCK_EX));
674 mrb_define_const(mrb, cnst, "LOCK_UN", mrb_fixnum_value(LOCK_UN));
675 mrb_define_const(mrb, cnst, "LOCK_NB", mrb_fixnum_value(LOCK_NB));
676 mrb_define_const(mrb, cnst, "SEPARATOR", mrb_str_new_cstr(mrb, FILE_SEPARATOR));
677 mrb_define_const(mrb, cnst, "PATH_SEPARATOR", mrb_str_new_cstr(mrb, PATH_SEPARATOR));
678#if defined(_WIN32) || defined(_WIN64)
679 mrb_define_const(mrb, cnst, "ALT_SEPARATOR", mrb_str_new_cstr(mrb, FILE_ALT_SEPARATOR));
680#else
681 mrb_define_const(mrb, cnst, "ALT_SEPARATOR", mrb_nil_value());
682#endif
683 mrb_define_const(mrb, cnst, "NULL", mrb_str_new_cstr(mrb, NULL_FILE));
684
685 mrb_define_const(mrb, cnst, "RDONLY", mrb_fixnum_value(MRB_O_RDONLY));
686 mrb_define_const(mrb, cnst, "WRONLY", mrb_fixnum_value(MRB_O_WRONLY));
687 mrb_define_const(mrb, cnst, "RDWR", mrb_fixnum_value(MRB_O_RDWR));
688 mrb_define_const(mrb, cnst, "APPEND", mrb_fixnum_value(MRB_O_APPEND));
689 mrb_define_const(mrb, cnst, "CREAT", mrb_fixnum_value(MRB_O_CREAT));
690 mrb_define_const(mrb, cnst, "EXCL", mrb_fixnum_value(MRB_O_EXCL));
691 mrb_define_const(mrb, cnst, "TRUNC", mrb_fixnum_value(MRB_O_TRUNC));
692 mrb_define_const(mrb, cnst, "NONBLOCK", mrb_fixnum_value(MRB_O_NONBLOCK));
693 mrb_define_const(mrb, cnst, "NOCTTY", mrb_fixnum_value(MRB_O_NOCTTY));
694 mrb_define_const(mrb, cnst, "BINARY", mrb_fixnum_value(MRB_O_BINARY));
695 mrb_define_const(mrb, cnst, "SHARE_DELETE", mrb_fixnum_value(MRB_O_SHARE_DELETE));
696 mrb_define_const(mrb, cnst, "SYNC", mrb_fixnum_value(MRB_O_SYNC));
697 mrb_define_const(mrb, cnst, "DSYNC", mrb_fixnum_value(MRB_O_DSYNC));
698 mrb_define_const(mrb, cnst, "RSYNC", mrb_fixnum_value(MRB_O_RSYNC));
699 mrb_define_const(mrb, cnst, "NOFOLLOW", mrb_fixnum_value(MRB_O_NOFOLLOW));
700 mrb_define_const(mrb, cnst, "NOATIME", mrb_fixnum_value(MRB_O_NOATIME));
701 mrb_define_const(mrb, cnst, "DIRECT", mrb_fixnum_value(MRB_O_DIRECT));
702 mrb_define_const(mrb, cnst, "TMPFILE", mrb_fixnum_value(MRB_O_TMPFILE));
703}
Note: See TracBrowser for help on using the repository browser.