Hi,
I don't feel very well when I have to write code like this:
File.open "somefile", "a" do |f|
f.flock File::LOCK_EX
f.print ...
f.flock File::LOCK_UN
end
Rather, I would prefer
File.open "somefile", "a" do |f|
f.flock File::LOCK_EX do
f.print ...
end
end
My primary problem is how to handle exceptions that occur
while writing to the file.
A solution could be implemented easily by extending the
`rb_file_flock' function in `file.c'. I'm posting the code
below. Maybe you have any idea how to improve it.
What would you think, is it worth a consideration?
Bertram
--->---
static VALUE
file_flock(VALUE obj, VALUE operation)
{
#ifndef __CHECKER__
OpenFile *fptr;
int op;
rb_secure(2);
op = NUM2INT(operation);
GetOpenFile(obj, fptr);
if (fptr->mode & FMODE_WRITABLE) {
rb_io_flush(obj);
}
retry:
if (flock(fptr->fd, op) < 0) {
switch (errno) {
case EAGAIN:
case EACCES:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif
return Qfalse;
case EINTR:
#if defined(ERESTART)
case ERESTART:
#endif
goto retry;
}
rb_sys_fail(fptr->path);
}
#endif
return INT2FIX(0);
}
static VALUE
file_flock_un(VALUE obj)
{
#ifndef __CHECKER__
OpenFile *fptr;
rb_secure(2);
GetOpenFile(obj, fptr);
if (flock(fptr->fd, LOCK_UN) < 0) {
rb_sys_fail(fptr->path);
}
#endif
return INT2FIX(0);
}
static VALUE
rb_file_flock(VALUE obj, VALUE operation)
{
if (rb_block_given_p()) {
file_flock(obj, operation);
rb_ensure( rb_yield, obj, file_flock_un, obj);
} else
file_flock(obj, operation);
return INT2FIX(0);
}
---<---
--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de