aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2021-08-16 21:54:00 +0300
committerSergey Poznyakoff <gray@gnu.org>2021-09-03 13:23:50 +0300
commit9e4213610f56454a84d614511e5ed7c7c9bd2591 (patch)
tree7c42b98d77920dda9be938938be6ad783420d4c8 /src
parent6f3160eade02dd21498e765f29d72832ced50913 (diff)
downloadgdbm-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.c222
-rw-r--r--src/gdbmtool.h9
-rw-r--r--src/gram.y15
-rw-r--r--src/lex.l7
-rw-r--r--src/var.c161
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 (&param, &cenv);
+ rc = cmd->handler (&param, &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);
diff --git a/src/gram.y b/src/gram.y
index 4b1bb18..662c9e8 100644
--- a/src/gram.y
+++ b/src/gram.y
@@ -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);
diff --git a/src/lex.l b/src/lex.l
index 09f6ccd..b2d6539 100644
--- a/src/lex.l
+++ b/src/lex.l
@@ -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)
{
diff --git a/src/var.c b/src/var.c
index 7b583e2..f5fdaf3 100644
--- a/src/var.c
+++ b/src/var.c
@@ -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;
+}

Return to:

Send suggestions and report system problems to the System administrator.