diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2021-08-16 21:54:00 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2021-09-03 13:23:50 +0300 |
commit | 9e4213610f56454a84d614511e5ed7c7c9bd2591 (patch) | |
tree | 7c42b98d77920dda9be938938be6ad783420d4c8 /src | |
parent | 6f3160eade02dd21498e765f29d72832ced50913 (diff) | |
download | gdbm-9e4213610f56454a84d614511e5ed7c7c9bd2591.tar.gz gdbm-9e4213610f56454a84d614511e5ed7c7c9bd2591.tar.bz2 |
New gdbmtool variables: errorexit and errormask.
Boolean errorexit controls whether script terminates upon first
erroneous return from run_command or its derivatives. The variable
can be set only in non-interactive mode.
errormask is a comma-delimited list of GDBM error codes that are
masked, i.e. that won't trigger a diagnostic message if they occur.
* src/gdbmshell.c (all handlers): Return integer value indicating
success (0) or failure (!0).
* src/gdbmtool.h (input_context_drain): New function.
(run_last_command): Return integer.
* src/gram.y: abort if run_command returns error and "errorexit" is
set.
* src/input-argv.c (instream_argv_read): Bugfix.
* src/lex.l (input_context_drain): New function.
* src/var.c: New variables: errorexit and errormask.
Diffstat (limited to 'src')
-rw-r--r-- | src/gdbmshell.c | 222 | ||||
-rw-r--r-- | src/gdbmtool.h | 9 | ||||
-rw-r--r-- | src/gram.y | 15 | ||||
-rw-r--r-- | src/lex.l | 7 | ||||
-rw-r--r-- | src/var.c | 161 |
5 files changed, 338 insertions, 76 deletions
diff --git a/src/gdbmshell.c b/src/gdbmshell.c index 7df0fc7..cade2b8 100644 --- a/src/gdbmshell.c +++ b/src/gdbmshell.c @@ -298,11 +298,13 @@ avail_list_print (avail_block *avblk, off_t n, void *data) return 0; } -static void +static int _gdbm_print_avail_list (FILE *fp, GDBM_FILE dbf) { - if (gdbm_avail_traverse (dbf, avail_list_print, fp)) + int rc = gdbm_avail_traverse (dbf, avail_list_print, fp); + if (rc) dberror (_("%s failed"), "gdbm_avail_traverse"); + return rc; } static void @@ -368,7 +370,7 @@ get_screen_lines (void) } /* Open database */ -static void +static int open_handler (struct command_param *param, struct command_environ *cenv GDBM_ARG_UNUSED) { @@ -392,11 +394,13 @@ open_handler (struct command_param *param, variable_set ("fd", VART_INT, &fd); else variable_unset ("fd"); + return 0; } + return 1; } /* Close database */ -static void +static int close_handler (struct command_param *param GDBM_ARG_UNUSED, struct command_environ *cenv GDBM_ARG_UNUSED) { @@ -404,6 +408,7 @@ close_handler (struct command_param *param GDBM_ARG_UNUSED, terror ("%s", _("nothing to close")); else closedb (); + return 0; } static char * @@ -426,14 +431,17 @@ count_to_str (gdbm_count_t count, char *buf, size_t bufsize) } /* count - count items in the database */ -static void +static int count_handler (struct command_param *param GDBM_ARG_UNUSED, struct command_environ *cenv) { gdbm_count_t count; if (gdbm_count (gdbm_file, &count)) - dberror (_("%s failed"), "gdbm_count"); + { + dberror (_("%s failed"), "gdbm_count"); + return 1; + } else { char buf[128]; @@ -448,23 +456,29 @@ count_handler (struct command_param *param GDBM_ARG_UNUSED, count), p); } + return 0; } /* delete KEY - delete a key*/ -static void +static int delete_handler (struct command_param *param, struct command_environ *cenv) { if (gdbm_delete (gdbm_file, PARAM_DATUM (param, 0)) != 0) { if (gdbm_errno == GDBM_ITEM_NOT_FOUND) - terror ("%s", _("No such item found")); + { + if (!gdbm_error_is_masked (gdbm_errno)) + terror ("%s", _("No such item found")); + } else dberror ("%s", _("Can't delete")); + return 1; } + return 0; } /* fetch KEY - fetch a record by its key */ -static void +static int fetch_handler (struct command_param *param, struct command_environ *cenv) { return_data = gdbm_fetch (gdbm_file, PARAM_DATUM (param, 0)); @@ -473,27 +487,36 @@ fetch_handler (struct command_param *param, struct command_environ *cenv) datum_format (cenv->fp, &return_data, dsdef[DS_CONTENT]); fputc ('\n', cenv->fp); datum_free (&return_data); + return 0; } else if (gdbm_errno == GDBM_ITEM_NOT_FOUND) - terror ("%s", _("No such item found")); + { + if (!gdbm_error_is_masked (gdbm_errno)) + terror ("%s", _("No such item found")); + } else dberror ("%s", _("Can't fetch data")); + return 1; } /* store KEY DATA - store data */ -static void +static int store_handler (struct command_param *param, struct command_environ *cenv GDBM_ARG_UNUSED) { if (gdbm_store (gdbm_file, PARAM_DATUM (param, 0), PARAM_DATUM (param, 1), GDBM_REPLACE) != 0) - dberror ("%s", _("Item not inserted")); + { + dberror ("%s", _("Item not inserted")); + return 1; + } + return 0; } /* first - begin iteration */ -static void +static int firstkey_handler (struct command_param *param, struct command_environ *cenv) { datum_free (&key_data); @@ -508,15 +531,20 @@ firstkey_handler (struct command_param *param, struct command_environ *cenv) fputc ('\n', cenv->fp); datum_free (&return_data); + return 0; } else if (gdbm_errno == GDBM_ITEM_NOT_FOUND) - fprintf (cenv->fp, _("No such item found.\n")); + { + if (!gdbm_error_is_masked (gdbm_errno)) + fprintf (cenv->fp, _("No such item found.\n")); + } else dberror ("%s", _("Can't find first key")); + return 1; } /* next [KEY] - next key */ -static void +static int nextkey_handler (struct command_param *param, struct command_environ *cenv) { if (param->argc == 1) @@ -539,25 +567,32 @@ nextkey_handler (struct command_param *param, struct command_environ *cenv) fputc ('\n', cenv->fp); datum_free (&return_data); + return 0; } else if (gdbm_errno == GDBM_ITEM_NOT_FOUND) { - terror ("%s", _("No such item found")); + if (!gdbm_error_is_masked (gdbm_errno)) + terror ("%s", _("No such item found")); datum_free (&key_data); } else dberror ("%s", _("Can't find next key")); + return 1; } /* reorganize */ -static void +static int reorganize_handler (struct command_param *param GDBM_ARG_UNUSED, struct command_environ *cenv) { if (gdbm_reorganize (gdbm_file)) - dberror ("%s", _("Reorganization failed")); + { + dberror ("%s", _("Reorganization failed")); + return 1; + } else fprintf (cenv->fp, "%s\n", _("Reorganization succeeded.")); + return 0; } static void @@ -572,7 +607,7 @@ err_printer (void *data GDBM_ARG_UNUSED, char const *fmt, ...) } /* recover sumamry verbose backup max-failed-keys=N max-failed-buckets=N max-failures=N */ -static void +static int recover_handler (struct command_param *param, struct command_environ *cenv) { gdbm_recovery rcvr; @@ -608,7 +643,7 @@ recover_handler (struct command_param *param, struct command_environ *cenv) if (*p) { terror (_("not a number (stopped near %s)"), p); - return; + return 1; } flags |= GDBM_RCVR_MAX_FAILURES; } @@ -618,7 +653,7 @@ recover_handler (struct command_param *param, struct command_environ *cenv) if (*p) { terror (_("not a number (stopped near %s)"), p); - return; + return 1; } flags |= GDBM_RCVR_MAX_FAILED_KEYS; } @@ -628,14 +663,14 @@ recover_handler (struct command_param *param, struct command_environ *cenv) if (*p) { terror (_("not a number (stopped near %s)"), p); - return; + return 1; } flags |= GDBM_RCVR_MAX_FAILED_BUCKETS; } else { terror (_("unrecognized argument: %s"), arg); - return; + return 1; } } @@ -670,6 +705,7 @@ recover_handler (struct command_param *param, struct command_environ *cenv) { dberror ("%s", _("Recovery failed")); } + return rc; } /* avail - print available list */ @@ -685,11 +721,11 @@ avail_begin (struct command_param *param GDBM_ARG_UNUSED, return 0; } -static void +static int avail_handler (struct command_param *param GDBM_ARG_UNUSED, struct command_environ *cenv) { - _gdbm_print_avail_list (cenv->fp, gdbm_file); + return _gdbm_print_avail_list (cenv->fp, gdbm_file); } /* print current bucket */ @@ -709,7 +745,7 @@ print_current_bucket_begin (struct command_param *param GDBM_ARG_UNUSED, return 0; } -static void +static int print_current_bucket_handler (struct command_param *param, struct command_environ *cenv) { @@ -727,6 +763,7 @@ print_current_bucket_handler (struct command_param *param, fprintf (cenv->fp, _(" current bucket address = %lu.\n"), (unsigned long) gdbm_file->cache_entry->ca_adr); } + return 0; } int @@ -808,7 +845,7 @@ bucket_count (void) return count; } -static void +static int print_dir_handler (struct command_param *param GDBM_ARG_UNUSED, struct command_environ *cenv) { @@ -822,6 +859,8 @@ print_dir_handler (struct command_param *param GDBM_ARG_UNUSED, for (i = 0; i < GDBM_DIR_COUNT (gdbm_file); i++) fprintf (cenv->fp, " %10d: %12lu\n", i, (unsigned long) gdbm_file->dir[i]); + + return 0; } /* header - print file handler */ @@ -856,7 +895,7 @@ print_header_begin (struct command_param *param GDBM_ARG_UNUSED, return 0; } -static void +static int print_header_handler (struct command_param *param GDBM_ARG_UNUSED, struct command_environ *cenv) { @@ -905,30 +944,38 @@ print_header_handler (struct command_param *param GDBM_ARG_UNUSED, fprintf (fp, _(" version = %d\n"), gdbm_file->xheader->version); fprintf (fp, _(" numsync = %u\n"), gdbm_file->xheader->numsync); } + + return 0; } -static void +static int sync_handler (struct command_param *param GDBM_ARG_UNUSED, struct command_environ *cenv GDBM_ARG_UNUSED) { - if (gdbm_sync (gdbm_file)) + int rc = gdbm_sync (gdbm_file); + if (rc) dberror ("%s", "gdbm_sync"); + return rc; } -static void +static int upgrade_handler (struct command_param *param GDBM_ARG_UNUSED, struct command_environ *cenv GDBM_ARG_UNUSED) { - if (gdbm_convert (gdbm_file, GDBM_NUMSYNC)) + int rc = gdbm_convert (gdbm_file, GDBM_NUMSYNC); + if (rc) dberror ("%s", "gdbm_convert"); + return rc; } -static void +static int downgrade_handler (struct command_param *param GDBM_ARG_UNUSED, struct command_environ *cenv GDBM_ARG_UNUSED) { - if (gdbm_convert (gdbm_file, 0)) + int rc = gdbm_convert (gdbm_file, 0); + if (rc) dberror ("%s", "gdbm_convert"); + return rc; } struct snapshot_status_info @@ -1116,7 +1163,7 @@ static struct snapshot_status_info snapshot_status_info[] = { } }; -void +static int snapshot_handler (struct command_param *param, struct command_environ *cenv) { char *sa = tildexpand (PARAM_STRING (param, 0)); @@ -1136,12 +1183,16 @@ snapshot_handler (struct command_param *param, struct command_environ *cenv) print_snapshot (sel, cenv->fp); } else - terror (_("unexpected error code: %d"), rc); + { + terror (_("unexpected error code: %d"), rc); + return 1; + } + return 0; } /* hash KEY - hash the key */ -static void +static int hash_handler (struct command_param *param GDBM_ARG_UNUSED, struct command_environ *cenv) { @@ -1159,6 +1210,7 @@ hash_handler (struct command_param *param GDBM_ARG_UNUSED, fprintf (cenv->fp, _("hash value = %x"), _gdbm_hash (PARAM_DATUM (param, 0))); fprintf (cenv->fp, ".\n"); + return 0; } /* cache - print the bucket cache */ @@ -1174,19 +1226,21 @@ print_cache_begin (struct command_param *param GDBM_ARG_UNUSED, return 0; } -static void +static int print_cache_handler (struct command_param *param GDBM_ARG_UNUSED, struct command_environ *cenv) { _gdbm_print_bucket_cache (cenv->fp, gdbm_file); + return 0; } /* version - print GDBM version */ -static void +static int print_version_handler (struct command_param *param GDBM_ARG_UNUSED, struct command_environ *cenv) { fprintf (cenv->fp, "%s\n", gdbm_version); + return 0; } /* list - List all entries */ @@ -1212,14 +1266,20 @@ list_begin (struct command_param *param GDBM_ARG_UNUSED, return 0; } -static void +static int list_handler (struct command_param *param GDBM_ARG_UNUSED, struct command_environ *cenv) { datum key; datum data; - + int rc = 0; + key = gdbm_firstkey (gdbm_file); + if (!key.dptr && gdbm_errno != GDBM_ITEM_NOT_FOUND) + { + dberror ("%s", "gdbm_firstkey"); + return 1; + } while (key.dptr) { datum nextkey = gdbm_nextkey (gdbm_file, key); @@ -1230,6 +1290,7 @@ list_handler (struct command_param *param GDBM_ARG_UNUSED, dberror ("%s", "gdbm_fetch"); terror ("%s", _("the key was:")); datum_format (stderr, &key, dsdef[DS_KEY]); + rc = 1; } else { @@ -1242,21 +1303,27 @@ list_handler (struct command_param *param GDBM_ARG_UNUSED, free (key.dptr); key = nextkey; } + if (gdbm_errno != GDBM_ITEM_NOT_FOUND) + { + dberror ("%s", "gdbm_firstkey"); + rc = 1; + } + return rc; } /* quit - quit the program */ -static void +static int quit_handler (struct command_param *param GDBM_ARG_UNUSED, struct command_environ *cenv GDBM_ARG_UNUSED) { - while (!input_context_pop ()) - ; + input_context_drain (); if (input_context_push (instream_null_create ())) exit (EXIT_FATAL); + return 0; } /* export FILE [truncate] - export to a flat file format */ -static void +static int export_handler (struct command_param *param, struct command_environ *cenv GDBM_ARG_UNUSED) { @@ -1264,7 +1331,8 @@ export_handler (struct command_param *param, int flags = GDBM_WRCREAT; int i; int filemode; - + int rc; + for (i = 1; i < param->argc; i++) { if (strcmp (PARAM_STRING (param, i), "truncate") == 0) @@ -1276,20 +1344,22 @@ export_handler (struct command_param *param, else { terror (_("unrecognized argument: %s"), PARAM_STRING (param, i)); - return; + return 1; } } if (variable_get ("filemode", VART_INT, (void**) &filemode)) abort (); - if (gdbm_dump (gdbm_file, PARAM_STRING (param, 0), format, flags, filemode)) + rc = gdbm_dump (gdbm_file, PARAM_STRING (param, 0), format, flags, filemode); + if (rc) { dberror ("%s", _("error dumping database")); } + return rc; } /* import FILE [replace] [nometa] - import from a flat file */ -static void +static int import_handler (struct command_param *param, struct command_environ *cenv GDBM_ARG_UNUSED) { @@ -1310,7 +1380,7 @@ import_handler (struct command_param *param, { terror (_("unrecognized argument: %s"), PARAM_STRING (param, i)); - return; + return 1; } } @@ -1329,7 +1399,7 @@ import_handler (struct command_param *param, free (save_mode); if (rc) - return; + return rc; rc = gdbm_load (&gdbm_file, PARAM_STRING (param, 0), flag, meta_mask, &err_line); @@ -1349,21 +1419,23 @@ import_handler (struct command_param *param, else dberror (_("cannot load from %s"), PARAM_STRING (param, 0)); } - return; + return rc; } free (file_name); - if (gdbm_setopt (gdbm_file, GDBM_GETDBNAME, &file_name, sizeof (file_name))) + rc = gdbm_setopt (gdbm_file, GDBM_GETDBNAME, &file_name, sizeof (file_name)); + if (rc) dberror ("%s", "GDBM_GETDBNAME"); else { variable_set ("filename", VART_STRING, file_name); variable_unset ("fd"); } + return rc; } /* status - print current program status */ -static void +static int status_handler (struct command_param *param GDBM_ARG_UNUSED, struct command_environ *cenv) { @@ -1377,6 +1449,7 @@ status_handler (struct command_param *param GDBM_ARG_UNUSED, fprintf (cenv->fp, "%s\n", _("Database is not open")); dsprint (cenv->fp, DS_KEY, dsdef[DS_KEY]); dsprint (cenv->fp, DS_CONTENT, dsdef[DS_CONTENT]); + return 0; } #if GDBM_DEBUG_ENABLE @@ -1389,7 +1462,7 @@ debug_flag_printer (void *data, int flag, char const *tok) } #endif -static void +static int debug_handler (struct command_param *param, struct command_environ *cenv) { #if GDBM_DEBUG_ENABLE @@ -1448,9 +1521,10 @@ debug_handler (struct command_param *param, struct command_environ *cenv) #else terror ("%s", _("compiled without debug support")); #endif + return 0; } -static void +static int shell_handler (struct command_param *param, struct command_environ *cenv GDBM_ARG_UNUSED) { @@ -1476,7 +1550,7 @@ shell_handler (struct command_param *param, if (pid == -1) { terror ("fork: %s", strerror (errno)); - return; + return 1; } if (pid == 0) { @@ -1497,9 +1571,10 @@ shell_handler (struct command_param *param, else if (WIFSIGNALED (status)) terror (_("command terminated on signal %d"), WTERMSIG (status)); } + return 0; } -static void +static int source_handler (struct command_param *param, struct command_environ *cenv GDBM_ARG_UNUSED) { @@ -1507,7 +1582,12 @@ source_handler (struct command_param *param, instream_t istr = instream_file_create (fname); free (fname); if (istr && input_context_push (istr) == 0) - yyparse (); + { + yyparse (); + input_context_drain (); + yylex_destroy (); + } + return 0; } struct history_param @@ -1564,7 +1644,7 @@ input_history_begin (struct command_param *param, return 0; } -static void +static int input_history_handler (struct command_param *param GDBM_ARG_UNUSED, struct command_environ *cenv) { @@ -1579,10 +1659,11 @@ input_history_handler (struct command_param *param GDBM_ARG_UNUSED, break; fprintf (fp, "%4d) %s\n", p->from + i + 1, s); } + return 0; } -static void help_handler (struct command_param *, struct command_environ *); +static int help_handler (struct command_param *, struct command_environ *); static int help_begin (struct command_param *, struct command_environ *, size_t *); @@ -1608,7 +1689,7 @@ struct command size_t len; /* Name length */ int tok; int (*begin) (struct command_param *param, struct command_environ *cenv, size_t *); - void (*handler) (struct command_param *param, struct command_environ *cenv); + int (*handler) (struct command_param *param, struct command_environ *cenv); void (*end) (void *data); struct argdef args[NARGS]; int variadic; @@ -1914,7 +1995,7 @@ help_begin (struct command_param *param GDBM_ARG_UNUSED, return 0; } -static void +static int help_handler (struct command_param *param GDBM_ARG_UNUSED, struct command_environ *cenv) { @@ -1947,6 +2028,7 @@ help_handler (struct command_param *param GDBM_ARG_UNUSED, fprintf (fp, " %s", gettext (cmd->doc)); fputc ('\n', fp); } + return 0; } int @@ -2318,7 +2400,7 @@ coerce (struct gdbmarg *arg, struct argdef *def) static struct command *last_cmd; static struct gdbmarglist last_args; -void +int run_last_command (void) { if (interactive ()) @@ -2333,14 +2415,14 @@ run_last_command (void) gdbmarglist_free (&last_args); /* FALLTHROUGH */ case REPEAT_ALWAYS: - if (run_command (last_cmd, &last_args)) - exit (EXIT_USAGE); - break; + return run_command (last_cmd, &last_args); + default: abort (); } } } + return 0; } int @@ -2354,6 +2436,7 @@ run_command (struct command *cmd, struct gdbmarglist *arglist) FILE *pagfp = NULL; struct command_param param = HANDLER_PARAM_INITIALIZER; struct command_environ cenv = COMMAND_ENVIRON_INITIALIZER; + int rc = 0; variable_get ("pager", VART_STRING, (void**) &pager); @@ -2434,7 +2517,7 @@ run_command (struct command *cmd, struct gdbmarglist *arglist) else cenv.fp = stdout; - cmd->handler (¶m, &cenv); + rc = cmd->handler (¶m, &cenv); if (cmd->end) cmd->end (cenv.data); else if (cenv.data) @@ -2453,7 +2536,7 @@ run_command (struct command *cmd, struct gdbmarglist *arglist) last_args = *arglist; } - return 0; + return rc; } int @@ -2499,6 +2582,7 @@ gdbmshell_run (int (*init) (void *, instream_t *), void *data) if (instream_interactive (instream) && !variable_is_true ("quiet")) printf (_("\nWelcome to the gdbm tool. Type ? for help.\n\n")); rc = yyparse (); + input_context_drain (); yylex_destroy (); closedb (); sigaction (SIGPIPE, &old_act, NULL); diff --git a/src/gdbmtool.h b/src/gdbmtool.h index 2ad32b5..5486ac4 100644 --- a/src/gdbmtool.h +++ b/src/gdbmtool.h @@ -184,6 +184,7 @@ instream_t instream_readline_create (void); int interactive (void); int input_context_push (instream_t); int input_context_pop (void); +void input_context_drain (void); int input_history_size (void); const char *input_history_get (int n); const char *input_stream_name (void); @@ -290,7 +291,7 @@ struct command; int command_lookup (const char *str, struct locus *loc, struct command **pcmd); int run_command (struct command *cmd, struct gdbmarglist *arglist); -void run_last_command (void); +int run_last_command (void); struct xdatum; void xd_expand (struct xdatum *xd, size_t size); @@ -359,7 +360,11 @@ int variable_unset(const char *name); int variable_is_set (const char *name); int variable_is_true (const char *name); void variable_print_all (FILE *fp); - +static inline int +gdbm_error_is_masked (int e) +{ + return variable_get ("errormask", VART_INT, (void**)&e) == VAR_OK && e == 1; +} int unescape (int c); int escape (int c); @@ -74,12 +74,17 @@ stmtlist : stmt stmt : /* empty */ eol { - run_last_command (); + if (run_last_command () && variable_is_set ("errorexit")) + { + YYABORT; + } } | command arglist eol { - if (run_command ($1, &$2) && !interactive ()) - exit (EXIT_USAGE); + if (run_command ($1, &$2) && variable_is_set ("errorexit")) + { + YYABORT; + } } | set eol | defn eol @@ -394,7 +399,9 @@ dberror (char const *fmt, ...) { int ec = errno; va_list ap; - + + if (gdbm_error_is_masked (gdbm_errno)) + return; if (!interactive ()) fprintf (stderr, "%s: ", progname); YY_LOCATION_PRINT (stderr, yylloc); @@ -164,6 +164,13 @@ input_context_pop (void) return 0; } +void +input_context_drain (void) +{ + while (!input_context_pop ()) + ; +} + static int t_num (int base) { @@ -50,6 +50,9 @@ static int fd_sethook (struct variable *, union value *); static int centfree_sethook (struct variable *var, union value *v); static int coalesce_sethook (struct variable *var, union value *v); static int cachesize_sethook (struct variable *var, union value *v); +static int errormask_sethook (struct variable *var, union value *v); +static int errormask_typeconv (struct variable *var, int type, void **retptr); +static int errorexit_sethook (struct variable *var, union value *v); static struct variable vartab[] = { /* Top-level prompt */ @@ -172,6 +175,17 @@ static struct variable vartab[] = { .flags = VARF_DFL, .sethook = fd_sethook }, + { + .name = "errorexit", + .type = VART_BOOL, + .sethook = errorexit_sethook + }, + { + .name = "errormask", + .type = VART_STRING, + .sethook = errormask_sethook, + .typeconv = errormask_typeconv + }, { NULL } }; @@ -621,4 +635,149 @@ coalesce_sethook (struct variable *var, union value *v) return gdbmshell_setopt ("GDBM_SETCOALESCEBLKS", GDBM_SETCOALESCEBLKS, v->bool) == 0 ? VAR_OK : VAR_ERR_BADVALUE; } - + +const char * const errname[_GDBM_MAX_ERRNO+1] = { + [GDBM_NO_ERROR] = "GDBM_NO_ERROR", + [GDBM_MALLOC_ERROR] = "GDBM_MALLOC_ERROR", + [GDBM_BLOCK_SIZE_ERROR] = "GDBM_BLOCK_SIZE_ERROR", + [GDBM_FILE_OPEN_ERROR] = "GDBM_FILE_OPEN_ERROR", + [GDBM_FILE_WRITE_ERROR] = "GDBM_FILE_WRITE_ERROR", + [GDBM_FILE_SEEK_ERROR] = "GDBM_FILE_SEEK_ERROR", + [GDBM_FILE_READ_ERROR] = "GDBM_FILE_READ_ERROR", + [GDBM_BAD_MAGIC_NUMBER] = "GDBM_BAD_MAGIC_NUMBER", + [GDBM_EMPTY_DATABASE] = "GDBM_EMPTY_DATABASE", + [GDBM_CANT_BE_READER] = "GDBM_CANT_BE_READER", + [GDBM_CANT_BE_WRITER] = "GDBM_CANT_BE_WRITER", + [GDBM_READER_CANT_DELETE] = "GDBM_READER_CANT_DELETE", + [GDBM_READER_CANT_STORE] = "GDBM_READER_CANT_STORE", + [GDBM_READER_CANT_REORGANIZE] = "GDBM_READER_CANT_REORGANIZE", + [GDBM_UNKNOWN_ERROR] = "GDBM_UNKNOWN_ERROR", + [GDBM_ITEM_NOT_FOUND] = "GDBM_ITEM_NOT_FOUND", + [GDBM_REORGANIZE_FAILED] = "GDBM_REORGANIZE_FAILED", + [GDBM_CANNOT_REPLACE] = "GDBM_CANNOT_REPLACE", + [GDBM_MALFORMED_DATA] = "GDBM_MALFORMED_DATA", + [GDBM_OPT_ALREADY_SET] = "GDBM_OPT_ALREADY_SET", + [GDBM_OPT_BADVAL] = "GDBM_OPT_BADVAL", + [GDBM_BYTE_SWAPPED] = "GDBM_BYTE_SWAPPED", + [GDBM_BAD_FILE_OFFSET] = "GDBM_BAD_FILE_OFFSET", + [GDBM_BAD_OPEN_FLAGS] = "GDBM_BAD_OPEN_FLAGS", + [GDBM_FILE_STAT_ERROR] = "GDBM_FILE_STAT_ERROR", + [GDBM_FILE_EOF] = "GDBM_FILE_EOF", + [GDBM_NO_DBNAME] = "GDBM_NO_DBNAME", + [GDBM_ERR_FILE_OWNER] = "GDBM_ERR_FILE_OWNER", + [GDBM_ERR_FILE_MODE] = "GDBM_ERR_FILE_MODE", + [GDBM_NEED_RECOVERY] = "GDBM_NEED_RECOVERY", + [GDBM_BACKUP_FAILED] = "GDBM_BACKUP_FAILED", + [GDBM_DIR_OVERFLOW] = "GDBM_DIR_OVERFLOW", + [GDBM_BAD_BUCKET] = "GDBM_BAD_BUCKET", + [GDBM_BAD_HEADER] = "GDBM_BAD_HEADER", + [GDBM_BAD_AVAIL] = "GDBM_BAD_AVAIL", + [GDBM_BAD_HASH_TABLE] = "GDBM_BAD_HASH_TABLE", + [GDBM_BAD_DIR_ENTRY] = "GDBM_BAD_DIR_ENTRY", + [GDBM_FILE_CLOSE_ERROR] = "GDBM_FILE_CLOSE_ERROR", + [GDBM_FILE_SYNC_ERROR] = "GDBM_FILE_SYNC_ERROR", + [GDBM_FILE_TRUNCATE_ERROR] = "GDBM_FILE_TRUNCATE_ERROR", + [GDBM_BUCKET_CACHE_CORRUPTED] = "GDBM_BUCKET_CACHE_CORRUPTED", + [GDBM_BAD_HASH_ENTRY] = "GDBM_BAD_HASH_ENTRY", + [GDBM_ERR_SNAPSHOT_CLONE] = "GDBM_ERR_SNAPSHOT_CLONE", + [GDBM_ERR_REALPATH] = "GDBM_ERR_REALPATH", + [GDBM_ERR_USAGE] = "GDBM_ERR_USAGE", +}; + +static int +str2errcode (char const *str) +{ + int i; +#define GDBM_PREFIX "GDBM_" +#define GDBM_PREFIX_LEN (sizeof (GDBM_PREFIX) - 1) + + if (strncasecmp (str, GDBM_PREFIX, GDBM_PREFIX_LEN) == 0) + str += GDBM_PREFIX_LEN; + + for (i = 0; i < ARRAY_SIZE (errname); i++) + if (strcasecmp (errname[i] + GDBM_PREFIX_LEN, str) == 0) + return i; + + return -1; +} + +static char gdbmshell_errmask[_GDBM_MAX_ERRNO+1]; + +static int +errormask_sethook (struct variable *var, union value *v) +{ + if (!v) + { + memset (gdbmshell_errmask, 0, sizeof (gdbmshell_errmask)); + } + else + { + char *t; + + for (t = strtok (v->string, ","); t; t = strtok (NULL, ",")) + { + int len, val, e; + + while (t[0] == ' ' || t[0] == '\t') + t++; + len = strlen (t); + while (len > 0 && (t[len-1] == ' ' || t[len-1] == '\t')) + len--; + t[len] = 0; + + if (t[0] == '-') + { + val = 0; + t++; + } + else + { + val = 1; + } + if (strcmp (t, "all") == 0) + { + for (e = 1; e < ARRAY_SIZE (gdbmshell_errmask); e++) + gdbmshell_errmask[e] = val; + } + else + { + e = str2errcode (t); + if (e == -1) + terror (_("unrecognized error code: %s"), t); + else + gdbmshell_errmask[e] = val; + } + } + } + return VAR_OK; +} + +static int +errormask_typeconv (struct variable *var, int type, void **retptr) +{ + if (type == VART_INT) + { + int n = *(int*) retptr; + if (n >= 0 && n < ARRAY_SIZE (gdbmshell_errmask)) + { + *(int*) retptr = gdbmshell_errmask[n]; + return VAR_OK; + } + else + return VAR_ERR_BADVALUE; + } + return VAR_ERR_BADTYPE; +} + +static int +errorexit_sethook (struct variable *var, union value *v) +{ + if (v) + { + if (interactive ()) + { + return VAR_ERR_BADVALUE; + } + } + return VAR_OK; +} |