aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Downs <downsj@downsj.com>2008-12-01 00:57:13 +0000
committerJason Downs <downsj@downsj.com>2008-12-01 00:57:13 +0000
commit6732749a44326b5cbfc69d446c07367b0b3a3fc2 (patch)
tree9907e5dcd612cac7c542e540dd67e9619c31e9ce
parent30d03809f242c0e3d2f95d75cf27a69f49648563 (diff)
downloadgdbm-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--ChangeLog8
-rw-r--r--src/gdbm.proto3
-rw-r--r--src/gdbmdefs.h4
-rw-r--r--src/lock.c42
-rw-r--r--src/proto.h1
5 files changed, 44 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index 54fe3b1..004b0dd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 *);
diff --git a/src/lock.c b/src/lock.c
index 5b977bf..4fd5cd6 100644
--- a/src/lock.c
+++ b/src/lock.c
@@ -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 *);

Return to:

Send suggestions and report system problems to the System administrator.