diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2016-07-19 12:01:48 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2016-07-19 12:58:16 +0300 |
commit | 85f1e72da83e3078e2ae1f78093ef0966e43cec1 (patch) | |
tree | b00707979e9088d5f7b7880d438260eb063c9160 /src/gdbmclose.c | |
parent | 8e83f209342e2b035bbb19efa87ec5295158ef65 (diff) | |
download | gdbm-85f1e72da83e3078e2ae1f78093ef0966e43cec1.tar.gz gdbm-85f1e72da83e3078e2ae1f78093ef0966e43cec1.tar.bz2 |
Implement gdbm_recover function
* configure.ac: Don't check for rename.
* src/Makefile.am (libgdbm_la_SOURCES): Add recover.c
* src/recover.c: New file.
* src/bucket.c (_gdbm_get_bucket): Remove extra space before [
* src/err.c (prerror): Take additional argument
(gdbm_perror): Print system errno if necessary.
* src/gdbm.h.in (GDBM_CLOERROR): New flag.
(gdbm_fd_open, gdbm_copy_meta): New proto.
(gdbm_last_syserr,gdbm_db_strerror,gdbm_recover): New proto.
(gdbm_syserr): New extern.
(gdbm_recovery): New struct.
(GDBM_RCVR_DEFAULT,GDBM_RCVR_ERRFUN)
(GDBM_RCVR_MAX_FAILED_KEYS)
(GDBM_RCVR_MAX_FAILED_BUCKETS)
(GDBM_RCVR_MAX_FAILURES)
(GDBM_RCVR_BACKUP): New flags.
(GDBM_BACKUP_FAILED): New error code.
* src/gdbmclose.c (gdbm_close): Work correctly if dbf->desc == -1.
* src/gdbmcount.c (gdbm_count): Remove spurious sorting.
Use _gdbm_next_bucket_dir for iterating over the buckets.
* src/gdbmdefs.h (struct gdbm_file_info)<last_syserror>
<last_errstr>: New members.
* src/gdbmerrno.c (gdbm_set_errno): Set last_syserror as well.
(gdbm_clear_error): Reset last_syserror.
(gdbm_last_syserr): New function.
(gdbm_errlist): New entry for GDBM_BACKUP_FAILED.
(gdbm_db_strerror): New function.
(gdbm_syserr): New global.
* src/gdbmload.c (get_parms): Buffer can be NULL.
* src/gdbmopen.c (gdbm_fd_open): New function.
(gdbm_open): Rewrite as a wrapper over gdbm_fd_open.
* src/gdbmreorg.c (gdbm_reorganize): Rewrite as a wrapper
over gdbm_recover.
* src/proto.h (_gdbm_next_bucket_dir): New proto.
* src/gdbmtool.c: New command: recover.
* tests/.gitignore: Add gtrecover
* tests/gtrecover.c: New test program.
* tests/Makefile.am: Build gtrecover
Diffstat (limited to 'src/gdbmclose.c')
-rw-r--r-- | src/gdbmclose.c | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/src/gdbmclose.c b/src/gdbmclose.c index f711a8f..adf654d 100644 --- a/src/gdbmclose.c +++ b/src/gdbmclose.c @@ -31,31 +31,36 @@ gdbm_close (GDBM_FILE dbf) { int index; /* For freeing the bucket cache. */ - /* Make sure the database is all on disk. */ - if (dbf->read_write != GDBM_READER) - __fsync (dbf); + if (dbf->desc != -1) + { + /* Make sure the database is all on disk. */ + if (dbf->read_write != GDBM_READER) + __fsync (dbf); - /* Close the file and free all malloced memory. */ + /* Close the file and free all malloced memory. */ #if HAVE_MMAP - _gdbm_mapped_unmap(dbf); + _gdbm_mapped_unmap (dbf); #endif - if (dbf->file_locking) - { - _gdbm_unlock_file (dbf); + if (dbf->file_locking) + _gdbm_unlock_file (dbf); + + close (dbf->desc); } - close (dbf->desc); + + gdbm_clear_error (dbf); + free (dbf->name); - if (dbf->dir != NULL) free (dbf->dir); - - if (dbf->bucket_cache != NULL) { - for (index = 0; index < dbf->cache_size; index++) { - if (dbf->bucket_cache[index].ca_bucket != NULL) - free (dbf->bucket_cache[index].ca_bucket); - if (dbf->bucket_cache[index].ca_data.dptr != NULL) - free (dbf->bucket_cache[index].ca_data.dptr); + free (dbf->dir); + + if (dbf->bucket_cache != NULL) + { + for (index = 0; index < dbf->cache_size; index++) + { + free (dbf->bucket_cache[index].ca_bucket); + free (dbf->bucket_cache[index].ca_data.dptr); + } + free (dbf->bucket_cache); } - free (dbf->bucket_cache); - } - if ( dbf->header != NULL ) free (dbf->header); + free (dbf->header); free (dbf); } |