aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compat/dbminit.c2
-rw-r--r--compat/dbmopen.c4
-rw-r--r--src/gdbm.h.in3
-rw-r--r--src/gdbmcount.c3
-rw-r--r--src/gdbmdefs.h274
-rw-r--r--src/gdbmdelete.c4
-rw-r--r--src/gdbmdump.c6
-rw-r--r--src/gdbmerrno.c3
-rw-r--r--src/gdbmexists.c3
-rw-r--r--src/gdbmexp.c3
-rw-r--r--src/gdbmfetch.c3
-rw-r--r--src/gdbmimp.c3
-rw-r--r--src/gdbmopen.c3
-rw-r--r--src/gdbmreorg.c2
-rw-r--r--src/gdbmseq.c12
-rw-r--r--src/gdbmsetopt.c3
-rw-r--r--src/gdbmstore.c5
-rw-r--r--src/gdbmsync.c2
18 files changed, 201 insertions, 137 deletions
diff --git a/compat/dbminit.c b/compat/dbminit.c
index f5c5a65..f5203d1 100644
--- a/compat/dbminit.c
+++ b/compat/dbminit.c
@@ -2,7 +2,7 @@
DBM interface. */
/* This file is part of GDBM, the GNU data base manager.
- Copyright (C) 1990, 1991, 1993, 2007, 2011 Free Software Foundation,
+ Copyright (C) 1990, 1991, 1993, 2007, 2011, 2016 Free Software Foundation,
Inc.
GDBM is free software; you can redistribute it and/or modify
diff --git a/compat/dbmopen.c b/compat/dbmopen.c
index f8df3e3..af423df 100644
--- a/compat/dbmopen.c
+++ b/compat/dbmopen.c
@@ -2,7 +2,7 @@
NDBM interface for dbm use. */
/* This file is part of GDBM, the GNU data base manager.
- Copyright (C) 1990, 1991, 1993, 2007, 2011 Free Software Foundation,
+ Copyright (C) 1990, 1991, 1993, 2007, 2011, 2016 Free Software Foundation,
Inc.
GDBM is free software; you can redistribute it and/or modify
@@ -259,7 +259,7 @@ dbm_open (char *file, int flags, int mode)
/* Did we successfully open the file? */
if (dbm->file == NULL)
{
- gdbm_set_errno (dbm, GDBM_FILE_OPEN_ERROR, 1);
+ gdbm_set_errno (NULL, GDBM_FILE_OPEN_ERROR, 1);
free (dbm);
dbm = NULL;
}
diff --git a/src/gdbm.h.in b/src/gdbm.h.in
index 9a027dc..83f99c2 100644
--- a/src/gdbm.h.in
+++ b/src/gdbm.h.in
@@ -171,9 +171,10 @@ extern int gdbm_load_from_file (GDBM_FILE *, FILE *, int replace,
# define GDBM_NO_DBNAME 26
# define GDBM_ERR_FILE_OWNER 27
# define GDBM_ERR_FILE_MODE 28
+# define GDBM_NEED_RECOVERY 29
# define _GDBM_MIN_ERRNO 0
-# define _GDBM_MAX_ERRNO GDBM_ERR_FILE_MODE
+# define _GDBM_MAX_ERRNO GDBM_NEED_RECOVERY
typedef int gdbm_error; /* For compatibilities sake. */
extern gdbm_error gdbm_errno;
diff --git a/src/gdbmcount.c b/src/gdbmcount.c
index 17016b2..472f0d3 100644
--- a/src/gdbmcount.c
+++ b/src/gdbmcount.c
@@ -39,6 +39,9 @@ gdbm_count (GDBM_FILE dbf, gdbm_count_t *pcount)
off_t *sdir;
gdbm_count_t count = 0;
int i, last;
+
+ /* Return immediately if the database needs recovery */
+ GDBM_ASSERT_CONSISTENCY (dbf, -1);
sdir = malloc (dbf->header->dir_size);
if (!sdir)
diff --git a/src/gdbmdefs.h b/src/gdbmdefs.h
index e873117..34c8b55 100644
--- a/src/gdbmdefs.h
+++ b/src/gdbmdefs.h
@@ -1,8 +1,8 @@
/* gdbmdefs.h - The include file for dbm. Defines structure and constants. */
/* This file is part of GDBM, the GNU data base manager.
- Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013 Free Software Foundation,
- Inc.
+ Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013,
+ 2016 Free Software Foundation, Inc.
GDBM is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -35,36 +35,39 @@
not empty, the top of the stack is popped into the active avail table. */
/* The following structure is the element of the avaliable table. */
-typedef struct {
- int av_size; /* The size of the available block. */
- off_t av_adr; /* The file address of the available block. */
- } avail_elem;
+typedef struct
+{
+ int av_size; /* The size of the available block. */
+ off_t av_adr; /* The file address of the available block. */
+} avail_elem;
/* This is the actual table. The in-memory images of the avail blocks are
allocated by malloc using a calculated size. */
-typedef struct {
- int size; /* The number of avail elements in the table.*/
- int count; /* The number of entries in the table. */
- off_t next_block; /* The file address of the next avail block. */
- avail_elem av_table[1]; /* The table. Make it look like an array. */
- } avail_block;
+typedef struct
+{
+ int size; /* The number of avail elements in the table.*/
+ int count; /* The number of entries in the table. */
+ off_t next_block; /* The file address of the next avail block. */
+ avail_elem av_table[1]; /* The table. Make it look like an array. */
+} avail_block;
/* The dbm file header keeps track of the current location of the hash
directory and the free space in the file. */
-typedef struct {
- int header_magic; /* Version of file. */
- int block_size; /* The optimal i/o blocksize from stat. */
- off_t dir; /* File address of hash directory table. */
- int dir_size; /* Size in bytes of the table. */
- int dir_bits; /* The number of address bits used in the table.*/
- int bucket_size; /* Size in bytes of a hash bucket struct. */
- int bucket_elems; /* Number of elements in a hash bucket. */
- off_t next_block; /* The next unallocated block address. */
- avail_block avail; /* This must be last because of the pseudo
- array in avail. This avail grows to fill
- the entire block. */
- } gdbm_file_header;
+typedef struct
+{
+ int header_magic; /* Version of file. */
+ int block_size; /* The optimal i/o blocksize from stat. */
+ off_t dir; /* File address of hash directory table. */
+ int dir_size; /* Size in bytes of the table. */
+ int dir_bits; /* The number of address bits used in the table.*/
+ int bucket_size; /* Size in bytes of a hash bucket struct. */
+ int bucket_elems; /* Number of elements in a hash bucket. */
+ off_t next_block; /* The next unallocated block address. */
+ avail_block avail; /* This must be last because of the pseudo
+ array in avail. This avail grows to fill
+ the entire block. */
+} gdbm_file_header;
/* The dbm hash bucket element contains the full 31 bit hash value, the
@@ -73,14 +76,15 @@ typedef struct {
part of the key has the correct value without having to read the actual
key. */
-typedef struct {
- int hash_value; /* The complete 31 bit value. */
- char key_start[SMALL]; /* Up to the first SMALL bytes of the key. */
- off_t data_pointer; /* The file address of the key record. The
- data record directly follows the key. */
- int key_size; /* Size of key data in the file. */
- int data_size; /* Size of associated data in the file. */
- } bucket_element;
+typedef struct
+{
+ int hash_value; /* The complete 31 bit value. */
+ char key_start[SMALL]; /* Up to the first SMALL bytes of the key. */
+ off_t data_pointer; /* The file address of the key record. The
+ data record directly follows the key. */
+ int key_size; /* Size of key data in the file. */
+ int data_size; /* Size of associated data in the file. */
+} bucket_element;
/* A bucket is a small hash table. This one consists of a number of
@@ -95,13 +99,14 @@ typedef struct {
the file system buffer size. To speed up write, each bucket will have
BUCKET_AVAIL avail elements with the bucket. */
-typedef struct {
- int av_count; /* The number of bucket_avail entries. */
- avail_elem bucket_avail[BUCKET_AVAIL]; /* Distributed avail. */
- int bucket_bits; /* The number of bits used to get here. */
- int count; /* The number of element buckets full. */
- bucket_element h_table[1]; /* The table. Make it look like an array.*/
- } hash_bucket;
+typedef struct
+{
+ int av_count; /* The number of bucket_avail entries. */
+ avail_elem bucket_avail[BUCKET_AVAIL]; /* Distributed avail. */
+ int bucket_bits; /* The number of bits used to get here. */
+ int count; /* The number of element buckets full. */
+ bucket_element h_table[1]; /* The table. Make it look like an array.*/
+} hash_bucket;
/* We want to keep from reading buckets as much as possible. The following is
to implement a bucket cache. When full, buckets will be dropped in a
@@ -114,118 +119,133 @@ typedef struct {
in a data cache. Each bucket cached will have a one element data
cache. */
-typedef struct {
- int hash_val;
- int data_size;
- int key_size;
- char *dptr;
- int elem_loc;
- } data_cache_elem;
-
-typedef struct {
- hash_bucket * ca_bucket;
- off_t ca_adr;
- char ca_changed; /* Data in the bucket changed. */
- data_cache_elem ca_data;
- } cache_elem;
+typedef struct
+{
+ int hash_val;
+ int data_size;
+ int key_size;
+ char *dptr;
+ int elem_loc;
+} data_cache_elem;
+
+typedef struct
+{
+ hash_bucket * ca_bucket;
+ off_t ca_adr;
+ char ca_changed; /* Data in the bucket changed. */
+ data_cache_elem ca_data;
+} cache_elem;
/* This final structure contains all main memory based information for
a gdbm file. This allows multiple gdbm files to be opened at the same
time by one program. */
-struct gdbm_file_info {
- /* Global variables and pointers to dynamic variables used by gdbm. */
+struct gdbm_file_info
+{
+ /* Global variables and pointers to dynamic variables used by gdbm. */
- /* The file name. */
- char *name;
+ /* The file name. */
+ char *name;
- /* The reader/writer status. */
- unsigned read_write :2;
+ /* The reader/writer status. */
+ unsigned read_write :2;
- /* Fast_write is set to 1 if no fsyncs are to be done. */
- unsigned fast_write :1;
+ /* Fast_write is set to 1 if no fsyncs are to be done. */
+ unsigned fast_write :1;
- /* Central_free is set if all free blocks are kept in the header. */
- unsigned central_free :1;
+ /* Central_free is set if all free blocks are kept in the header. */
+ unsigned central_free :1;
- /* Coalesce_blocks is set if we should try to merge free blocks. */
- unsigned coalesce_blocks :1;
+ /* Coalesce_blocks is set if we should try to merge free blocks. */
+ unsigned coalesce_blocks :1;
- /* Whether or not we should do file locking ourselves. */
- unsigned file_locking :1;
+ /* Whether or not we should do file locking ourselves. */
+ unsigned file_locking :1;
- /* Whether or not we're allowing mmap() use. */
- unsigned memory_mapping :1;
+ /* Whether or not we're allowing mmap() use. */
+ unsigned memory_mapping :1;
- /* Whether the database was open with GDBM_CLOEXEC flag */
- unsigned cloexec :1;
+ /* Whether the database was open with GDBM_CLOEXEC flag */
+ unsigned cloexec :1;
- /* Last error was fatal */
- unsigned fatal :1;
+ /* Last error was fatal, the database needs recovery */
+ unsigned need_recovery :1;
- /* Last error number */
- int last_error;
+ /* Last error number */
+ int last_error;
- /* Type of file locking in use. */
- enum { LOCKING_NONE = 0, LOCKING_FLOCK, LOCKING_LOCKF,
- LOCKING_FCNTL } lock_type;
+ /* 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 *);
+ /* The fatal error handling routine. */
+ void (*fatal_err) (const char *);
- /* The gdbm file descriptor which is set in gdbm_open. */
- int desc;
+ /* The gdbm file descriptor which is set in gdbm_open. */
+ int desc;
- /* The file header holds information about the database. */
- gdbm_file_header *header;
-
- /* The hash table directory from extendable hashing. See Fagin et al,
- ACM Trans on Database Systems, Vol 4, No 3. Sept 1979, 315-344 */
- off_t *dir;
-
- /* The bucket cache. */
- cache_elem *bucket_cache;
- size_t cache_size;
- int last_read;
-
- /* Points to the current hash bucket in the cache. */
- hash_bucket *bucket;
-
- /* The directory entry used to get the current hash bucket. */
- int bucket_dir;
-
- /* Pointer to the current bucket's cache entry. */
- cache_elem *cache_entry;
-
- /* Bookkeeping of things that need to be written back at the
- end of an update. */
- unsigned header_changed :1;
- unsigned directory_changed :1;
- unsigned bucket_changed :1;
- unsigned second_changed :1;
-
- /* Mmap info */
- size_t mapped_size_max;/* Max. allowed value for mapped_size */
- void *mapped_region; /* Mapped region */
- size_t mapped_size; /* Size of the region */
- off_t mapped_pos; /* Current offset in the region */
- off_t mapped_off; /* Position in the file where the region
- begins */
- };
+ /* The file header holds information about the database. */
+ gdbm_file_header *header;
+
+ /* The hash table directory from extendable hashing. See Fagin et al,
+ ACM Trans on Database Systems, Vol 4, No 3. Sept 1979, 315-344 */
+ off_t *dir;
+
+ /* The bucket cache. */
+ cache_elem *bucket_cache;
+ size_t cache_size;
+ int last_read;
+
+ /* Points to the current hash bucket in the cache. */
+ hash_bucket *bucket;
+
+ /* The directory entry used to get the current hash bucket. */
+ int bucket_dir;
+
+ /* Pointer to the current bucket's cache entry. */
+ cache_elem *cache_entry;
+
+ /* Bookkeeping of things that need to be written back at the
+ end of an update. */
+ unsigned header_changed :1;
+ unsigned directory_changed :1;
+ unsigned bucket_changed :1;
+ unsigned second_changed :1;
+
+ /* Mmap info */
+ size_t mapped_size_max;/* Max. allowed value for mapped_size */
+ void *mapped_region; /* Mapped region */
+ size_t mapped_size; /* Size of the region */
+ off_t mapped_pos; /* Current offset in the region */
+ off_t mapped_off; /* Position in the file where the region
+ begins */
+};
#define GDBM_DIR_COUNT(db) ((db)->header->dir_size / sizeof (off_t))
/* Execute CODE without clobbering errno */
-#define SAVE_ERRNO(code) \
- do \
- { \
- int __ec = errno; \
- code; \
- errno = __ec; \
- } \
- while (0) \
+#define SAVE_ERRNO(code) \
+ do \
+ { \
+ int __ec = errno; \
+ code; \
+ errno = __ec; \
+ } \
+ while (0) \
#define _GDBM_MAX_DUMP_LINE_LEN 76
+/* Return immediately if the database needs recovery */
+#define GDBM_ASSERT_CONSISTENCY(dbf, onerr) \
+ do \
+ { \
+ if (dbf->need_recovery) \
+ { \
+ gdbm_set_errno (dbf, GDBM_NEED_RECOVERY, 1); \
+ return onerr; \
+ } \
+ } \
+ while (0)
+
/* Now define all the routines in use. */
#include "proto.h"
diff --git a/src/gdbmdelete.c b/src/gdbmdelete.c
index 7e2867d..faa4957 100644
--- a/src/gdbmdelete.c
+++ b/src/gdbmdelete.c
@@ -36,13 +36,15 @@ gdbm_delete (GDBM_FILE dbf, datum key)
off_t free_adr; /* Temporary storage for address and size. */
int free_size;
+ GDBM_ASSERT_CONSISTENCY (dbf, -1);
+
/* First check to make sure this guy is a writer. */
if (dbf->read_write == GDBM_READER)
{
gdbm_set_errno (dbf, GDBM_READER_CANT_DELETE, 0);
return -1;
}
-
+
/* Initialize the gdbm_errno variable. */
gdbm_set_errno (dbf, GDBM_NO_ERROR, 0);
diff --git a/src/gdbmdump.c b/src/gdbmdump.c
index cf1e2fc..49f39bf 100644
--- a/src/gdbmdump.c
+++ b/src/gdbmdump.c
@@ -128,6 +128,9 @@ gdbm_dump_to_file (GDBM_FILE dbf, FILE *fp, int format)
{
int rc;
+ /* Return immediately if the database needs recovery */
+ GDBM_ASSERT_CONSISTENCY (dbf, -1);
+
switch (format)
{
case GDBM_DUMP_FMT_BINARY:
@@ -159,6 +162,9 @@ gdbm_dump (GDBM_FILE dbf, const char *filename, int fmt, int open_flags,
int nfd, rc;
FILE *fp;
+ /* Return immediately if the database needs recovery */
+ GDBM_ASSERT_CONSISTENCY (dbf, -1);
+
/* Only support GDBM_WCREAT or GDBM_NEWDB */
switch (open_flags)
{
diff --git a/src/gdbmerrno.c b/src/gdbmerrno.c
index 2ff647f..4eeff8c 100644
--- a/src/gdbmerrno.c
+++ b/src/gdbmerrno.c
@@ -33,7 +33,7 @@ gdbm_set_errno (GDBM_FILE dbf, gdbm_error ec, int fatal)
if (dbf)
{
dbf->last_error = ec;
- dbf->fatal = fatal;
+ dbf->need_recovery = fatal;
}
gdbm_errno = ec;
}
@@ -91,6 +91,7 @@ const char * const gdbm_errlist[_GDBM_MAX_ERRNO+1] = {
[GDBM_NO_DBNAME] = N_("Database name not given"),
[GDBM_ERR_FILE_OWNER] = N_("Failed to restore file owner"),
[GDBM_ERR_FILE_MODE] = N_("Failed to restore file mode"),
+ [GDBM_NEED_RECOVERY] = N_("Database needs recovery")
};
const char *
diff --git a/src/gdbmexists.c b/src/gdbmexists.c
index 0d551c0..e44f04e 100644
--- a/src/gdbmexists.c
+++ b/src/gdbmexists.c
@@ -27,6 +27,9 @@
int
gdbm_exists (GDBM_FILE dbf, datum key)
{
+ /* Return immediately if the database needs recovery */
+ GDBM_ASSERT_CONSISTENCY (dbf, 0);
+
if (_gdbm_findkey (dbf, key, NULL, NULL) < 0)
{
if (gdbm_errno == GDBM_ITEM_NOT_FOUND)
diff --git a/src/gdbmexp.c b/src/gdbmexp.c
index 613166e..f188040 100644
--- a/src/gdbmexp.c
+++ b/src/gdbmexp.c
@@ -32,6 +32,9 @@ gdbm_export_to_file (GDBM_FILE dbf, FILE *fp)
const char *header2 = "\r\n!\r\n";
int count = 0;
+ /* Return immediately if the database needs recovery */
+ GDBM_ASSERT_CONSISTENCY (dbf, -1);
+
/* Write out the text header. */
if (fwrite (header1, strlen (header1), 1, fp) != 1)
goto write_fail;
diff --git a/src/gdbmfetch.c b/src/gdbmfetch.c
index ca82550..25a6c1d 100644
--- a/src/gdbmfetch.c
+++ b/src/gdbmfetch.c
@@ -37,6 +37,9 @@ gdbm_fetch (GDBM_FILE dbf, datum key)
return_val.dptr = NULL;
return_val.dsize = 0;
+ /* Return immediately if the database needs recovery */
+ GDBM_ASSERT_CONSISTENCY (dbf, return_val);
+
/* Initialize the gdbm_errno variable. */
gdbm_set_errno (dbf, GDBM_NO_ERROR, 0);
diff --git a/src/gdbmimp.c b/src/gdbmimp.c
index 96c774f..6227a39 100644
--- a/src/gdbmimp.c
+++ b/src/gdbmimp.c
@@ -34,6 +34,9 @@ gdbm_import_from_file (GDBM_FILE dbf, FILE *fp, int flag)
datum key, data;
int count = 0;
+ /* Return immediately if the database needs recovery */
+ GDBM_ASSERT_CONSISTENCY (dbf, -1);
+
seenbang = 0;
seennewline = 0;
kbuffer = NULL;
diff --git a/src/gdbmopen.c b/src/gdbmopen.c
index b8b14e3..a45cb04 100644
--- a/src/gdbmopen.c
+++ b/src/gdbmopen.c
@@ -110,6 +110,9 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
dbf->file_locking = TRUE; /* Default to doing file locking. */
dbf->central_free = FALSE; /* Default to not using central_free. */
dbf->coalesce_blocks = FALSE; /* Default to not coalescing blocks. */
+
+ dbf->need_recovery = FALSE;
+ dbf->last_error = GDBM_NO_ERROR;
/* GDBM_FAST used to determine whether or not we set fast_write. */
if (flags & GDBM_SYNC)
diff --git a/src/gdbmreorg.c b/src/gdbmreorg.c
index 360f5c8..8a0cc64 100644
--- a/src/gdbmreorg.c
+++ b/src/gdbmreorg.c
@@ -65,6 +65,8 @@ gdbm_reorganize (GDBM_FILE dbf)
struct stat fileinfo; /* Information about the file. */
int index; /* Use in moving the bucket cache. */
+ /* Return immediately if the database needs recovery */
+ GDBM_ASSERT_CONSISTENCY (dbf, -1);
/* Readers can not reorganize! */
if (dbf->read_write == GDBM_READER)
diff --git a/src/gdbmseq.c b/src/gdbmseq.c
index c62a13b..831339a 100644
--- a/src/gdbmseq.c
+++ b/src/gdbmseq.c
@@ -100,6 +100,9 @@ gdbm_firstkey (GDBM_FILE dbf)
/* Set the default return value for not finding a first entry. */
return_val.dptr = NULL;
+ /* Return immediately if the database needs recovery */
+ GDBM_ASSERT_CONSISTENCY (dbf, return_val);
+
/* Initialize the gdbm_errno variable. */
gdbm_set_errno (dbf, GDBM_NO_ERROR, 0);
@@ -121,12 +124,15 @@ gdbm_nextkey (GDBM_FILE dbf, datum key)
datum return_val; /* The return value. */
int elem_loc; /* The location in the bucket. */
- /* Initialize the gdbm_errno variable. */
- gdbm_set_errno (dbf, GDBM_NO_ERROR, 0);
-
/* Set the default return value for no next entry. */
return_val.dptr = NULL;
+ /* Return immediately if the database needs recovery */
+ GDBM_ASSERT_CONSISTENCY (dbf, return_val);
+
+ /* Initialize the gdbm_errno variable. */
+ gdbm_set_errno (dbf, GDBM_NO_ERROR, 0);
+
/* Do we have a valid key? */
if (key.dptr == NULL)
{
diff --git a/src/gdbmsetopt.c b/src/gdbmsetopt.c
index e372a92..47e01ad 100644
--- a/src/gdbmsetopt.c
+++ b/src/gdbmsetopt.c
@@ -57,6 +57,9 @@ gdbm_setopt (GDBM_FILE dbf, int optflag, void *optval, int optlen)
int n;
size_t sz;
+ /* Return immediately if the database needs recovery */
+ GDBM_ASSERT_CONSISTENCY (dbf, -1);
+
switch (optflag)
{
/* Cache size: */
diff --git a/src/gdbmstore.c b/src/gdbmstore.c
index f166ba9..ec4b96b 100644
--- a/src/gdbmstore.c
+++ b/src/gdbmstore.c
@@ -47,6 +47,9 @@ gdbm_store (GDBM_FILE dbf, datum key, datum content, int flags)
int new_size; /* Used in allocating space. */
int rc;
+ /* Return immediately if the database needs recovery */
+ GDBM_ASSERT_CONSISTENCY (dbf, -1);
+
/* First check to make sure this guy is a writer. */
if (dbf->read_write == GDBM_READER)
{
@@ -99,7 +102,7 @@ gdbm_store (GDBM_FILE dbf, datum key, datum content, int flags)
}
}
else if (gdbm_errno == GDBM_ITEM_NOT_FOUND)
- gdbm_set_errno (dbf, GDBM_NO_ERROR, 0); //clear error state
+ gdbm_set_errno (dbf, GDBM_NO_ERROR, 0); /* clear error state */
else
return -1;
diff --git a/src/gdbmsync.c b/src/gdbmsync.c
index c9b146c..1d2a1d4 100644
--- a/src/gdbmsync.c
+++ b/src/gdbmsync.c
@@ -27,6 +27,8 @@
void
gdbm_sync (GDBM_FILE dbf)
{
+ /* Return immediately if the database needs recovery */
+ GDBM_ASSERT_CONSISTENCY (dbf, );
/* Initialize the gdbm_errno variable. */
gdbm_set_errno (dbf, GDBM_NO_ERROR, 0);

Return to:

Send suggestions and report system problems to the System administrator.