diff options
| author | Tomoyuki Sahara <[email protected]> | 2013-09-30 10:17:21 +0900 |
|---|---|---|
| committer | Tomoyuki Sahara <[email protected]> | 2013-09-30 10:17:21 +0900 |
| commit | b4f0a68fba4b222461ca79feb94d94e325341129 (patch) | |
| tree | f63fc3799c9605a15f20168148f50fdec82beb9a | |
| parent | 140da1c6caf1ba98f961470a1d87ba7e14f0fb25 (diff) | |
| download | mruby-b4f0a68fba4b222461ca79feb94d94e325341129.tar.gz mruby-b4f0a68fba4b222461ca79feb94d94e325341129.zip | |
add File#flock.
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | src/file.c | 35 | ||||
| -rw-r--r-- | test/file.rb | 11 |
3 files changed, 47 insertions, 1 deletions
@@ -176,7 +176,7 @@ DEALINGS IN THE SOFTWARE. | File#chmod | | | | File#chown | | | | File#ctime | | | -| File#flock | | | +| File#flock | o | | | File#lstat | | | | File#mtime | | | | File#path, File#to_path | o | | diff --git a/src/file.c b/src/file.c index 0fed5b21a..5c46aa965 100644 --- a/src/file.c +++ b/src/file.c @@ -36,6 +36,9 @@ #define STAT(p, s) stat(p, s) +extern mrb_value mrb_io_fileno(mrb_state *mrb, mrb_value io); + + mrb_value mrb_file_s_umask(mrb_state *mrb, mrb_value klass) { @@ -262,6 +265,36 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass) return mrb_str_new_cstr(mrb, home); } +mrb_value +mrb_file_flock(mrb_state *mrb, mrb_value self) +{ + mrb_int operation; + int fd; + + mrb_get_args(mrb, "i", &operation); + fd = mrb_fixnum(mrb_io_fileno(mrb, self)); + + while (flock(fd, operation) == -1) { + switch (errno) { + case EINTR: + /* retry */ + break; + case EAGAIN: /* NetBSD */ +#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: /* FreeBSD OpenBSD Linux */ +#endif + if (operation & LOCK_NB) { + return mrb_false_value(); + } + /* FALLTHRU - should not happen */ + default: + mrb_sys_fail(mrb, "flock failed"); + break; + } + } + return mrb_fixnum_value(0); +} + void mrb_init_file(mrb_state *mrb) { @@ -282,6 +315,8 @@ mrb_init_file(mrb_state *mrb) mrb_define_class_method(mrb, file, "_getwd", mrb_file__getwd, MRB_ARGS_NONE()); mrb_define_class_method(mrb, file, "_gethome", mrb_file__gethome, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, file, "flock", mrb_file_flock, MRB_ARGS_REQ(1)); + cnst = mrb_define_module_under(mrb, file, "Constants"); mrb_define_const(mrb, cnst, "LOCK_SH", mrb_fixnum_value(LOCK_SH)); mrb_define_const(mrb, cnst, "LOCK_EX", mrb_fixnum_value(LOCK_EX)); diff --git a/test/file.rb b/test/file.rb index 8fe7636e0..4b3458d1a 100644 --- a/test/file.rb +++ b/test/file.rb @@ -49,6 +49,17 @@ assert('File.extname') do assert_equal '', File.extname('.foo') end +assert('IO#flock') do + f = File.open $mrbtest_io_rfname + assert_equal(f.flock(File::LOCK_SH), 0) + assert_equal(f.flock(File::LOCK_UN), 0) + assert_equal(f.flock(File::LOCK_EX | File::LOCK_UN), 0) + assert_equal(f.flock(File::LOCK_UN), 0) + f.close + true +end + + assert('File.size') do File.size($mrbtest_io_rfname) == $mrbtest_io_msg.size + 1 and File.size($mrbtest_io_wfname) == 0 |
