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