[ANN] posixlock

SYNOPSIS:
posixlock
use fcntl (vs. flock) based locking for File#flock

USAGE
require ‘posixlock’ # replaces File#flock!

i currently do not have a place to post software - so here’s a little
extension that replaces flock with an fcntl based impl for posix compliant
locking (safe on nfs) - posted to c.l.r for posterity:

extconf.rb

···

================
require ‘mkmf’
create_makefile ‘posixlock’

posixlock.c

#ifdef _WIN32
#include “missing/file.h”
#endif

#include “ruby.h”
#include “rubyio.h”
#include “rubysig.h”

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif

#include <errno.h>

extern VALUE rb_cFile;

ifndef LOCK_SH

define LOCK_SH 1

endif

ifndef LOCK_EX

define LOCK_EX 2

endif

ifndef LOCK_NB

define LOCK_NB 4

endif

ifndef LOCK_UN

define LOCK_UN 8

endif

static int
posixlock (fd, operation)
int fd;
int operation;
{
struct flock lock;

switch (operation & ~LOCK_NB)
{
case LOCK_SH:
lock.l_type = F_RDLCK;
break;
case LOCK_EX:
lock.l_type = F_WRLCK;
break;
case LOCK_UN:
lock.l_type = F_UNLCK;
break;
default:
errno = EINVAL;
return -1;
}
lock.l_whence = SEEK_SET;
lock.l_start = lock.l_len = 0L;
return fcntl (fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &lock);
}

static VALUE
rb_file_posixlock (obj, operation)
VALUE obj;
VALUE operation;
{
#ifndef CHECKER
OpenFile *fptr;
int ret;

rb_secure (2);
GetOpenFile (obj, fptr);

if (fptr->mode & FMODE_WRITABLE)
{
fflush (GetWriteFile (fptr));
}
retry:
TRAP_BEG;
ret = posixlock (fileno (fptr->f), NUM2INT (operation));
TRAP_END;
if (ret < 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);
}

void
Init_posixlock()
{
rb_define_method(rb_cFile, “flock”, rb_file_posixlock, 1);
}

-a

ATTN: please update your address books with address below!

===============================================================================

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
STP :: Solar-Terrestrial Physics Data | NCEI
NGDC :: http://www.ngdc.noaa.gov/
NESDIS :: http://www.nesdis.noaa.gov/
NOAA :: http://www.noaa.gov/
US DOC :: http://www.commerce.gov/

The difference between art and science is that science is what we
understand well enough to explain to a computer.
Art is everything else.
– Donald Knuth, “Discover”

/bin/sh -c ‘for l in ruby perl;do $l -e “print "\x3a\x2d\x29\x0a"”;done’
===============================================================================

Hi!

  • Ara.T.Howard; 2003-12-05, 22:45 UTC:

i currently do not have a place to post software - so here’s a
little extension that replaces flock with an fcntl based impl for
posix compliant locking (safe on nfs) - posted to c.l.r for
posterity:

Why don’t you use one of those free web space providers? If you
rename file_foo.rb to file_foo.rb.txt or put it into a zip file you
won’t have any problems (some of these systems seem to run Windhoos
where ‘.rb’ can run you into trouble).

Josef ‘Jupp’ SCHUGT

···


http://oss.erdfunkstelle.de/ruby/ - German comp.lang.ruby-FAQ
http://rubyforge.org/users/jupp/ - Ruby projects at Rubyforge

Ara.T.Howard wrote:

SYNOPSIS:
posixlock
use fcntl (vs. flock) based locking for File#flock

Thanks for that–I’ve been needing it for my fsdb projet! Ok to use it
under the ruby license (with attribution and copyright to you, of course)?

Suggestion, if you ever package it up somewhere: call it File#posixlock,
#plock, #pflock, #fcntl_lock, or whatever, and let users alias it in for
#flock or use it under its own name without replacing #flock. (In my
local copy I named it fcntl_lock.)