diff options
author | Jason Downs <downsj@downsj.com> | 2008-12-01 00:57:13 +0000 |
---|---|---|
committer | Jason Downs <downsj@downsj.com> | 2008-12-01 00:57:13 +0000 |
commit | 6732749a44326b5cbfc69d446c07367b0b3a3fc2 (patch) | |
tree | 9907e5dcd612cac7c542e540dd67e9619c31e9ce | |
parent | 30d03809f242c0e3d2f95d75cf27a69f49648563 (diff) | |
download | gdbm-6732749a44326b5cbfc69d446c07367b0b3a3fc2.tar.gz gdbm-6732749a44326b5cbfc69d446c07367b0b3a3fc2.tar.bz2 |
Finish up lock.c, adding error checking to see if a lock failed because it's
already locked. Also added gdbm_locked() to the API.
* src/lock.c: Check errno to see if a lock failed because it's already
locked. Add external gdbm_locked() routine to return the
status of locking. Move lock type to the dbf.
* src/gdbmdefs.h: Move lock type to the dbf.
* src/gdbm.proto: Add gdbm_export(), gdbm_import(), and gdbm_locked().
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | src/gdbm.proto | 3 | ||||
-rw-r--r-- | src/gdbmdefs.h | 4 | ||||
-rw-r--r-- | src/lock.c | 42 | ||||
-rw-r--r-- | src/proto.h | 1 |
5 files changed, 44 insertions, 14 deletions
@@ -1,3 +1,11 @@ +Sun Nov 30 16:48:29 PST 2008 Jason Downs (downsj@downsj.com) + + * src/lock.c: Check errno to see if a lock failed because it's already + locked. Add external gdbm_locked() routine to return the + status of locking. Move lock type to the dbf. + * src/gdbmdefs.h: Move lock type to the dbf. + * src/gdbm.proto: Add gdbm_export(), gdbm_import(), and gdbm_locked(). + 2008-11-30 Sergey Poznyakoff <gray@gnu.org.ua> * src/lock.c: Remove flock/flock64 distinction. diff --git a/src/gdbm.proto b/src/gdbm.proto index 17ac7cb..b159c56 100644 --- a/src/gdbm.proto +++ b/src/gdbm.proto @@ -99,6 +99,9 @@ extern void gdbm_sync __P((GDBM_FILE)); extern int gdbm_exists __P((GDBM_FILE, datum)); extern int gdbm_setopt __P((GDBM_FILE, int, int *, int)); extern int gdbm_fdesc __P((GDBM_FILE)); +extern int gdbm_locked __P((GDBM_FILE)); +extern int gdbm_export __P((GDBM_FILE, const char *, int, int)); +extern int gdbm_import __P((GDBM_FILE, const char *, int)); #if defined(__cplusplus) || defined(c_plusplus) } diff --git a/src/gdbmdefs.h b/src/gdbmdefs.h index f760b14..f1f3ee3 100644 --- a/src/gdbmdefs.h +++ b/src/gdbmdefs.h @@ -161,6 +161,10 @@ typedef struct { /* Whether or not we're allowing mmap() use. */ unsigned allow_mmap :1; + /* Type of file locking in use. */ + enum { LOCKING_NONE = 0, LOCKING_FLOCK, LOCKING_LOCKF, + LOCKING_FCNTL } lock_type; + /* The fatal error handling routine. */ void (*fatal_err) (const char *); @@ -24,6 +24,8 @@ #include "gdbmerrno.h" #include "extern.h" +#include <errno.h> + #if HAVE_FLOCK #ifndef LOCK_SH #define LOCK_SH 1 @@ -42,18 +44,17 @@ #endif #endif -#if (defined(F_SETLK) || defined(F_SETLK64)) && defined(F_RDLCK) && defined(F_WRLCK) +#if defined(F_SETLK) && defined(F_RDLCK) && defined(F_WRLCK) #define HAVE_FCNTL_LOCK 1 #else #define HAVE_FCNTL_LOCK 0 #endif -#define LOCKING_NONE 0 -#define LOCKING_FLOCK 1 -#define LOCKING_LOCKF 2 -#define LOCKING_FCNTL 3 - -static int _gdbm_lock_type = LOCKING_NONE; +int +gdbm_locked (gdbm_file_info *dbf) +{ + return (dbf->lock_type != LOCKING_NONE); +} void _gdbm_unlock_file (gdbm_file_info *dbf) @@ -62,7 +63,7 @@ _gdbm_unlock_file (gdbm_file_info *dbf) struct flock fl; #endif - switch (_gdbm_lock_type) + switch (dbf->lock_type) { case LOCKING_FLOCK: #if HAVE_FLOCK @@ -85,6 +86,8 @@ _gdbm_unlock_file (gdbm_file_info *dbf) #endif break; } + + dbf->lock_type = LOCKING_NONE; } /* Try each supported locking mechanism. */ @@ -102,9 +105,14 @@ _gdbm_lock_file (gdbm_file_info *dbf) else lock_val = flock (dbf->desc, LOCK_EX + LOCK_NB); - if (lock_val != -1) + if ((lock_val == -1) && (errno == EWOULDBLOCK)) { - _gdbm_lock_type = LOCKING_FLOCK; + dbf->lock_type = LOCKING_NONE; + return lock_val; + } + else if (lock_val != -1) + { + dbf->lock_type = LOCKING_FLOCK; return lock_val; } #endif @@ -112,9 +120,14 @@ _gdbm_lock_file (gdbm_file_info *dbf) #if HAVE_LOCKF /* Mask doesn't matter for lockf. */ lock_val = lockf (dbf->desc, F_LOCK, (off_t)0L); - if (lock_val != -1) + if ((lock_val == -1) && (errno == EDEADLK)) { - _gdbm_lock_type = LOCKING_LOCKF; + dbf->lock_type = LOCKING_NONE; + return lock_val; + } + else if (lock_val != -1) + { + dbf->lock_type = LOCKING_LOCKF; return lock_val; } #endif @@ -128,11 +141,12 @@ _gdbm_lock_file (gdbm_file_info *dbf) fl.l_whence = SEEK_SET; fl.l_start = fl.l_len = (off_t)0L; lock_val = fcntl (dbf->desc, F_SETLK, &fl); + if (lock_val != -1) - _gdbm_lock_type = LOCKING_FCNTL; + dbf->lock_type = LOCKING_FCNTL; #endif if (lock_val == -1) - _gdbm_lock_type = LOCKING_NONE; + dbf->lock_type = LOCKING_NONE; return lock_val; } diff --git a/src/proto.h b/src/proto.h index 90b28ed..129ed55 100644 --- a/src/proto.h +++ b/src/proto.h @@ -51,6 +51,7 @@ off_t _gdbm_mapped_lseek (gdbm_file_info *, off_t, int); int _gdbm_mapped_sync (gdbm_file_info *); /* From lock.c */ +int gdbm_locked (gdbm_file_info *); void _gdbm_unlock_file (gdbm_file_info *); int _gdbm_lock_file (gdbm_file_info *); |