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 /tests | |
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 'tests')
-rw-r--r-- | tests/.gitignore | 1 | ||||
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rw-r--r-- | tests/gtrecover.c | 124 |
3 files changed, 127 insertions, 0 deletions
diff --git a/tests/.gitignore b/tests/.gitignore index 0883563..a339f8d 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -15,12 +15,13 @@ g_open_ce g_reorg_ce gtdel gtdump gtfetch gtload gtopt +gtrecover gtver num2word package.m4 testsuite testsuite.dir testsuite.log diff --git a/tests/Makefile.am b/tests/Makefile.am index f706213..a95db7e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -110,24 +110,26 @@ check_PROGRAMS = \ g_reorg_ce\ gtdel\ gtdump\ gtfetch\ gtload\ gtopt\ + gtrecover\ gtver\ num2word\ $(DBMPROGS) AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_builddir)/src $(DBMINCLUDES) noinst_HEADERS=progname.h gtdel_LDADD = ../src/libgdbm.la gtload_LDADD = ../src/libgdbm.la gtdump_LDADD = ../src/libgdbm.la gtfetch_LDADD = ../src/libgdbm.la gtver_LDADD = ../src/libgdbm.la gtopt_LDADD = ../src/libgdbm.la +gtrecover_LDADD = ../src/libgdbm.la g_open_ce_LDADD = ../src/libgdbm.la g_reorg_ce_LDADD = ../src/libgdbm.la dtload_LDADD = ../src/libgdbm.la ../compat/libgdbm_compat.la dtdump_LDADD = ../src/libgdbm.la ../compat/libgdbm_compat.la diff --git a/tests/gtrecover.c b/tests/gtrecover.c new file mode 100644 index 0000000..7bb1f1e --- /dev/null +++ b/tests/gtrecover.c @@ -0,0 +1,124 @@ +/* This file is part of GDBM test suite. + Copyright (C) 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 + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GDBM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GDBM. If not, see <http://www.gnu.org/licenses/>. +*/ +#include "autoconf.h" +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include "gdbm.h" +#include "progname.h" +#include <assert.h> + +const char *progname; + +void +err_printer (void *data, char const *fmt, ...) +{ + va_list ap; + + fprintf (stderr, "%s: ", progname); + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + fprintf (stderr, "\n"); +} + +int +main (int argc, char **argv) +{ + const char *dbname; + GDBM_FILE dbf; + int rc = 0; + int open_flags = GDBM_WRITER; + gdbm_recovery rcvr; + int rcvr_flags = 0; + char *p; + + progname = canonical_progname (argv[0]); + while (--argc) + { + char *arg = *++argv; + + if (strcmp (arg, "-h") == 0) + { + printf ("usage: %s [-nolock] [-nommap] [-verbose] [-backup] [-max-failures=N] [-max-failed-keys=N] [-max-failed-buckets=N] DBFILE\n", + progname); + exit (0); + } + else if (strcmp (arg, "-nolock") == 0) + open_flags |= GDBM_NOLOCK; + else if (strcmp (arg, "-nommap") == 0) + open_flags |= GDBM_NOMMAP; + else if (strcmp (arg, "-verbose") == 0) + { + rcvr.errfun = err_printer; + rcvr_flags |= GDBM_RCVR_ERRFUN; + } + else if (strcmp (arg, "-backup") == 0) + rcvr_flags |= GDBM_RCVR_BACKUP; + else if (strncmp (arg, "-max-failures=", 14) == 0) + { + rcvr.max_failures = strtoul (arg + 14, &p, 10); + assert (*p == 0); + rcvr_flags |= GDBM_RCVR_MAX_FAILURES; + } + else if (strncmp (arg, "-max-failed-keys=", 17) == 0) + { + rcvr.max_failed_keys = strtoul (arg + 17, &p, 10); + assert (*p == 0); + rcvr_flags |= GDBM_RCVR_MAX_FAILED_KEYS; + } + else if (strncmp (arg, "-max-failed-buckets=", 20) == 0) + { + rcvr.max_failures = strtoul (arg + 20, &p, 10); + assert (*p == 0); + rcvr_flags |= GDBM_RCVR_MAX_FAILED_BUCKETS; + } + else if (strcmp (arg, "--") == 0) + { + --argc; + ++argv; + break; + } + else if (arg[0] == '-') + { + fprintf (stderr, "%s: unknown option %s\n", progname, arg); + exit (1); + } + else + break; + } + + if (argc < 1) + { + fprintf (stderr, "%s: wrong arguments\n", progname); + exit (1); + } + dbname = *argv; + + dbf = gdbm_open (dbname, 0, open_flags, 0, NULL); + if (!dbf) + { + fprintf (stderr, "gdbm_open failed: %s\n", gdbm_strerror (gdbm_errno)); + exit (1); + } + + rc = gdbm_recover (dbf, &rcvr, rcvr_flags); + + gdbm_close (dbf); + exit (rc); +} |