aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2016-07-09 08:40:04 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2016-07-09 08:47:16 +0300
commit479a469033903a76b9c073806037dd66176f3da0 (patch)
tree2841b611288f9343868e6ded82909b096a62e121 /src
parent2efd8358711ab3ea6c0ecaab75d195837b4b3e37 (diff)
downloadgdbm-479a469033903a76b9c073806037dd66176f3da0.tar.gz
gdbm-479a469033903a76b9c073806037dd66176f3da0.tar.bz2
Per-database error state.
Last error code is stored in the database file structure as well as in the global gdbm_errno. Special functions are provided for retrieving and clearing the last error state. * src/gdbmdefs.h (gdbm_file_info): New member: last_error * src/gdbm.h.in (gdbm_last_errno, gdbm_set_errno) (gdbm_clear_error): New protos. * src/gdbmerrno.c (gdbm_last_errno, gdbm_set_errno) (gdbm_clear_error): New functions * NEWS: Update. * compat/dbminit.c: Use gdbm_set_errno to set error state. * compat/dbmopen.c: Likewise. * src/bucket.c: Likewise. * src/findkey.c: Likewise. * src/gdbm_load.c: Likewise. * src/gdbmcount.c: Likewise. * src/gdbmdelete.c: Likewise. * src/gdbmdump.c: Likewise. * src/gdbmexists.c: Likewise. * src/gdbmexp.c: Likewise. * src/gdbmfetch.c: Likewise. * src/gdbmimp.c: Likewise. * src/gdbmload.c: Likewise. * src/gdbmopen.c: Likewise. * src/gdbmreorg.c: Likewise. * src/gdbmseq.c: Likewise. * src/gdbmsetopt.c: Likewise. * src/gdbmstore.c: Likewise. * src/gdbmsync.c: Likewise. * src/mmap.c: Likewise.
Diffstat (limited to 'src')
-rw-r--r--src/bucket.c8
-rw-r--r--src/findkey.c2
-rw-r--r--src/gdbm.h.in4
-rw-r--r--src/gdbm_load.c6
-rw-r--r--src/gdbmcount.c5
-rw-r--r--src/gdbmdefs.h6
-rw-r--r--src/gdbmdelete.c4
-rw-r--r--src/gdbmdump.c18
-rw-r--r--src/gdbmerrno.c36
-rw-r--r--src/gdbmexists.c4
-rw-r--r--src/gdbmexp.c12
-rw-r--r--src/gdbmfetch.c4
-rw-r--r--src/gdbmimp.c12
-rw-r--r--src/gdbmload.c14
-rw-r--r--src/gdbmopen.c65
-rw-r--r--src/gdbmreorg.c20
-rw-r--r--src/gdbmseq.c10
-rw-r--r--src/gdbmsetopt.c79
-rw-r--r--src/gdbmstore.c12
-rw-r--r--src/gdbmsync.c6
-rw-r--r--src/mmap.c8
21 files changed, 199 insertions, 136 deletions
diff --git a/src/bucket.c b/src/bucket.c
index c9a951c..ee0e157 100644
--- a/src/bucket.c
+++ b/src/bucket.c
@@ -1,11 +1,11 @@
/* bucket.c - The routines for playing with hash buckets. */
/* 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
the Free Software Foundation; either version 3, or (at your option)
any later version.
@@ -128,19 +128,19 @@ _gdbm_read_bucket_at (GDBM_FILE dbf, off_t off, hash_bucket *bucket,
}
/* Read the bucket. */
file_pos = __lseek (dbf, off, SEEK_SET);
if (file_pos != off)
{
- gdbm_errno = GDBM_FILE_SEEK_ERROR;
+ gdbm_set_errno (dbf, GDBM_FILE_SEEK_ERROR, 1);
return -1;
}
rc = _gdbm_full_read (dbf, bucket, size);
if (rc)
{
- gdbm_errno = rc;
+ gdbm_set_errno (dbf, rc, 1);
return -1;
}
return 0;
}
/* Split the current bucket. This includes moving all items in the bucket to
diff --git a/src/findkey.c b/src/findkey.c
index b4b3bd2..6b13fbf 100644
--- a/src/findkey.c
+++ b/src/findkey.c
@@ -146,10 +146,10 @@ _gdbm_findkey (GDBM_FILE dbf, datum key, char **ret_dptr, int *ret_hash_val)
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;
+ gdbm_set_errno (dbf, GDBM_ITEM_NOT_FOUND, 0);
return -1;
}
diff --git a/src/gdbm.h.in b/src/gdbm.h.in
index f8238b9..07ac4dc 100644
--- a/src/gdbm.h.in
+++ b/src/gdbm.h.in
@@ -174,12 +174,16 @@ extern int gdbm_load_from_file (GDBM_FILE *, FILE *, int replace,
# define _GDBM_MIN_ERRNO 0
# define _GDBM_MAX_ERRNO GDBM_ERR_FILE_MODE
typedef int gdbm_error; /* For compatibilities sake. */
extern gdbm_error gdbm_errno;
extern const char * const gdbm_errlist[];
+extern int gdbm_last_errno (GDBM_FILE dbf);
+extern void gdbm_set_errno (GDBM_FILE dbf, gdbm_error ec, int fatal);
+extern void gdbm_clear_error (GDBM_FILE dbf);
+
/* extra prototypes */
extern const char *gdbm_strerror (gdbm_error);
extern int gdbm_version_cmp (int const a[], int const b[]);
# if defined(__cplusplus) || defined(c_plusplus)
diff --git a/src/gdbm_load.c b/src/gdbm_load.c
index 260a601..fd404b9 100644
--- a/src/gdbm_load.c
+++ b/src/gdbm_load.c
@@ -1,8 +1,8 @@
/* This file is part of GDBM, the GNU data base manager.
- Copyright (C) 2011, 2013 Free Software Foundation, Inc.
+ Copyright (C) 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
the Free Software Foundation; either version 3, or (at your option)
any later version.
@@ -50,19 +50,19 @@ set_meta_info (GDBM_FILE dbf)
int fd = gdbm_fdesc (dbf);
if (meta_mask & GDBM_META_MASK_OWNER)
{
if (fchown (fd, owner_uid, owner_gid))
{
- gdbm_errno = GDBM_ERR_FILE_OWNER;
+ gdbm_set_errno (dbf, GDBM_ERR_FILE_OWNER, 0);
return 1;
}
}
if ((meta_mask & GDBM_META_MASK_MODE) && fchmod (fd, mode))
{
- gdbm_errno = GDBM_ERR_FILE_OWNER;
+ gdbm_set_errno (dbf, GDBM_ERR_FILE_OWNER, 0);
return 1;
}
}
return 0;
}
diff --git a/src/gdbmcount.c b/src/gdbmcount.c
index 8e22213..17016b2 100644
--- a/src/gdbmcount.c
+++ b/src/gdbmcount.c
@@ -1,10 +1,11 @@
/* gdbmcount.c - get number of items in a gdbm file. */
/* This file is part of GDBM, the GNU data base manager.
- Copyright (C) 1993, 1994, 2007, 2011, 2013 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 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
the Free Software Foundation; either version 3, or (at your option)
any later version.
@@ -39,13 +40,13 @@ gdbm_count (GDBM_FILE dbf, gdbm_count_t *pcount)
gdbm_count_t count = 0;
int i, last;
sdir = malloc (dbf->header->dir_size);
if (!sdir)
{
- gdbm_errno = GDBM_MALLOC_ERROR;
+ gdbm_set_errno (dbf, GDBM_MALLOC_ERROR, 0);
return -1;
}
memcpy (sdir, dbf->dir, dbf->header->dir_size);
qsort (sdir, nbuckets, sizeof (off_t), compoff);
diff --git a/src/gdbmdefs.h b/src/gdbmdefs.h
index c62413b..e873117 100644
--- a/src/gdbmdefs.h
+++ b/src/gdbmdefs.h
@@ -156,12 +156,18 @@ struct gdbm_file_info {
/* Whether or not we're allowing mmap() use. */
unsigned memory_mapping :1;
/* Whether the database was open with GDBM_CLOEXEC flag */
unsigned cloexec :1;
+
+ /* Last error was fatal */
+ unsigned fatal :1;
+
+ /* Last error number */
+ int last_error;
/* Type of file locking in use. */
enum { LOCKING_NONE = 0, LOCKING_FLOCK, LOCKING_LOCKF,
LOCKING_FCNTL } lock_type;
/* The fatal error handling routine. */
diff --git a/src/gdbmdelete.c b/src/gdbmdelete.c
index 4396b14..7e2867d 100644
--- a/src/gdbmdelete.c
+++ b/src/gdbmdelete.c
@@ -36,18 +36,18 @@ gdbm_delete (GDBM_FILE dbf, datum key)
off_t free_adr; /* Temporary storage for address and size. */
int free_size;
/* First check to make sure this guy is a writer. */
if (dbf->read_write == GDBM_READER)
{
- gdbm_errno = GDBM_READER_CANT_DELETE;
+ gdbm_set_errno (dbf, GDBM_READER_CANT_DELETE, 0);
return -1;
}
/* Initialize the gdbm_errno variable. */
- gdbm_errno = GDBM_NO_ERROR;
+ gdbm_set_errno (dbf, GDBM_NO_ERROR, 0);
/* Find the item. */
elem_loc = _gdbm_findkey (dbf, key, NULL, NULL);
if (elem_loc == -1)
return -1;
diff --git a/src/gdbmdump.c b/src/gdbmdump.c
index 1b374f3..cf1e2fc 100644
--- a/src/gdbmdump.c
+++ b/src/gdbmdump.c
@@ -1,8 +1,8 @@
/* This file is part of GDBM, the GNU data base manager.
- Copyright (C) 2011, 2013 Free Software Foundation, Inc.
+ Copyright (C) 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
the Free Software Foundation; either version 3, or (at your option)
any later version.
@@ -96,13 +96,13 @@ _gdbm_dump_ascii (GDBM_FILE dbf, FILE *fp)
{
if ((rc = print_datum (&key, &buffer, &bufsize, fp)) ||
(rc = print_datum (&data, &buffer, &bufsize, fp)))
{
free (key.dptr);
free (data.dptr);
- gdbm_errno = rc;
+ gdbm_set_errno (dbf, rc, 0);
break;
}
}
nextkey = gdbm_nextkey (dbf, key);
free (key.dptr);
free (data.dptr);
@@ -136,17 +136,21 @@ gdbm_dump_to_file (GDBM_FILE dbf, FILE *fp, int format)
case GDBM_DUMP_FMT_ASCII:
rc = _gdbm_dump_ascii (dbf, fp);
break;
default:
+ gdbm_set_errno (NULL, GDBM_BAD_OPEN_FLAGS, 0);
return EINVAL;
}
if (rc == 0 && ferror (fp))
- rc = gdbm_errno = GDBM_FILE_WRITE_ERROR;
+ {
+ gdbm_set_errno (NULL, GDBM_FILE_WRITE_ERROR, 0);
+ rc = -1;
+ }
return rc;
}
int
gdbm_dump (GDBM_FILE dbf, const char *filename, int fmt, int open_flags,
@@ -159,34 +163,34 @@ gdbm_dump (GDBM_FILE dbf, const char *filename, int fmt, int open_flags,
switch (open_flags)
{
case GDBM_WRCREAT:
nfd = open (filename, O_WRONLY | O_CREAT | O_EXCL, mode);
if (nfd == -1)
{
- gdbm_errno = GDBM_FILE_OPEN_ERROR;
+ gdbm_set_errno (NULL, GDBM_FILE_OPEN_ERROR, 0);
return -1;
}
break;
case GDBM_NEWDB:
nfd = open (filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
if (nfd == -1)
{
- gdbm_errno = GDBM_FILE_OPEN_ERROR;
+ gdbm_set_errno (NULL, GDBM_FILE_OPEN_ERROR, 0);
return -1;
}
break;
default:
- gdbm_errno = GDBM_BAD_OPEN_FLAGS;
+ gdbm_set_errno (NULL, GDBM_BAD_OPEN_FLAGS, 0);
return -1;
}
fp = fdopen (nfd, "w");
if (!fp)
{
close (nfd);
- gdbm_errno = GDBM_FILE_OPEN_ERROR;
+ gdbm_set_errno (NULL, GDBM_FILE_OPEN_ERROR, 0);
return -1;
}
rc = gdbm_dump_to_file (dbf, fp, fmt);
fclose (fp);
return rc;
}
diff --git a/src/gdbmerrno.c b/src/gdbmerrno.c
index 3b5cf4c..2ff647f 100644
--- a/src/gdbmerrno.c
+++ b/src/gdbmerrno.c
@@ -1,10 +1,10 @@
/* gdbmerrno.c - convert gdbm errors into english. */
/* This file is part of GDBM, the GNU data base manager.
- Copyright (C) 1993, 2007, 2011, 2013 Free Software Foundation, Inc.
+ Copyright (C) 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
the Free Software Foundation; either version 3, or (at your option)
any later version.
@@ -21,12 +21,46 @@
#include "gdbmdefs.h"
/* The dbm error number is placed in the variable GDBM_ERRNO. */
gdbm_error gdbm_errno = GDBM_NO_ERROR;
+/* Store error code EC in the database structure DBF and in the
+ global variable gdbm_error.
+*/
+void
+gdbm_set_errno (GDBM_FILE dbf, gdbm_error ec, int fatal)
+{
+ if (dbf)
+ {
+ dbf->last_error = ec;
+ dbf->fatal = fatal;
+ }
+ gdbm_errno = ec;
+}
+
+/* Retrieve last error code for the database DBF. */
+int
+gdbm_last_errno (GDBM_FILE dbf)
+{
+ if (!dbf)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ return dbf->last_error;
+}
+
+/* Clear error state for the database DBF. */
+void
+gdbm_clear_error (GDBM_FILE dbf)
+{
+ if (dbf)
+ dbf->last_error = GDBM_NO_ERROR;
+}
+
/* this is not static so that applications may access the array if they
like. */
const char * const gdbm_errlist[_GDBM_MAX_ERRNO+1] = {
[GDBM_NO_ERROR] = N_("No error"),
[GDBM_MALLOC_ERROR] = N_("Malloc error"),
diff --git a/src/gdbmexists.c b/src/gdbmexists.c
index 9bbd308..0d551c0 100644
--- a/src/gdbmexists.c
+++ b/src/gdbmexists.c
@@ -1,10 +1,10 @@
/* gdbmexists.c - Check to see if a key exists */
/* This file is part of GDBM, the GNU data base manager.
- Copyright (C) 1993, 2007, 2011, 2013 Free Software Foundation, Inc.
+ Copyright (C) 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
the Free Software Foundation; either version 3, or (at your option)
any later version.
@@ -27,11 +27,11 @@
int
gdbm_exists (GDBM_FILE dbf, datum key)
{
if (_gdbm_findkey (dbf, key, NULL, NULL) < 0)
{
if (gdbm_errno == GDBM_ITEM_NOT_FOUND)
- gdbm_errno = GDBM_NO_ERROR;
+ gdbm_set_errno (dbf, GDBM_NO_ERROR, 0);
return 0;
}
return 1;
}
diff --git a/src/gdbmexp.c b/src/gdbmexp.c
index e68457f..613166e 100644
--- a/src/gdbmexp.c
+++ b/src/gdbmexp.c
@@ -78,13 +78,13 @@ gdbm_export_to_file (GDBM_FILE dbf, FILE *fp)
return -1;
return count;
write_fail:
- gdbm_errno = GDBM_FILE_WRITE_ERROR;
+ gdbm_set_errno (NULL, GDBM_FILE_WRITE_ERROR, 0);
return -1;
}
int
gdbm_export (GDBM_FILE dbf, const char *exportfile, int flags, int mode)
{
@@ -95,38 +95,38 @@ gdbm_export (GDBM_FILE dbf, const char *exportfile, int flags, int mode)
switch (flags)
{
case GDBM_WRCREAT:
nfd = open (exportfile, O_WRONLY | O_CREAT | O_EXCL, mode);
if (nfd == -1)
{
- gdbm_errno = GDBM_FILE_OPEN_ERROR;
+ gdbm_set_errno (NULL, GDBM_FILE_OPEN_ERROR, 0);
return -1;
}
break;
case GDBM_NEWDB:
nfd = open (exportfile, O_WRONLY | O_CREAT | O_TRUNC, mode);
if (nfd == -1)
{
- gdbm_errno = GDBM_FILE_OPEN_ERROR;
+ gdbm_set_errno (NULL, GDBM_FILE_OPEN_ERROR, 0);
return -1;
}
break;
default:
#ifdef GDBM_BAD_OPEN_FLAGS
- gdbm_errno = GDBM_BAD_OPEN_FLAGS;
+ gdbm_set_errno (NULL, GDBM_BAD_OPEN_FLAGS, 0);
#else
- gdbm_errno = GDBM_FILE_OPEN_ERROR;
+ gdbm_set_errno (NULL, GDBM_FILE_OPEN_ERROR, 0);
#endif
return -1;
}
fp = fdopen (nfd, "w");
if (!fp)
{
close (nfd);
- gdbm_errno = GDBM_FILE_OPEN_ERROR;
+ gdbm_set_errno (NULL, GDBM_FILE_OPEN_ERROR, 0);
return -1;
}
rc = gdbm_export_to_file (dbf, fp);
fclose (fp);
return rc;
diff --git a/src/gdbmfetch.c b/src/gdbmfetch.c
index a765c52..ca82550 100644
--- a/src/gdbmfetch.c
+++ b/src/gdbmfetch.c
@@ -35,13 +35,13 @@ gdbm_fetch (GDBM_FILE dbf, datum key)
/* Set the default return value. */
return_val.dptr = NULL;
return_val.dsize = 0;
/* Initialize the gdbm_errno variable. */
- gdbm_errno = GDBM_NO_ERROR;
+ gdbm_set_errno (dbf, GDBM_NO_ERROR, 0);
/* Find the key and return a pointer to the data. */
elem_loc = _gdbm_findkey (dbf, key, &find_data, NULL);
/* Copy the data if the key was found. */
if (elem_loc >= 0)
@@ -51,13 +51,13 @@ gdbm_fetch (GDBM_FILE dbf, datum key)
if (return_val.dsize == 0)
return_val.dptr = (char *) malloc (1);
else
return_val.dptr = (char *) malloc (return_val.dsize);
if (return_val.dptr == NULL)
{
- gdbm_errno = GDBM_MALLOC_ERROR;
+ gdbm_set_errno (dbf, GDBM_MALLOC_ERROR, 0);
return return_val;
}
memcpy (return_val.dptr, find_data, return_val.dsize);
}
return return_val;
diff --git a/src/gdbmimp.c b/src/gdbmimp.c
index 31092aa..96c774f 100644
--- a/src/gdbmimp.c
+++ b/src/gdbmimp.c
@@ -1,10 +1,10 @@
/* gdbmimp.c - Import 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
the Free Software Foundation; either version 3, or (at your option)
any later version.
@@ -41,13 +41,13 @@ gdbm_import_from_file (GDBM_FILE dbf, FILE *fp, int flag)
/* Read (and discard) four lines begining with ! and ending with \n. */
while (1)
{
if ((rret = fgetc (fp)) == -1)
{
- gdbm_errno = GDBM_FILE_READ_ERROR;
+ gdbm_set_errno (NULL, GDBM_FILE_READ_ERROR, 0);
return -1;
}
if (rret == '!')
seenbang++;
if (rret == '\n')
@@ -63,21 +63,21 @@ gdbm_import_from_file (GDBM_FILE dbf, FILE *fp, int flag)
/* Allocate buffers. */
kbufsize = 512;
kbuffer = malloc (kbufsize);
if (kbuffer == NULL)
{
- gdbm_errno = GDBM_MALLOC_ERROR;
+ gdbm_set_errno (NULL, GDBM_MALLOC_ERROR, 0);
return -1;
}
dbufsize = 512;
dbuffer = malloc (dbufsize);
if (dbuffer == NULL)
{
free (kbuffer);
- gdbm_errno = GDBM_MALLOC_ERROR;
+ gdbm_set_errno (NULL, GDBM_MALLOC_ERROR, 0);
return -1;
}
ec = GDBM_NO_ERROR;
/* Insert/replace records in the database until we run out of file. */
while ((rret = fread (&rsize, sizeof (rsize), 1, fp)) == 1)
@@ -157,26 +157,26 @@ gdbm_import_from_file (GDBM_FILE dbf, FILE *fp, int flag)
free (kbuffer);
free (dbuffer);
if (ec == GDBM_NO_ERROR)
return count;
- gdbm_errno = ec;
+ gdbm_set_errno (NULL, ec, 0);
return -1;
}
int
gdbm_import (GDBM_FILE dbf, const char *importfile, int flag)
{
FILE *fp;
int rc;
fp = fopen (importfile, "r");
if (!fp)
{
- gdbm_errno = GDBM_FILE_OPEN_ERROR;
+ gdbm_set_errno (NULL, GDBM_FILE_OPEN_ERROR, 0);
return -1;
}
rc = gdbm_import_from_file (dbf, fp, flag);
fclose (fp);
return rc;
}
diff --git a/src/gdbmload.c b/src/gdbmload.c
index 19ee0fb..5723b95 100644
--- a/src/gdbmload.c
+++ b/src/gdbmload.c
@@ -1,8 +1,8 @@
/* This file is part of GDBM, the GNU data base manager.
- Copyright (C) 2011, 2013 Free Software Foundation, Inc.
+ Copyright (C) 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
the Free Software Foundation; either version 3, or (at your option)
any later version.
@@ -370,19 +370,19 @@ _set_gdbm_meta_info (GDBM_FILE dbf, char *param, int meta_mask)
owner_uid = st.st_uid;
if (!(meta_flags & META_GID))
owner_gid = st.st_gid;
}
if (fchown (fd, owner_uid, owner_gid))
{
- gdbm_errno = GDBM_ERR_FILE_OWNER;
+ gdbm_set_errno (dbf, GDBM_ERR_FILE_OWNER, 0);
rc = 1;
}
}
if ((meta_flags & META_MODE) && fchmod (fd, mode))
{
- gdbm_errno = GDBM_ERR_FILE_OWNER;
+ gdbm_set_errno (dbf, GDBM_ERR_FILE_OWNER, 0);
rc = 1;
}
}
return rc;
}
@@ -578,13 +578,13 @@ gdbm_load_from_file (GDBM_FILE *pdbf, FILE *fp, int replace,
if (rc == '!')
{
if (line)
*line = 0;
if (!*pdbf)
{
- gdbm_errno = GDBM_NO_DBNAME;
+ gdbm_set_errno (NULL, GDBM_NO_DBNAME, 0);
return -1;
}
if (gdbm_import_from_file (*pdbf, fp, replace) == -1)
return -1;
return 0;
}
@@ -593,25 +593,25 @@ gdbm_load_from_file (GDBM_FILE *pdbf, FILE *fp, int replace,
df.fp = fp;
if (rc == 'V')
{
if (!*pdbf)
{
- gdbm_errno = GDBM_NO_DBNAME;
+ gdbm_set_errno (NULL, GDBM_NO_DBNAME, 0);
return -1;
}
rc = gdbm_load_bdb_dump (&df, *pdbf, replace);
}
else
rc = _gdbm_load_file (&df, *pdbf, pdbf, replace, meta_mask);
dump_file_free (&df);
if (rc)
{
if (line)
*line = df.line;
- gdbm_errno = rc;
+ gdbm_set_errno (NULL, rc, 0);
return -1;
}
return 0;
}
int
@@ -622,13 +622,13 @@ gdbm_load (GDBM_FILE *pdbf, const char *filename, int replace,
FILE *fp;
int rc;
fp = fopen (filename, "r");
if (!fp)
{
- gdbm_errno = GDBM_FILE_OPEN_ERROR;
+ gdbm_set_errno (NULL, GDBM_FILE_OPEN_ERROR, 0);
return -1;
}
rc = gdbm_load_from_file (pdbf, fp, replace, meta_mask, line);
fclose (fp);
return rc;
}
diff --git a/src/gdbmopen.c b/src/gdbmopen.c
index 14c687d..b8b14e3 100644
--- a/src/gdbmopen.c
+++ b/src/gdbmopen.c
@@ -1,11 +1,11 @@
/* gdbmopen.c - Open the dbm file and initialize data structures for use. */
/* 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
the Free Software Foundation; either version 3, or (at your option)
any later version.
@@ -64,19 +64,19 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
char need_trunc; /* Used with GDBM_NEWDB and locking to avoid
truncating a file from under a reader. */
int rc; /* temporary error code */
int fbits = 0; /* additional bits for open(2) flags */
/* Initialize the gdbm_errno variable. */
- gdbm_errno = GDBM_NO_ERROR;
+ gdbm_set_errno (NULL, GDBM_NO_ERROR, 0);
/* Allocate new info structure. */
dbf = (GDBM_FILE) malloc (sizeof (*dbf));
if (dbf == NULL)
{
- gdbm_errno = GDBM_MALLOC_ERROR;
+ gdbm_set_errno (NULL, GDBM_MALLOC_ERROR, 0);
return NULL;
}
/* Initialize some fields for known values. This is done so gdbm_close
will work if called before allocating some structures. */
dbf->dir = NULL;
@@ -95,13 +95,13 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
/* Save name of file. */
len = strlen (file);
dbf->name = (char *) malloc (len + 1);
if (dbf->name == NULL)
{
free (dbf);
- gdbm_errno = GDBM_MALLOC_ERROR;
+ gdbm_set_errno (NULL, GDBM_MALLOC_ERROR, 0);
return NULL;
}
strcpy (dbf->name, file);
/* Initialize the fatal error routine. */
dbf->fatal_err = fatal_func;
@@ -152,33 +152,33 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
}
if (dbf->desc < 0)
{
SAVE_ERRNO (free (dbf->name);
free (dbf));
- gdbm_errno = GDBM_FILE_OPEN_ERROR;
+ gdbm_set_errno (NULL, GDBM_FILE_OPEN_ERROR, 0);
return NULL;
}
/* Get the status of the file. */
if (fstat (dbf->desc, &file_stat))
{
SAVE_ERRNO (close (dbf->desc);
free (dbf->name);
free (dbf));
- gdbm_errno = GDBM_FILE_STAT_ERROR;
+ gdbm_set_errno (NULL, GDBM_FILE_STAT_ERROR, 0);
return NULL;
}
/* Zero-length file can't be a reader... */
if (((flags & GDBM_OPENMASK) == GDBM_READER) && (file_stat.st_size == 0))
{
close (dbf->desc);
free (dbf->name);
free (dbf);
- gdbm_errno = GDBM_EMPTY_DATABASE;
+ gdbm_set_errno (NULL, GDBM_EMPTY_DATABASE, 0);
return NULL;
}
/* Record the kind of user. */
dbf->read_write = (flags & GDBM_OPENMASK);
@@ -187,16 +187,15 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
{
if (_gdbm_lock_file (dbf) == -1)
{
close (dbf->desc);
free (dbf->name);
free (dbf);
- if ((flags & GDBM_OPENMASK) == GDBM_READER)
- gdbm_errno = GDBM_CANT_BE_READER;
- else
- gdbm_errno = GDBM_CANT_BE_WRITER;
+ gdbm_set_errno (NULL,
+ (flags & GDBM_OPENMASK) == GDBM_READER
+ ? GDBM_CANT_BE_READER : GDBM_CANT_BE_WRITER, 0);
return NULL;
}
}
/* If we do have a write lock and it was a GDBM_NEWDB, it is
now time to truncate the file. */
@@ -221,13 +220,13 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
/* Get space for the file header. It will be written to disk, so
make sure there's no garbage in it. */
dbf->header = (gdbm_file_header *) calloc (1, file_block_size);
if (dbf->header == NULL)
{
gdbm_close (dbf);
- gdbm_errno = GDBM_MALLOC_ERROR;
+ gdbm_set_errno (NULL, GDBM_MALLOC_ERROR, 0);
return NULL;
}
/* Set the magic number and the block_size. */
dbf->header->header_magic = GDBM_MAGIC;
dbf->header->block_size = file_block_size;
@@ -242,22 +241,22 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
}
/* Check for correct block_size. */
if (dbf->header->dir_size != dbf->header->block_size)
{
gdbm_close (dbf);
- gdbm_errno = GDBM_BLOCK_SIZE_ERROR;
+ gdbm_set_errno (NULL, GDBM_BLOCK_SIZE_ERROR, 0);
return NULL;
}
/* Allocate the space for the directory. */
dbf->dir = (off_t *) malloc (dbf->header->dir_size);
if (dbf->dir == NULL)
{
gdbm_close (dbf);
- gdbm_errno = GDBM_MALLOC_ERROR;
+ gdbm_set_errno (NULL, GDBM_MALLOC_ERROR, 0);
return NULL;
}
dbf->header->dir = dbf->header->block_size;
/* Create the first and only hash bucket. */
dbf->header->bucket_elems =
@@ -265,13 +264,13 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
/ sizeof (bucket_element) + 1;
dbf->header->bucket_size = dbf->header->block_size;
dbf->bucket = (hash_bucket *) malloc (dbf->header->bucket_size);
if (dbf->bucket == NULL)
{
gdbm_close (dbf);
- gdbm_errno = GDBM_MALLOC_ERROR;
+ gdbm_set_errno (NULL, GDBM_MALLOC_ERROR, 0);
return NULL;
}
_gdbm_new_bucket (dbf, dbf->bucket, 0);
dbf->bucket->av_count = 1;
dbf->bucket->bucket_avail[0].av_adr = 3*dbf->header->block_size;
dbf->bucket->bucket_avail[0].av_size = dbf->header->block_size;
@@ -291,31 +290,31 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
/* Write initial configuration to the file. */
/* Block 0 is the file header and active avail block. */
rc = _gdbm_full_write (dbf, dbf->header, dbf->header->block_size);
if (rc)
{
SAVE_ERRNO (gdbm_close (dbf));
- gdbm_errno = rc;
+ gdbm_set_errno (NULL, rc, 0);
return NULL;
}
/* Block 1 is the initial bucket directory. */
rc = _gdbm_full_write (dbf, dbf->dir, dbf->header->dir_size);
if (rc)
{
SAVE_ERRNO (gdbm_close (dbf));
- gdbm_errno = rc;
+ gdbm_set_errno (NULL, rc, 0);
return NULL;
}
/* Block 2 is the only bucket. */
rc = _gdbm_full_write (dbf, dbf->bucket, dbf->header->bucket_size);
if (rc)
{
SAVE_ERRNO (gdbm_close (dbf));
- gdbm_errno = rc;
+ gdbm_set_errno (NULL, rc, 0);
return NULL;
}
/* Wait for initial configuration to be written to disk. */
__fsync (dbf);
@@ -330,13 +329,13 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
/* Read the partial file header. */
rc = _gdbm_full_read (dbf, &partial_header, sizeof (gdbm_file_header));
if (rc)
{
SAVE_ERRNO (gdbm_close (dbf));
- gdbm_errno = rc;
+ gdbm_set_errno (NULL, rc, 0);
return NULL;
}
/* Is the magic number good? */
if (partial_header.header_magic != GDBM_MAGIC
&& partial_header.header_magic != GDBM_OMAGIC)
@@ -344,65 +343,65 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
gdbm_close (dbf);
switch (partial_header.header_magic)
{
case GDBM_OMAGIC_SWAP:
case GDBM_MAGIC32_SWAP:
case GDBM_MAGIC64_SWAP:
- gdbm_errno = GDBM_BYTE_SWAPPED;
+ gdbm_set_errno (NULL, GDBM_BYTE_SWAPPED, 0);
break;
case GDBM_MAGIC32:
case GDBM_MAGIC64:
- gdbm_errno = GDBM_BAD_FILE_OFFSET;
+ gdbm_set_errno (NULL, GDBM_BAD_FILE_OFFSET, 0);
break;
default:
- gdbm_errno = GDBM_BAD_MAGIC_NUMBER;
+ gdbm_set_errno (NULL, GDBM_BAD_MAGIC_NUMBER, 0);
}
return NULL;
}
/* It is a good database, read the entire header. */
dbf->header = (gdbm_file_header *) malloc (partial_header.block_size);
if (dbf->header == NULL)
{
gdbm_close (dbf);
- gdbm_errno = GDBM_MALLOC_ERROR;
+ gdbm_set_errno (NULL, GDBM_MALLOC_ERROR, 0);
return NULL;
}
memcpy (dbf->header, &partial_header, sizeof (gdbm_file_header));
rc = _gdbm_full_read (dbf, &dbf->header->avail.av_table[1],
dbf->header->block_size-sizeof (gdbm_file_header));
if (rc)
{
SAVE_ERRNO (gdbm_close (dbf));
- gdbm_errno = rc;
+ gdbm_set_errno (NULL, rc, 0);
return NULL;
}
/* Allocate space for the hash table directory. */
dbf->dir = (off_t *) malloc (dbf->header->dir_size);
if (dbf->dir == NULL)
{
gdbm_close (dbf);
- gdbm_errno = GDBM_MALLOC_ERROR;
+ gdbm_set_errno (NULL, GDBM_MALLOC_ERROR, 0);
return NULL;
}
/* Read the hash table directory. */
file_pos = __lseek (dbf, dbf->header->dir, SEEK_SET);
if (file_pos != dbf->header->dir)
{