aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2017-12-21 09:19:41 +0200
committerSergey Poznyakoff <gray@gnu.org>2017-12-21 09:26:54 +0200
commit2e8a5e0be7b2db179018c10248a6cc64f9db3314 (patch)
tree6c36d26a1b6c6e668628683978baa2acea3ad3ba /src
parentc175231e2781abd17eabf412cfb597654a076c7b (diff)
downloadgdbm-2e8a5e0be7b2db179018c10248a6cc64f9db3314.tar.gz
gdbm-2e8a5e0be7b2db179018c10248a6cc64f9db3314.tar.bz2
Improve database reproducibility
* src/gdbmopen.c (gdbm_fd_open): Fill allocated memory with 0's where necessary. Check return value from fstat. * src/mmap.c (_gdbm_file_size): Set errno here, instead of delegating that to the caller. (_gdbm_file_extend): New function. (_gdbm_mapped_remap): Call _gdbm_file_extend instead of leaving the newly allocated space filled with garbage. * src/gdbmload.c (_set_gdbm_meta_info): Additional error checking. * NEWS: Update.
Diffstat (limited to 'src')
-rw-r--r--src/gdbmload.c13
-rw-r--r--src/gdbmopen.c20
-rw-r--r--src/mmap.c59
3 files changed, 71 insertions, 21 deletions
diff --git a/src/gdbmload.c b/src/gdbmload.c
index f634987..b243d08 100644
--- a/src/gdbmload.c
+++ b/src/gdbmload.c
@@ -297,3 +297,2 @@ _set_gdbm_meta_info (GDBM_FILE dbf, char *param, int meta_mask)
char *end;
- int rc = 0;
@@ -368,3 +367,7 @@ _set_gdbm_meta_info (GDBM_FILE dbf, char *param, int meta_mask)
struct stat st;
- fstat (fd, &st);
+ if (fstat (fd, &st))
+ {
+ GDBM_SET_ERRNO (dbf, GDBM_FILE_STAT_ERROR, FALSE);
+ return 1;
+ }
if (!(meta_flags & META_UID))
@@ -377,3 +380,3 @@ _set_gdbm_meta_info (GDBM_FILE dbf, char *param, int meta_mask)
GDBM_SET_ERRNO (dbf, GDBM_ERR_FILE_OWNER, FALSE);
- rc = 1;
+ return 1;
}
@@ -383,6 +386,6 @@ _set_gdbm_meta_info (GDBM_FILE dbf, char *param, int meta_mask)
GDBM_SET_ERRNO (dbf, GDBM_ERR_FILE_OWNER, FALSE);
- rc = 1;
+ return 1;
}
}
- return rc;
+ return 0;
}
diff --git a/src/gdbmopen.c b/src/gdbmopen.c
index 80474a6..cb73669 100644
--- a/src/gdbmopen.c
+++ b/src/gdbmopen.c
@@ -73,3 +73,3 @@ gdbm_fd_open (int fd, const char *file_name, int block_size,
/* Allocate new info structure. */
- dbf = (GDBM_FILE) malloc (sizeof (*dbf));
+ dbf = calloc (1, sizeof (*dbf));
if (dbf == NULL)
@@ -173,3 +173,11 @@ gdbm_fd_open (int fd, const char *file_name, int block_size,
TRUNCATE (dbf);
- fstat (dbf->desc, &file_stat);
+ if (fstat (dbf->desc, &file_stat))
+ {
+ if (flags & GDBM_CLOERROR)
+ close (dbf->desc);
+ free (dbf->name);
+ free (dbf);
+ GDBM_SET_ERRNO2 (NULL, GDBM_FILE_STAT_ERROR, FALSE, GDBM_DEBUG_OPEN);
+ return NULL;
+ }
}
@@ -210,3 +218,3 @@ gdbm_fd_open (int fd, const char *file_name, int block_size,
make sure there's no garbage in it. */
- dbf->header = (gdbm_file_header *) calloc (1, block_size);
+ dbf->header = calloc (1, block_size);
if (dbf->header == NULL)
@@ -243,3 +251,3 @@ gdbm_fd_open (int fd, const char *file_name, int block_size,
dbf->header->bucket_size = dbf->header->block_size;
- dbf->bucket = (hash_bucket *) malloc (dbf->header->bucket_size);
+ dbf->bucket = calloc (1, dbf->header->bucket_size);
if (dbf->bucket == NULL)
@@ -358,3 +366,3 @@ gdbm_fd_open (int fd, const char *file_name, int block_size,
/* It is a good database, read the entire header. */
- dbf->header = (gdbm_file_header *) malloc (partial_header.block_size);
+ dbf->header = malloc (partial_header.block_size);
if (dbf->header == NULL)
@@ -381,3 +389,3 @@ gdbm_fd_open (int fd, const char *file_name, int block_size,
/* Allocate space for the hash table directory. */
- dbf->dir = (off_t *) malloc (dbf->header->dir_size);
+ dbf->dir = malloc (dbf->header->dir_size);
if (dbf->dir == NULL)
diff --git a/src/mmap.c b/src/mmap.c
index 27f0e75..69bb58b 100644
--- a/src/mmap.c
+++ b/src/mmap.c
@@ -56,3 +56,6 @@ _gdbm_file_size (GDBM_FILE dbf, off_t *psize)
if (fstat (dbf->desc, &sb))
- return -1;
+ {
+ GDBM_SET_ERRNO (dbf, GDBM_FILE_STAT_ERROR, FALSE);
+ return -1;
+ }
*psize = sb.st_size;
@@ -114,2 +117,44 @@ _gdbm_internal_remap (GDBM_FILE dbf, size_t size)
+/* Grow the disk file of DBF to the SIZE bytes in length. Fill the
+ newly allocated space with zeros. */
+static int
+_gdbm_file_extend (GDBM_FILE dbf, off_t size)
+{
+ size_t page_size = sysconf (_SC_PAGESIZE);
+ char *buf;
+ off_t file_end;
+
+ file_end = lseek (dbf->desc, 0, SEEK_END);
+ if (!file_end)
+ {
+ GDBM_SET_ERRNO (dbf, GDBM_FILE_SEEK_ERROR, FALSE);
+ return -1;
+ }
+ size -= file_end;
+
+ if (size < page_size)
+ page_size = size;
+ buf = calloc (1, page_size);
+ if (!buf)
+ {
+ GDBM_SET_ERRNO (dbf, GDBM_MALLOC_ERROR, FALSE);
+ return -1;
+ }
+
+ while (size)
+ {
+ ssize_t n = write (dbf->desc, buf, size < page_size ? size : page_size);
+ if (n <= 0)
+ {
+ GDBM_SET_ERRNO (dbf, GDBM_FILE_WRITE_ERROR, FALSE);
+ break;
+ }
+ size -= n;
+ }
+ free (buf);
+ if (size)
+ return -1;
+ return 0;
+}
+
# define _REMAP_DEFAULT 0
@@ -142,3 +187,2 @@ _gdbm_mapped_remap (GDBM_FILE dbf, off_t size, int flag)
SAVE_ERRNO (_gdbm_mapped_unmap (dbf));
- GDBM_SET_ERRNO (dbf, GDBM_FILE_STAT_ERROR, FALSE);
return -1;
@@ -155,8 +199,6 @@ _gdbm_mapped_remap (GDBM_FILE dbf, off_t size, int flag)
{
- char c = 0;
-
if (size < dbf->header->next_block)
size = dbf->header->next_block;
- lseek (dbf->desc, size - 1, SEEK_SET);
- write (dbf->desc, &c, 1);
+ if (_gdbm_file_extend (dbf, size))
+ return -1;
file_size = size;
@@ -336,6 +378,3 @@ _gdbm_mapped_lseek (GDBM_FILE dbf, off_t offset, int whence)
if (_gdbm_file_size (dbf, &file_size))
- {
- GDBM_SET_ERRNO (dbf, GDBM_FILE_STAT_ERROR, FALSE);
- return -1;
- }
+ return -1;
needle = file_size - offset;

Return to:

Send suggestions and report system problems to the System administrator.