aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2021-08-30 19:22:24 +0300
committerSergey Poznyakoff <gray@gnu.org>2021-09-03 13:23:50 +0300
commitd88abe096dbce5b00aa0d24b18718f5e978dd8fa (patch)
treee42f4a63818ef8433d34670ee2649ddd9c213013 /src
parent4b603e6c021f359427e90768f1576edf3df78847 (diff)
downloadgdbm-d88abe096dbce5b00aa0d24b18718f5e978dd8fa.tar.gz
gdbm-d88abe096dbce5b00aa0d24b18718f5e978dd8fa.tar.bz2
Change semantics of the errorexit variable.
The "errorexit" variable is a string variable with the same syntax as errormask. If a GDBM error is reported and the corresponding gdbm_errno value is listed in this variable, further script execution is aborted. Setting it as boolean value is equivalent to set errorexit="all". * src/gdbmshell.c (all handlers): Return a GDBMSHELL_* error code. (closedb): Unset the fd variable only after closing the database. (run_command): If handler reported GDBM error and gdbm_errno is listed in the errorexit variable, return 1 (which will cause YYABORT in parser). * src/gdbmtool.h (VAR_ERR_GDBM): New variable error code. (variable_has_errno): New function. (gdbm_error_is_masked): Rewrite using variable_has_errno. * src/gram.y: Abort if run_command or run_last_command return !0. Handle VAR_ERR_GDBM. * src/var.c (variable): New member: data. (errorexit variable): Change type to VART_STRING; install sethook and typeconv. (variable_unset): When unsetting string variable, free and reset its value. (cachesize_sethook,centfree_sethook) (coalesce_sethook): Return VAR_ERR_GDBM on gdbmshell_setopt error. (errormask_sethook): Keep the mask vector in the data member. Handle conversions from boolean. (errorexit_sethook): Call errormask_sethook unless in interactive session.
Diffstat (limited to 'src')
-rw-r--r--src/gdbmshell.c282
-rw-r--r--src/gdbmtool.h27
-rw-r--r--src/gram.y8
-rw-r--r--src/var.c126
4 files changed, 261 insertions, 182 deletions
diff --git a/src/gdbmshell.c b/src/gdbmshell.c
index a1ba4b2..0961ca3 100644
--- a/src/gdbmshell.c
+++ b/src/gdbmshell.c
@@ -36,6 +36,16 @@ static GDBM_FILE gdbm_file = NULL; /* Database to operate upon */
static datum key_data; /* Current key */
static datum return_data; /* Current data */
+/* Return values for hanlders: */
+enum
+ {
+ GDBMSHELL_OK, /* Success */
+ GDBMSHELL_GDBM_ERR, /* GDBM error */
+ GDBMSHELL_SYNTAX, /* Syntax error (invalid argument etc) */
+ GDBMSHELL_ERR, /* Other error */
+ GDBMSHELL_CANCEL /* Operation canceled */
+ };
+
static void
datum_free (datum *dp)
{
@@ -65,11 +75,11 @@ closedb (void)
{
gdbm_close (gdbm_file);
gdbm_file = NULL;
+ variable_unset ("fd");
}
datum_free (&key_data);
datum_free (&return_data);
- variable_unset ("fd");
}
static int
@@ -108,7 +118,7 @@ opendb (char *dbname, int fd)
access (dbname, F_OK) == 0)
{
if (!getyn (_("database %s already exists; overwrite"), dbname))
- return 1;
+ return GDBMSHELL_CANCEL;
}
}
@@ -139,7 +149,7 @@ opendb (char *dbname, int fd)
if (db == NULL)
{
dberror (_("cannot open database %s"), dbname);
- return 1;
+ return GDBMSHELL_GDBM_ERR;
}
if (cache_size &&
@@ -159,7 +169,7 @@ opendb (char *dbname, int fd)
gdbm_close (gdbm_file);
gdbm_file = db;
- return 0;
+ return GDBMSHELL_OK;
}
static int
@@ -173,7 +183,7 @@ checkdb (void)
variable_get ("fd", VART_INT, (void**) &fd);
return opendb (filename, fd);
}
- return 0;
+ return GDBMSHELL_OK;
}
static int
@@ -306,7 +316,7 @@ _gdbm_print_avail_list (FILE *fp, GDBM_FILE dbf)
int rc = gdbm_avail_traverse (dbf, avail_list_print, fp);
if (rc)
dberror (_("%s failed"), "gdbm_avail_traverse");
- return rc;
+ return GDBMSHELL_GDBM_ERR;
}
static void
@@ -378,7 +388,8 @@ open_handler (struct command_param *param,
{
char *filename;
int fd = -1;
-
+ int rc;
+
closedb ();
if (param->argc == 1)
@@ -389,16 +400,15 @@ open_handler (struct command_param *param,
variable_get ("fd", VART_INT, (void**) &fd);
}
- if (opendb (filename, fd) == 0)
+ if ((rc = opendb (filename, fd)) == GDBMSHELL_OK)
{
variable_set ("filename", VART_STRING, filename);
if (fd >= 0)
variable_set ("fd", VART_INT, &fd);
else
variable_unset ("fd");
- return 0;
}
- return 1;
+ return rc;
}
/* Close database */
@@ -410,7 +420,7 @@ close_handler (struct command_param *param GDBM_ARG_UNUSED,
terror ("%s", _("nothing to close"));
else
closedb ();
- return 0;
+ return GDBMSHELL_OK;
}
static char *
@@ -442,7 +452,7 @@ count_handler (struct command_param *param GDBM_ARG_UNUSED,
if (gdbm_count (gdbm_file, &count))
{
dberror (_("%s failed"), "gdbm_count");
- return 1;
+ return GDBMSHELL_GDBM_ERR;
}
else
{
@@ -458,7 +468,7 @@ count_handler (struct command_param *param GDBM_ARG_UNUSED,
count),
p);
}
- return 0;
+ return GDBMSHELL_OK;
}
/* delete KEY - delete a key*/
@@ -474,9 +484,9 @@ delete_handler (struct command_param *param, struct command_environ *cenv)
}
else
dberror ("%s", _("Can't delete"));
- return 1;
+ return GDBMSHELL_GDBM_ERR;
}
- return 0;
+ return GDBMSHELL_OK;
}
/* fetch KEY - fetch a record by its key */
@@ -489,7 +499,7 @@ 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;
+ return GDBMSHELL_OK;
}
else if (gdbm_errno == GDBM_ITEM_NOT_FOUND)
{
@@ -498,7 +508,7 @@ fetch_handler (struct command_param *param, struct command_environ *cenv)
}
else
dberror ("%s", _("Can't fetch data"));
- return 1;
+ return GDBMSHELL_GDBM_ERR;
}
/* store KEY DATA - store data */
@@ -511,9 +521,9 @@ store_handler (struct command_param *param,
GDBM_REPLACE) != 0)
{
dberror ("%s", _("Item not inserted"));
- return 1;
+ return GDBMSHELL_GDBM_ERR;
}
- return 0;
+ return GDBMSHELL_OK;
}
/* first - begin iteration */
@@ -533,7 +543,7 @@ firstkey_handler (struct command_param *param, struct command_environ *cenv)
fputc ('\n', cenv->fp);
datum_free (&return_data);
- return 0;
+ return GDBMSHELL_OK;
}
else if (gdbm_errno == GDBM_ITEM_NOT_FOUND)
{
@@ -542,7 +552,7 @@ firstkey_handler (struct command_param *param, struct command_environ *cenv)
}
else
dberror ("%s", _("Can't find first key"));
- return 1;
+ return GDBMSHELL_GDBM_ERR;
}
/* next [KEY] - next key */
@@ -569,7 +579,7 @@ nextkey_handler (struct command_param *param, struct command_environ *cenv)
fputc ('\n', cenv->fp);
datum_free (&return_data);
- return 0;
+ return GDBMSHELL_OK;
}
else if (gdbm_errno == GDBM_ITEM_NOT_FOUND)
{
@@ -579,7 +589,7 @@ nextkey_handler (struct command_param *param, struct command_environ *cenv)
}
else
dberror ("%s", _("Can't find next key"));
- return 1;
+ return GDBMSHELL_GDBM_ERR;
}
/* reorganize */
@@ -590,11 +600,11 @@ reorganize_handler (struct command_param *param GDBM_ARG_UNUSED,
if (gdbm_reorganize (gdbm_file))
{
dberror ("%s", _("Reorganization failed"));
- return 1;
+ return GDBMSHELL_GDBM_ERR;
}
else
fprintf (cenv->fp, "%s\n", _("Reorganization succeeded."));
- return 0;
+ return GDBMSHELL_OK;
}
static void
@@ -672,7 +682,7 @@ recover_handler (struct command_param *param, struct command_environ *cenv)
else
{
terror (_("unrecognized argument: %s"), arg);
- return 1;
+ return GDBMSHELL_SYNTAX;
}
}
@@ -706,6 +716,7 @@ recover_handler (struct command_param *param, struct command_environ *cenv)
else
{
dberror ("%s", _("Recovery failed"));
+ rc = GDBMSHELL_GDBM_ERR;
}
return rc;
}
@@ -716,11 +727,13 @@ avail_begin (struct command_param *param GDBM_ARG_UNUSED,
struct command_environ *cenv GDBM_ARG_UNUSED,
size_t *exp_count)
{
- if (checkdb ())
- return 1;
- if (exp_count)
- *exp_count = _gdbm_avail_list_size (gdbm_file, SIZE_T_MAX);
- return 0;
+ int rc = checkdb ();
+ if (rc == GDBMSHELL_OK)
+ {
+ if (exp_count)
+ *exp_count = _gdbm_avail_list_size (gdbm_file, SIZE_T_MAX);
+ }
+ return rc;
}
static int
@@ -736,15 +749,16 @@ print_current_bucket_begin (struct command_param *param GDBM_ARG_UNUSED,
struct command_environ *cenv GDBM_ARG_UNUSED,
size_t *exp_count)
{
- if (checkdb ())
- return 1;
- if (!gdbm_file->bucket)
- return 0;
- if (exp_count)
- *exp_count = gdbm_file->bucket
+ int rc = checkdb ();
+
+ if (rc == GDBMSHELL_OK)
+ {
+ if (exp_count)
+ *exp_count = gdbm_file->bucket
? bucket_print_lines (gdbm_file->bucket) + 3
: 1;
- return 0;
+ }
+ return rc;
}
static int
@@ -765,7 +779,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;
+ return GDBMSHELL_OK;
}
int
@@ -798,28 +812,29 @@ print_bucket_begin (struct command_param *param,
struct command_environ *cenv GDBM_ARG_UNUSED,
size_t *exp_count)
{
+ int rc;
int temp;
- if (checkdb ())
- return 1;
+ if ((rc = checkdb ()) != GDBMSHELL_OK)
+ return rc;
if (getnum (&temp, PARAM_STRING (param, 0), NULL))
- return 1;
+ return GDBMSHELL_SYNTAX;
if (temp >= GDBM_DIR_COUNT (gdbm_file))
{
terror (_("bucket number out of range (0..%lu)"),
GDBM_DIR_COUNT (gdbm_file));
- return 1;
+ return GDBMSHELL_SYNTAX;
}
if (_gdbm_get_bucket (gdbm_file, temp))
{
dberror (_("%s failed"), "_gdbm_get_bucket");
- return 1;
+ return GDBMSHELL_GDBM_ERR;
}
if (exp_count)
*exp_count = bucket_print_lines (gdbm_file->bucket) + 3;
- return 0;
+ return GDBMSHELL_OK;
}
/* dir - print hash directory */
@@ -828,11 +843,14 @@ print_dir_begin (struct command_param *param GDBM_ARG_UNUSED,
struct command_environ *cenv GDBM_ARG_UNUSED,
size_t *exp_count)
{
- if (checkdb ())
- return 1;
- if (exp_count)
- *exp_count = GDBM_DIR_COUNT (gdbm_file) + 3;
- return 0;
+ int rc;
+
+ if ((rc = checkdb ()) == GDBMSHELL_OK)
+ {
+ if (exp_count)
+ *exp_count = GDBM_DIR_COUNT (gdbm_file) + 3;
+ }
+ return rc;
}
static size_t
@@ -862,7 +880,7 @@ print_dir_handler (struct command_param *param GDBM_ARG_UNUSED,
fprintf (cenv->fp, " %10d: %12lu\n",
i, (unsigned long) gdbm_file->dir[i]);
- return 0;
+ return GDBMSHELL_OK;
}
/* header - print file handler */
@@ -871,10 +889,11 @@ print_header_begin (struct command_param *param GDBM_ARG_UNUSED,
struct command_environ *cenv GDBM_ARG_UNUSED,
size_t *exp_count)
{
+ int rc;
int n;
- if (checkdb ())
- return 1;
+ if ((rc = checkdb ()) != GDBMSHELL_OK)
+ return rc;
switch (gdbm_file->header->header_magic)
{
@@ -894,7 +913,7 @@ print_header_begin (struct command_param *param GDBM_ARG_UNUSED,
if (exp_count)
*exp_count = n;
- return 0;
+ return GDBMSHELL_OK;
}
static int
@@ -947,37 +966,43 @@ print_header_handler (struct command_param *param GDBM_ARG_UNUSED,
fprintf (fp, _(" numsync = %u\n"), gdbm_file->xheader->numsync);
}
- return 0;
+ return GDBMSHELL_OK;
}
static int
sync_handler (struct command_param *param GDBM_ARG_UNUSED,
struct command_environ *cenv GDBM_ARG_UNUSED)
{
- int rc = gdbm_sync (gdbm_file);
- if (rc)
- dberror ("%s", "gdbm_sync");
- return rc;
+ if (gdbm_sync (gdbm_file))
+ {
+ dberror ("%s", "gdbm_sync");
+ return GDBMSHELL_GDBM_ERR;
+ }
+ return GDBMSHELL_OK;
}
static int
upgrade_handler (struct command_param *param GDBM_ARG_UNUSED,
struct command_environ *cenv GDBM_ARG_UNUSED)
{
- int rc = gdbm_convert (gdbm_file, GDBM_NUMSYNC);
- if (rc)
- dberror ("%s", "gdbm_convert");
- return rc;
+ if (gdbm_convert (gdbm_file, GDBM_NUMSYNC))
+ {
+ dberror ("%s", "gdbm_convert");
+ return GDBMSHELL_GDBM_ERR;
+ }
+ return GDBMSHELL_OK;
}
static int
downgrade_handler (struct command_param *param GDBM_ARG_UNUSED,
struct command_environ *cenv GDBM_ARG_UNUSED)
{
- int rc = gdbm_convert (gdbm_file, 0);
- if (rc)
- dberror ("%s", "gdbm_convert");
- return rc;
+ if (gdbm_convert (gdbm_file, 0))
+ {
+ dberror ("%s", "gdbm_convert");
+ return GDBMSHELL_GDBM_ERR;
+ }
+ return GDBMSHELL_OK;
}
struct snapshot_status_info
@@ -1187,9 +1212,9 @@ snapshot_handler (struct command_param *param, struct command_environ *cenv)
else
{
terror (_("unexpected error code: %d"), rc);
- return 1;
+ return GDBMSHELL_ERR;
}
- return 0;
+ return GDBMSHELL_OK;
}
@@ -1212,7 +1237,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;
+ return GDBMSHELL_OK;
}
/* cache - print the bucket cache */
@@ -1221,11 +1246,14 @@ print_cache_begin (struct command_param *param GDBM_ARG_UNUSED,
struct command_environ *cenv GDBM_ARG_UNUSED,
size_t *exp_count)
{
- if (checkdb ())
- return 1;
- if (exp_count)
- *exp_count = gdbm_file->cache_num + 1;
- return 0;
+ int rc;
+
+ if ((rc = checkdb ()) == GDBMSHELL_OK)
+ {
+ if (exp_count)
+ *exp_count = gdbm_file->cache_num + 1;
+ }
+ return rc;
}
static int
@@ -1233,7 +1261,7 @@ print_cache_handler (struct command_param *param GDBM_ARG_UNUSED,
struct command_environ *cenv)
{
_gdbm_print_bucket_cache (cenv->fp, gdbm_file);
- return 0;
+ return GDBMSHELL_OK;
}
/* version - print GDBM version */
@@ -1242,7 +1270,7 @@ print_version_handler (struct command_param *param GDBM_ARG_UNUSED,
struct command_environ *cenv)
{
fprintf (cenv->fp, "%s\n", gdbm_version);
- return 0;
+ return GDBMSHELL_OK;
}
/* list - List all entries */
@@ -1251,21 +1279,24 @@ list_begin (struct command_param *param GDBM_ARG_UNUSED,
struct command_environ *cenv GDBM_ARG_UNUSED,
size_t *exp_count)
{
- if (checkdb ())
- return 1;
- if (exp_count)
+ int rc;
+
+ if ((rc = checkdb ()) == GDBMSHELL_OK)
{
- gdbm_count_t count;
-
- if (gdbm_count (gdbm_file, &count))
- *exp_count = 0;
- else if (count > SIZE_T_MAX)
- *exp_count = SIZE_T_MAX;
- else
- *exp_count = count;
+ if (exp_count)
+ {
+ gdbm_count_t count;
+
+ if (gdbm_count (gdbm_file, &count))
+ *exp_count = 0;
+ else if (count > SIZE_T_MAX)
+ *exp_count = SIZE_T_MAX;
+ else
+ *exp_count = count;
+ }
}
- return 0;
+ return rc;
}
static int
@@ -1274,17 +1305,17 @@ list_handler (struct command_param *param GDBM_ARG_UNUSED,
{
datum key;
datum data;
- int rc = 0;
+ int rc = GDBMSHELL_OK;
key = gdbm_firstkey (gdbm_file);
if (!key.dptr && gdbm_errno != GDBM_ITEM_NOT_FOUND)
{
dberror ("%s", "gdbm_firstkey");
- return 1;
+ return GDBMSHELL_GDBM_ERR;
}
while (key.dptr)
{
- datum nextkey = gdbm_nextkey (gdbm_file, key);
+ datum nextkey;
data = gdbm_fetch (gdbm_file, key);
if (!data.dptr)
@@ -1292,7 +1323,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;
+ rc = GDBMSHELL_GDBM_ERR;
}
else
{
@@ -1302,13 +1333,14 @@ list_handler (struct command_param *param GDBM_ARG_UNUSED,
fputc ('\n', cenv->fp);
free (data.dptr);
}
+ nextkey = gdbm_nextkey (gdbm_file, key);
free (key.dptr);
key = nextkey;
}
if (gdbm_errno != GDBM_ITEM_NOT_FOUND)
{
- dberror ("%s", "gdbm_firstkey");
- rc = 1;
+ dberror ("%s", "gdbm_nextkey");
+ rc = GDBMSHELL_GDBM_ERR;
}
return rc;
}
@@ -1321,7 +1353,7 @@ quit_handler (struct command_param *param GDBM_ARG_UNUSED,
input_context_drain ();
if (input_context_push (instream_null_create ()))
exit (EXIT_FATAL);
- return 0;
+ return GDBMSHELL_OK;
}
/* export FILE [truncate] - export to a flat file format */
@@ -1333,7 +1365,7 @@ export_handler (struct command_param *param,
int flags = GDBM_WRCREAT;
int i;
int filemode;
- int rc;
+ int rc = GDBMSHELL_OK;
for (i = 1; i < param->argc; i++)
{
@@ -1346,16 +1378,16 @@ export_handler (struct command_param *param,
else
{
terror (_("unrecognized argument: %s"), PARAM_STRING (param, i));
- return 1;
+ return GDBMSHELL_SYNTAX;
}
}
if (variable_get ("filemode", VART_INT, (void**) &filemode))
abort ();
- rc = gdbm_dump (gdbm_file, PARAM_STRING (param, 0), format, flags, filemode);
- if (rc)
+ if (gdbm_dump (gdbm_file, PARAM_STRING (param, 0), format, flags, filemode))
{
dberror ("%s", _("error dumping database"));
+ rc = GDBMSHELL_GDBM_ERR;
}
return rc;
}
@@ -1369,7 +1401,7 @@ import_handler (struct command_param *param,
unsigned long err_line;
int meta_mask = 0;
int i;
- int rc;
+ int rc = GDBMSHELL_OK;
char *file_name;
for (i = 0; i < param->argc; i++)
@@ -1382,7 +1414,7 @@ import_handler (struct command_param *param,
{
terror (_("unrecognized argument: %s"),
PARAM_STRING (param, i));
- return 1;
+ return GDBMSHELL_SYNTAX;
}
}
@@ -1421,13 +1453,15 @@ import_handler (struct command_param *param,
else
dberror (_("cannot load from %s"), PARAM_STRING (param, 0));
}
- return rc;
+ return GDBMSHELL_GDBM_ERR;
}
free (file_name);
- rc = gdbm_setopt (gdbm_file, GDBM_GETDBNAME, &file_name, sizeof (file_name));
- if (rc)
- dberror ("%s", "GDBM_GETDBNAME");
+ if (gdbm_setopt (gdbm_file, GDBM_GETDBNAME, &file_name, sizeof (file_name)))
+ {
+ dberror ("%s", "GDBM_GETDBNAME");
+ rc = GDBMSHELL_GDBM_ERR;
+ }
else
{
variable_set ("filename", VART_STRING, file_name);
@@ -1451,7 +1485,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;
+ return GDBMSHELL_OK;
}
#if GDBM_DEBUG_ENABLE
@@ -1523,7 +1557,7 @@ debug_handler (struct command_param *param, struct command_environ *cenv)
#else
terror ("%s", _("compiled without debug support"));
#endif
- return 0;
+ return GDBMSHELL_OK;
}
static int
@@ -1552,7 +1586,7 @@ shell_handler (struct command_param *param,
if (pid == -1)
{
terror ("fork: %s", strerror (errno));
- return 1;
+ return GDBMSHELL_ERR;
}
if (pid == 0)
{
@@ -1562,7 +1596,10 @@ shell_handler (struct command_param *param,
rc = waitpid (pid, &status, 0);
if (rc == -1)
- terror ("waitpid: %s", strerror (errno));
+ {
+ terror ("waitpid: %s", strerror (errno));
+ rc = GDBMSHELL_ERR;
+ }
else if (!interactive ())
{
if (WIFEXITED (status))
@@ -1573,7 +1610,7 @@ shell_handler (struct command_param *param,
else if (WIFSIGNALED (status))
terror (_("command terminated on signal %d"), WTERMSIG (status));
}
- return 0;
+ return rc;
}
static int
@@ -1589,7 +1626,7 @@ source_handler (struct command_param *param,
input_context_drain ();
yylex_destroy ();
}
- return 0;
+ return GDBMSHELL_OK;
}
static int
@@ -1600,11 +1637,11 @@ perror_handler (struct command_param *param, struct command_environ *cenv)
if (param->argc)
{
if (getnum (&n, PARAM_STRING (param, 0), NULL))
- return 1;
+ return GDBMSHELL_SYNTAX;
}
- else if (checkdb ())
+ else if ((n = checkdb ()) != GDBMSHELL_OK)
{
- return 1;
+ return n;
}
else
{
@@ -1620,7 +1657,7 @@ perror_handler (struct command_param *param, struct command_environ *cenv)
gdbm_last_syserr (gdbm_file),
strerror (gdbm_last_syserr (gdbm_file)));
}
- return 0;
+ return GDBMSHELL_OK;
}
struct history_param
@@ -1643,7 +1680,7 @@ input_history_begin (struct command_param *param,
/* TRANSLATORS: %s is the stream name */
terror (_("input history is not available for %s input stream"),
input_stream_name ());
- return 1;
+ return GDBMSHELL_OK;
}
switch (param->argc)
@@ -1663,7 +1700,7 @@ input_history_begin (struct command_param *param,
if (from)
--from;
if (getnum (&count, param->argv[1]->v.string, NULL))
- return 1;
+ return GDBMSHELL_OK;
if (count > hlen)
count = hlen;
@@ -1674,7 +1711,7 @@ input_history_begin (struct command_param *param,
cenv->data = p;
if (exp_count)
*exp_count = count;
- return 0;
+ return GDBMSHELL_OK;
}
static int
@@ -1692,7 +1729,7 @@ input_history_handler (struct command_param *param GDBM_ARG_UNUSED,
break;
fprintf (fp, "%4d) %s\n", p->from + i + 1, s);
}
- return 0;
+ return GDBMSHELL_OK;
}
@@ -2838,6 +2875,11 @@ run_command (struct command *cmd, struct gdbmarglist *arglist)
gdbmarglist_free (&last_args);
last_args = *arglist;
}
+
+ if (rc == GDBMSHELL_GDBM_ERR && variable_has_errno ("errorexit", gdbm_errno))
+ rc = 1;
+ else
+ rc = 0;
return rc;
}
diff --git a/src/gdbmtool.h b/src/gdbmtool.h
index 5486ac4..f589537 100644
--- a/src/gdbmtool.h
+++ b/src/gdbmtool.h
@@ -345,14 +345,18 @@ extern struct dsegm *dsdef[];
#define VART_BOOL 1
#define VART_INT 2
-#define VAR_OK 0 /* operation succeeded */
-#define VAR_ERR_NOTSET 1 /* Only for variable_get:
- variable is not set */
-#define VAR_ERR_NOTDEF 2 /* no such variable */
-#define VAR_ERR_BADTYPE 3 /* variable cannot be coerced to the
- requested type (software error) */
-#define VAR_ERR_BADVALUE 4 /* Only for variable_set: the value is
- not valid for this variable. */
+enum
+ {
+ VAR_OK, /* operation succeeded */
+ VAR_ERR_NOTSET, /* Only for variable_get: variable is not set */
+ VAR_ERR_NOTDEF, /* no such variable */
+ VAR_ERR_BADTYPE, /* variable cannot be coerced to the requested type
+ (software error) */
+ VAR_ERR_BADVALUE, /* Only for variable_set: the value is not valid for
+ this variable. */
+ VAR_ERR_GDBM, /* GDBM error */
+ };
+
int variable_set (const char *name, int type, void *val);
int variable_get (const char *name, int type, void **val);
@@ -361,9 +365,14 @@ int variable_is_set (const char *name);
int variable_is_true (const char *name);
void variable_print_all (FILE *fp);
static inline int
+variable_has_errno (char *varname, int e)
+{
+ return variable_get (varname, VART_INT, (void**)&e) == VAR_OK && e == 1;
+}
+static inline int
gdbm_error_is_masked (int e)
{
- return variable_get ("errormask", VART_INT, (void**)&e) == VAR_OK && e == 1;
+ return variable_has_errno ("errormask", e);
}
int unescape (int c);
diff --git a/src/gram.y b/src/gram.y
index 662c9e8..d2b2fdc 100644
--- a/src/gram.y
+++ b/src/gram.y
@@ -74,14 +74,14 @@ stmtlist : stmt
stmt : /* empty */ eol
{
- if (run_last_command () && variable_is_set ("errorexit"))
+ if (run_last_command ())
{
YYABORT;
}
}
| command arglist eol
{
- if (run_command ($1, &$2) && variable_is_set ("errorexit"))
+ if (run_command ($1, &$2))
{
YYABORT;
}
@@ -323,6 +323,10 @@ asgn : T_IDENT
case VAR_ERR_BADVALUE:
lerror (&@1, _("%s: setting is not allowed"), $1);
break;
+
+ case VAR_ERR_GDBM:
+ dberror ("%s", _("can't set variable"));
+ break;
default:
lerror (&@1, _("unexpected error setting %s: %d"), $1, rc);
diff --git a/src/var.c b/src/var.c
index 9a828fe..7b8f3f6 100644
--- a/src/var.c
+++ b/src/var.c
@@ -38,6 +38,7 @@ struct variable
int flags;
union value init;
union value v;
+ void *data;
int (*sethook) (struct variable *, union value *);
int (*typeconv) (struct variable *, int, void **);
};
@@ -177,8 +178,9 @@ static struct variable vartab[] = {
},
{
.name = "errorexit",
- .type = VART_BOOL,
- .sethook = errorexit_sethook
+ .type = VART_STRING,
+ .sethook = errorexit_sethook,
+ .typeconv = errormask_typeconv
},
{
.name = "errormask",
@@ -370,6 +372,11 @@ variable_unset (const char *name)
if (vp->sethook && (rc = vp->sethook (vp, NULL)) != VAR_OK)
return rc;
+ if (vp->type == VART_STRING)
+ {
+ free (vp->v.string);
+ vp->v.string = NULL;
+ }
vp->flags &= ~VARF_SET;
return VAR_OK;
@@ -623,7 +630,7 @@ cachesize_sethook (struct variable *var, union value *v)
if (v->num < 0)
return VAR_ERR_BADVALUE;
return gdbmshell_setopt ("GDBM_SETCACHESIZE", GDBM_SETCACHESIZE, v->num) == 0
- ? VAR_OK : VAR_ERR_BADVALUE;
+ ? VAR_OK : VAR_ERR_GDBM;
}
static int
@@ -632,7 +639,7 @@ centfree_sethook (struct variable *var, union value *v)
if (!v)
return VAR_OK;
return gdbmshell_setopt ("GDBM_SETCENTFREE", GDBM_SETCENTFREE, v->bool) == 0
- ? VAR_OK : VAR_ERR_BADVALUE;
+ ? VAR_OK : VAR_ERR_GDBM;
}
static int
@@ -641,7 +648,7 @@ coalesce_sethook (struct variable *var, union value *v)
if (!v)
return VAR_OK;
return gdbmshell_setopt ("GDBM_SETCOALESCEBLKS", GDBM_SETCOALESCEBLKS, v->bool) == 0
- ? VAR_OK : VAR_ERR_BADVALUE;
+ ? VAR_OK : VAR_ERR_GDBM;
}
const char * const errname[_GDBM_MAX_ERRNO+1] = {
@@ -709,58 +716,76 @@ str2errcode (char const *str)
return -1;
}
-static char gdbmshell_errmask[_GDBM_MAX_ERRNO+1];
+#define ERROR_MASK_SIZE (_GDBM_MAX_ERRNO+1)
static int
errormask_sethook (struct variable *var, union value *v)
{
- if (!v)
+ char *errmask = var->data;
+
+ if (!v || strcmp (v->string, "false") == 0)
{
- memset (gdbmshell_errmask, 0, sizeof (gdbmshell_errmask));
+ if (var->data)
+ memset (errmask, 0, ERROR_MASK_SIZE);
}
else
{
char *t;
- for (t = strtok (v->string, ","); t; t = strtok (NULL, ","))
+ if (!errmask)
{
- 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 if (t[0] == '+')
- {
- val = 1;
- t++;
- }
- else
- {
- val = 1;
- }
- if (strcmp (t, "all") == 0)
- {
- for (e = 1; e < ARRAY_SIZE (gdbmshell_errmask); e++)
- gdbmshell_errmask[e] = val;
- }
- else
+ errmask = calloc (ERROR_MASK_SIZE, sizeof (char));
+ var->data = errmask;
+ }
+
+ if (strcmp (v->string, "true") == 0)
+ {
+ memset (errmask, 1, ERROR_MASK_SIZE);
+ free (v->string);
+ v->string = estrdup ("all");
+ }
+ else
+ {
+ for (t = strtok (v->string, ","); t; t = strtok (NULL, ","))
{
- e = str2errcode (t);
- if (e == -1)
- terror (_("unrecognized error code: %s"), t);
+ 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 if (t[0] == '+')
+ {
+ val = 1;
+ t++;
+ }
else
- gdbmshell_errmask[e] = val;
+ {
+ val = 1;
+ }
+ if (strcmp (t, "all") == 0)
+ {
+ for (e = 1; e < ERROR_MASK_SIZE; e++)
+ errmask[e] = val;
+ }
+ else
+ {
+ e = str2errcode (t);
+ if (e == -1)
+ terror (_("unrecognized error code: %s"), t);
+ else
+ errmask[e] = val;
+ }
}
- }
+ }
}
return VAR_OK;
}
@@ -768,12 +793,14 @@ errormask_sethook (struct variable *var, union value *v)
static int
errormask_typeconv (struct variable *var, int type, void **retptr)
{
+ char *errmask = var->data;
+
if (type == VART_INT)
{
int n = *(int*) retptr;
- if (n >= 0 && n < ARRAY_SIZE (gdbmshell_errmask))
+ if (n >= 0 && n < ERROR_MASK_SIZE)
{
- *(int*) retptr = gdbmshell_errmask[n];
+ *(int*) retptr = errmask ? errmask[n] : 0;
return VAR_OK;
}
else
@@ -785,12 +812,9 @@ errormask_typeconv (struct variable *var, int type, void **retptr)
static int
errorexit_sethook (struct variable *var, union value *v)
{
- if (v)
+ if (interactive ())
{
- if (interactive ())
- {
- return VAR_ERR_BADVALUE;
- }
+ return VAR_ERR_BADVALUE;
}
- return VAR_OK;
+ return errormask_sethook (var, v);
}

Return to:

Send suggestions and report system problems to the System administrator.