Commit b4f0a68f authored by Tomoyuki Sahara's avatar Tomoyuki Sahara

add File#flock.

parent 140da1c6
......@@ -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 | |
......
......@@ -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));
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment