aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2016-07-08 11:28:53 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2016-07-08 14:12:34 +0300
commit4aef6b36f862e46723403bc6422ac47058a5ef19 (patch)
treefa7afe6ed8f1abf080fa764bda1bbc81e07f407b /src
parent260102cf7f75db3c87d04a06eb8054853cacce97 (diff)
downloadgdbm-4aef6b36f862e46723403bc6422ac47058a5ef19.tar.gz
gdbm-4aef6b36f862e46723403bc6422ac47058a5ef19.tar.bz2
Fix error handling in gdbm_fetch, gdbm_firstkey, and gdbm_nextkey.
* src/gdbmfetch.c: Hanlde out of memory error. * src/findkey.c: Set gdbm_errno to GDBM_ITEM_NOT_FOUND if nothing was found. * src/gdbmdelete.c: Don't set gdbm_errno after _gdbm_findkey returns -1. It's been done already. * src/gdbmexp.c (gdbm_export_to_file): Return -1 if gdbm_fetch fails. * src/gdbmseq.c (get_next_key): Set gdbm_errno to GDBM_ITEM_NOT_FOUND if there's no next key. Don't call _gdbm_fatal on out of memory condition. (gdbm_nextkey): Set gdbm_errno to GDBM_ITEM_NOT_FOUND if there's no next key. * src/gdbmtool.c (fetch_handler) (firstkey_handler,nextkey_handler): Check gdbm_errno. * src/gdbmstore.c: Handle error return from _gdbm_findkey. * tests/gtdump.c: Likewise. * tests/gtfetch.c: Likewise. * doc/gdbm.texi: Document changes. * doc/gdbm.3: Likewise. * configure.ac: Version 1.12.90 * NEWS: Update. * .gitignore: Update.
Diffstat (limited to 'src')
-rw-r--r--src/findkey.c17
-rw-r--r--src/gdbmdelete.c9
-rw-r--r--src/gdbmexp.c12
-rw-r--r--src/gdbmfetch.c14
-rw-r--r--src/gdbmseq.c38
-rw-r--r--src/gdbmstore.c7
-rw-r--r--src/gdbmtool.c14
7 files changed, 73 insertions, 38 deletions
diff --git a/src/findkey.c b/src/findkey.c
index 08e8ebc..b3ebe0b 100644
--- a/src/findkey.c
+++ b/src/findkey.c
@@ -1,8 +1,8 @@
/* findkey.c - The routine that finds a key entry in the file. */
/* This file is part of GDBM, the GNU data base manager.
- Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013 Free Software Foundation,
- Inc.
+ Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013,
+ 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
@@ -74,9 +74,9 @@ _gdbm_read_entry (GDBM_FILE dbf, int elem_loc)
/* Find the KEY in the file and get ready to read the associated data. The
return value is the location in the current hash bucket of the KEY's
entry. If it is found, a pointer to the data and the key are returned
- in DPTR. If it is not found, the value -1 is returned. Since find
- key computes the hash value of key, that value is returned in
- NEW_HASH_VAL. */
+ in DPTR. If it is not found, the value -1 is returned and gdbm_errno is
+ set to GDBM_ITEM_NOT_FOUND. Since find key computes the hash value of key,
+ that value is returned in NEW_HASH_VAL. */
int
_gdbm_findkey (GDBM_FILE dbf, datum key, char **dptr, int *new_hash_val)
{
@@ -116,7 +116,8 @@ _gdbm_findkey (GDBM_FILE dbf, datum key, char **dptr, int *new_hash_val)
{
/* Current elem_loc is not the item, go to next item. */
elem_loc = (elem_loc + 1) % dbf->header->bucket_elems;
- if (elem_loc == home_loc) return -1;
+ if (elem_loc == home_loc)
+ break;
bucket_hash_val = dbf->bucket->h_table[elem_loc].hash_value;
}
else
@@ -134,13 +135,15 @@ _gdbm_findkey (GDBM_FILE dbf, datum key, char **dptr, int *new_hash_val)
{
/* Not the item, try the next one. Return if not found. */
elem_loc = (elem_loc + 1) % dbf->header->bucket_elems;
- if (elem_loc == home_loc) return -1;
+ if (elem_loc == home_loc)
+ break;
bucket_hash_val = dbf->bucket->h_table[elem_loc].hash_value;
}
}
}
/* If we get here, we never found the key. */
+ gdbm_errno = GDBM_ITEM_NOT_FOUND;
return -1;
}
diff --git a/src/gdbmdelete.c b/src/gdbmdelete.c
index 1970422..b308c51 100644
--- a/src/gdbmdelete.c
+++ b/src/gdbmdelete.c
@@ -1,8 +1,8 @@
/* gdbmdelete.c - Remove the key and its associated data from the database. */
/* This file is part of GDBM, the GNU data base manager.
- Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013 Free Software Foundation,
- Inc.
+ Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013,
+ 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
@@ -51,10 +51,7 @@ gdbm_delete (GDBM_FILE dbf, datum key)
/* Find the item. */
elem_loc = _gdbm_findkey (dbf, key, &find_data, &hash_val);
if (elem_loc == -1)
- {
- gdbm_errno = GDBM_ITEM_NOT_FOUND;
- return -1;
- }
+ return -1;
/* Save the element. */
elem = dbf->bucket->h_table[elem_loc];
diff --git a/src/gdbmexp.c b/src/gdbmexp.c
index e3babc0..e68457f 100644
--- a/src/gdbmexp.c
+++ b/src/gdbmexp.c
@@ -1,7 +1,7 @@
/* gdbmexp.c - Export a GDBM database. */
/* This file is part of GDBM, the GNU data base manager.
- Copyright (C) 2007, 2011, 2013 Free Software Foundation, Inc.
+ Copyright (C) 2007, 2011, 2013, 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
@@ -46,7 +46,12 @@ gdbm_export_to_file (GDBM_FILE dbf, FILE *fp)
while (key.dptr != NULL)
{
data = gdbm_fetch (dbf, key);
- if (data.dptr != NULL)
+ if (data.dptr == NULL)
+ {
+ if (gdbm_errno != GDBM_NO_ERROR)
+ return -1;
+ }
+ else
{
/* Add the data to the new file. */
size = htonl (key.dsize);
@@ -61,6 +66,7 @@ gdbm_export_to_file (GDBM_FILE dbf, FILE *fp)
if (fwrite (data.dptr, data.dsize, 1, fp) != 1)
goto write_fail;
}
+
nextkey = gdbm_nextkey (dbf, key);
free (key.dptr);
free (data.dptr);
@@ -68,6 +74,8 @@ gdbm_export_to_file (GDBM_FILE dbf, FILE *fp)
count++;
}
+ if (gdbm_errno != GDBM_ITEM_NOT_FOUND)
+ return -1;
return count;
diff --git a/src/gdbmfetch.c b/src/gdbmfetch.c
index 83d4204..f9a2e91 100644
--- a/src/gdbmfetch.c
+++ b/src/gdbmfetch.c
@@ -1,8 +1,8 @@
/* gdbmfetch.c - Find a key and return the associated data. */
/* This file is part of GDBM, the GNU data base manager.
- Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013 Free Software Foundation,
- Inc.
+ Copyright (C) 1990, 1991, 1993, 2007, 2011,
+ 2013, 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
@@ -53,11 +53,13 @@ gdbm_fetch (GDBM_FILE dbf, datum key)
return_val.dptr = (char *) malloc (1);
else
return_val.dptr = (char *) malloc (return_val.dsize);
- if (return_val.dptr == NULL) _gdbm_fatal (dbf, _("malloc error"));
+ if (return_val.dptr == NULL)
+ {
+ gdbm_errno = GDBM_MALLOC_ERROR;
+ return return_val;
+ }
memcpy (return_val.dptr, find_data, return_val.dsize);
}
-
- /* Check for an error and return. */
- if (return_val.dptr == NULL) gdbm_errno = GDBM_ITEM_NOT_FOUND;
+
return return_val;
}
diff --git a/src/gdbmseq.c b/src/gdbmseq.c
index 4167697..114cf11 100644
--- a/src/gdbmseq.c
+++ b/src/gdbmseq.c
@@ -1,8 +1,8 @@
/* gdbmseq.c - Routines to visit all keys. Not in sorted order. */
/* This file is part of GDBM, the GNU data base manager.
- Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013 Free Software Foundation,
- Inc.
+ Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013,
+ 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
@@ -28,7 +28,13 @@ extern char *_gdbm_read_entry (GDBM_FILE , int);
/* Find and read the next entry in the hash structure for DBF starting
at ELEM_LOC of the current bucket and using RETURN_VAL as the place to
- put the data that is found. */
+ put the data that is found.
+
+ If no next key is found, gdbm_errno is set to GDBM_ITEM_NOT_FOUND
+ and RETURN_VAL remains unmodified.
+
+ On error, gdbm_errno is set.
+*/
static void
get_next_key (GDBM_FILE dbf, int elem_loc, datum *return_val)
@@ -57,8 +63,11 @@ get_next_key (GDBM_FILE dbf, int elem_loc, datum *return_val)
if (dbf->bucket_dir < GDBM_DIR_COUNT (dbf))
_gdbm_get_bucket (dbf, dbf->bucket_dir);
else
- /* No next key, just return. */
- return ;
+ {
+ /* No next key, just return. */
+ gdbm_errno = GDBM_ITEM_NOT_FOUND;
+ return;
+ }
}
found = dbf->bucket->h_table[elem_loc].hash_value != -1;
}
@@ -70,8 +79,13 @@ get_next_key (GDBM_FILE dbf, int elem_loc, datum *return_val)
return_val->dptr = (char *) malloc (1);
else
return_val->dptr = (char *) malloc (return_val->dsize);
- if (return_val->dptr == NULL) _gdbm_fatal (dbf, _("malloc error"));
- memcpy (return_val->dptr, find_data, return_val->dsize);
+ if (return_val->dptr == NULL)
+ {
+ return_val->dsize = 0;
+ gdbm_errno = GDBM_MALLOC_ERROR;
+ }
+ else
+ memcpy (return_val->dptr, find_data, return_val->dsize);
}
@@ -116,12 +130,16 @@ gdbm_nextkey (GDBM_FILE dbf, datum key)
return_val.dptr = NULL;
/* Do we have a valid key? */
- if (key.dptr == NULL) return return_val;
-
+ if (key.dptr == NULL)
+ {
+ gdbm_errno = GDBM_ITEM_NOT_FOUND; /* FIXME: special error code perhaps */
+ return return_val;
+ }
+
/* Find the key. */
elem_loc = _gdbm_findkey (dbf, key, &find_data, &hash_val);
if (elem_loc == -1) return return_val;
-
+
/* Find the next key. */
get_next_key (dbf, elem_loc, &return_val);
diff --git a/src/gdbmstore.c b/src/gdbmstore.c
index 8c6064d..3cb7560 100644
--- a/src/gdbmstore.c
+++ b/src/gdbmstore.c
@@ -1,8 +1,8 @@
/* gdbmstore.c - Add a new key/data pair to the database. */
/* This file is part of GDBM, the GNU data base manager.
- Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013 Free Software Foundation,
- Inc.
+ Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013,
+ 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
@@ -99,7 +99,8 @@ gdbm_store (GDBM_FILE dbf, datum key, datum content, int flags)
return 1;
}
}
-
+ else if (gdbm_errno != GDBM_ITEM_NOT_FOUND)
+ return -1;
/* Get the file address for the new space.
(Current bucket's free space is first place to look.) */
diff --git a/src/gdbmtool.c b/src/gdbmtool.c
index 69acacd..65b6740 100644
--- a/src/gdbmtool.c
+++ b/src/gdbmtool.c
@@ -415,7 +415,7 @@ delete_handler (struct handler_param *param)
if (gdbm_errno == GDBM_ITEM_NOT_FOUND)
terror (_("Item not found"));
else
- terror (_("Can't delete: %s"), gdbm_strerror (gdbm_errno));
+ terror (_("Can't delete: %s"), gdbm_strerror (gdbm_errno));
}
}
@@ -430,8 +430,10 @@ fetch_handler (struct handler_param *param)
fputc ('\n', param->fp);
free (return_data.dptr);
}
- else
+ else if (gdbm_errno == GDBM_ITEM_NOT_FOUND)
fprintf (stderr, _("No such item found.\n"));
+ else
+ terror (_("Can't fetch data: %s"), gdbm_strerror (gdbm_errno));
}
/* store KEY DATA - store data */
@@ -463,8 +465,10 @@ firstkey_handler (struct handler_param *param)
free (return_data.dptr);
}
- else
+ else if (gdbm_errno == GDBM_ITEM_NOT_FOUND)
fprintf (param->fp, _("No such item found.\n"));
+ else
+ terror (_("Can't find key: %s"), gdbm_strerror (gdbm_errno));
}
/* next [KEY] - next key */
@@ -492,12 +496,14 @@ nextkey_handler (struct handler_param *param)
free (return_data.dptr);
}
- else
+ else if (gdbm_errno == GDBM_ITEM_NOT_FOUND)
{
fprintf (stderr, _("No such item found.\n"));
free (key_data.dptr);
key_data.dptr = NULL;
}
+ else
+ terror (_("Can't find key: %s"), gdbm_strerror (gdbm_errno));
}
/* reorganize */

Return to:

Send suggestions and report system problems to the System administrator.