/*
* libfilo - A File Locking Library
* Alberto Bertogli (albertogli@telpin.com.ar)
*/
#ifndef _LIBFILO_H
#define _LIBFILO_H
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h> /* because filo_plockf() uses the same constants as
* lockf() */
/* Check if we're using Large File Support - otherwise refuse to build.
* Otherwise, we would allow applications not using LFS to link with the
* library (which uses LFS) and that's just begging for problems. There should
* be a portable way for the C library to do some of this for us, but until I
* find one, this is the best we can do */
#if (!defined _FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS != 64)
#error "You must compile your application with Large File Support"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* locking modes */
#define FL_RD_MODE 0
#define FL_WR_MODE 1
/* locking modes for filo_plockf() */
#define _FL_READ 0x00001
#define _FL_WRITE 0x00010
#define _FL_LOCK 0x00100
#define _FL_TLOCK 0x01000
#define _FL_ULOCK 0x10000
#define FL_LOCKR (_FL_LOCK | _FL_READ)
#define FL_LOCKW (_FL_LOCK | _FL_WRITE)
#define FL_TLOCKR (_FL_TLOCK | _FL_READ)
#define FL_TLOCKW (_FL_TLOCK | _FL_WRITE)
#define FL_ULOCK (_FL_ULOCK)
/* a single locked range */
struct locked_range {
off_t start;
off_t end;
int mode;
pthread_t owner;
struct locked_range *next;
struct locked_range *prev;
};
/* a range waiting for read or write */
struct waiter_range {
off_t start;
off_t end;
int mode;
pthread_t owner;
sem_t sem;
struct waiter_range *next;
struct waiter_range *prev;
};
/* a file lock */
typedef struct filo_flock_t {
struct locked_range *locked;
struct waiter_range *waiters;
pthread_mutex_t lock;
} filock_t;
int filo_init(filock_t *fl);
int filo_free(filock_t *fl);
int filo_lock(filock_t *fl, off_t start, off_t len, int mode);
int filo_trylock(filock_t *fl, off_t start, off_t len, int mode);
int filo_unlock(filock_t *fl, off_t start, off_t len);
int filo_plockf(filock_t *fl, int cmd, off_t start, off_t len);
#ifdef __cplusplus
} /* from extern "C" avobe */
#endif
#endif