diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-07-09 08:40:04 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-07-09 08:47:16 +0300 |
commit | 479a469033903a76b9c073806037dd66176f3da0 (patch) | |
tree | 2841b611288f9343868e6ded82909b096a62e121 /src | |
parent | 2efd8358711ab3ea6c0ecaab75d195837b4b3e37 (diff) | |
download | gdbm-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.c | 8 | ||||
-rw-r--r-- | src/findkey.c | 2 | ||||
-rw-r--r-- | src/gdbm.h.in | 4 | ||||
-rw-r--r-- | src/gdbm_load.c | 6 | ||||
-rw-r--r-- | src/gdbmcount.c | 5 | ||||
-rw-r--r-- | src/gdbmdefs.h | 6 | ||||
-rw-r--r-- | src/gdbmdelete.c | 4 | ||||
-rw-r--r-- | src/gdbmdump.c | 18 | ||||
-rw-r--r-- | src/gdbmerrno.c | 36 | ||||
-rw-r--r-- | src/gdbmexists.c | 4 | ||||
-rw-r--r-- | src/gdbmexp.c | 12 | ||||
-rw-r--r-- | src/gdbmfetch.c | 4 | ||||
-rw-r--r-- | src/gdbmimp.c | 12 | ||||
-rw-r--r-- | src/gdbmload.c | 14 | ||||
-rw-r--r-- | src/gdbmopen.c | 65 | ||||
-rw-r--r-- | src/gdbmreorg.c | 20 | ||||
-rw-r--r-- | src/gdbmseq.c | 10 | ||||
-rw-r--r-- | src/gdbmsetopt.c | 79 | ||||
-rw-r--r-- | src/gdbmstore.c | 12 | ||||
-rw-r--r-- | src/gdbmsync.c | 6 | ||||
-rw-r--r-- | src/mmap.c | 8 |
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) { |