aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-08-31 11:26:31 +0300
committerSergey Poznyakoff <gray@gnu.org>2018-08-31 11:26:31 +0300
commit2ff4ae9c745d4b9e6ee36468c81554027f66c35b (patch)
tree4a6012ba90fc9c4fc9da8bade6fb943efc38d1a0 /src
parent778cc81d55aecd6344d577919cec73e4e6980e2e (diff)
downloadgdbm-2ff4ae9c745d4b9e6ee36468c81554027f66c35b.tar.gz
gdbm-2ff4ae9c745d4b9e6ee36468c81554027f66c35b.tar.bz2
Various bugfixes.
* compat/dbmopen.c (ndbm_open_dir_file0): Ignore ENOENT. * src/falloc.c (push_avail_block): Free temporary storage no matter what return status. * src/gdbm.h.in (GDBM_FILE_TRUNCATE_ERROR): New error code. * src/gdbmdump.c (_gdbm_dump_ascii): Initialize rc. * src/gdbmerrno.c: Handle new error.code * src/gdbmload.c (gdbm_load_bdb_dump): Initialize rc * src/gdbmopen.c (_gdbm_ftruncate): New function. (gdbm_fd_open): Use _gdbm_ftruncate. Check its return. * src/gdbmseq.c (gdbm_firstkey): Initialize dsize * src/gdbmtool.c (command_generator): Check if cmd is NULL. (shouldn't happen, but anyways). * src/mmap.c (_gdbm_mapped_lseek): Check for vailidity of the 'whence' parameter. * src/systems.h (TRUNCATE): Remove macro. * src/util.c (vgetyn): Remove unnecessary assignment.
Diffstat (limited to 'src')
-rw-r--r--src/falloc.c54
-rw-r--r--src/gdbm.h.in3
-rw-r--r--src/gdbmdump.c2
-rw-r--r--src/gdbmerrno.c6
-rw-r--r--src/gdbmload.c1
-rw-r--r--src/gdbmopen.c29
-rw-r--r--src/gdbmseq.c1
-rw-r--r--src/gdbmtool.c2
-rw-r--r--src/mmap.c4
-rw-r--r--src/systems.h7
-rw-r--r--src/util.c5
11 files changed, 75 insertions, 39 deletions
diff --git a/src/falloc.c b/src/falloc.c
index 09b40d4..7a94afb 100644
--- a/src/falloc.c
+++ b/src/falloc.c
@@ -310,39 +310,49 @@ push_avail_block (GDBM_FILE dbf)
310 dbf->header->avail.av_table[index>>1] 310 dbf->header->avail.av_table[index>>1]
311 = dbf->header->avail.av_table[index]; 311 = dbf->header->avail.av_table[index];
312 312
313 /* Update the header avail count to previous size divided by 2. */ 313 /* Update the header avail count to previous size divided by 2. */
314 dbf->header->avail.count >>= 1; 314 dbf->header->avail.count >>= 1;
315 315
316 /* Free the unneeded space. */ 316 rc = 0;
317 new_loc.av_adr += av_size; 317 do
318 new_loc.av_size -= av_size;
319 _gdbm_free (dbf, new_loc.av_adr, new_loc.av_size);
320
321 /* Update the disk. */
322 file_pos = gdbm_file_seek (dbf, av_adr, SEEK_SET);
323 if (file_pos != av_adr)
324 { 318 {
325 GDBM_SET_ERRNO (dbf, GDBM_FILE_SEEK_ERROR, TRUE); 319 /* Free the unneeded space. */
326 _gdbm_fatal (dbf, _("lseek error")); 320 new_loc.av_adr += av_size;
327 return -1; 321 new_loc.av_size -= av_size;
328 } 322 if (_gdbm_free (dbf, new_loc.av_adr, new_loc.av_size))
323 {
324 rc = -1;
325 break;
326 }
327
328 /* Update the disk. */
329 file_pos = gdbm_file_seek (dbf, av_adr, SEEK_SET);
330 if (file_pos != av_adr)
331 {
332 GDBM_SET_ERRNO (dbf, GDBM_FILE_SEEK_ERROR, TRUE);
333 _gdbm_fatal (dbf, _("lseek error"));
334 rc = -1;
335 break;
336 }
329 337
330 rc = _gdbm_full_write (dbf, temp, av_size); 338 rc = _gdbm_full_write (dbf, temp, av_size);
331 if (rc) 339 if (rc)
332 { 340 {
333 GDBM_DEBUG (GDBM_DEBUG_STORE|GDBM_DEBUG_ERR, 341 GDBM_DEBUG (GDBM_DEBUG_STORE|GDBM_DEBUG_ERR,
334 "%s: error writing avail data: %s", 342 "%s: error writing avail data: %s",
335 dbf->name, gdbm_db_strerror (dbf)); 343 dbf->name, gdbm_db_strerror (dbf));
336 _gdbm_fatal (dbf, gdbm_db_strerror (dbf)); 344 _gdbm_fatal (dbf, gdbm_db_strerror (dbf));
337 return -1; 345 rc = -1;
346 }
338 } 347 }
339 348 while (0);
349
340 free (temp); 350 free (temp);
341 351
342 return 0; 352 return rc;
343} 353}
344 354
345/* AV_TABLE contains COUNT entries sorted by AV_SIZE in ascending order. 355/* AV_TABLE contains COUNT entries sorted by AV_SIZE in ascending order.
346 Avail_lookup returns index of an item whose AV_SIZE member is greater 356 Avail_lookup returns index of an item whose AV_SIZE member is greater
347 than or equal to SIZE. */ 357 than or equal to SIZE. */
348static int 358static int
diff --git a/src/gdbm.h.in b/src/gdbm.h.in
index 6318ad8..f5eadc5 100644
--- a/src/gdbm.h.in
+++ b/src/gdbm.h.in
@@ -224,15 +224,16 @@ extern int gdbm_copy_meta (GDBM_FILE dst, GDBM_FILE src);
224# define GDBM_BAD_HEADER 33 224# define GDBM_BAD_HEADER 33
225# define GDBM_BAD_AVAIL 34 225# define GDBM_BAD_AVAIL 34
226# define GDBM_BAD_HASH_TABLE 35 226# define GDBM_BAD_HASH_TABLE 35
227# define GDBM_BAD_DIR_ENTRY 36 227# define GDBM_BAD_DIR_ENTRY 36
228# define GDBM_FILE_CLOSE_ERROR 37 228# define GDBM_FILE_CLOSE_ERROR 37
229# define GDBM_FILE_SYNC_ERROR 38 229# define GDBM_FILE_SYNC_ERROR 38
230# define GDBM_FILE_TRUNCATE_ERROR 39
230 231
231# define _GDBM_MIN_ERRNO 0 232# define _GDBM_MIN_ERRNO 0
232# define _GDBM_MAX_ERRNO GDBM_FILE_SYNC_ERROR 233# define _GDBM_MAX_ERRNO GDBM_FILE_TRUNCATE_ERROR
233 234
234/* This one was never used and will be removed in the future */ 235/* This one was never used and will be removed in the future */
235# define GDBM_UNKNOWN_UPDATE GDBM_UNKNOWN_ERROR 236# define GDBM_UNKNOWN_UPDATE GDBM_UNKNOWN_ERROR
236 237
237typedef int gdbm_error; 238typedef int gdbm_error;
238extern int *gdbm_errno_location (void); 239extern int *gdbm_errno_location (void);
diff --git a/src/gdbmdump.c b/src/gdbmdump.c
index 2e6f5b0..a8c4ec5 100644
--- a/src/gdbmdump.c
+++ b/src/gdbmdump.c
@@ -59,13 +59,13 @@ _gdbm_dump_ascii (GDBM_FILE dbf, FILE *fp)
59 struct passwd *pw; 59 struct passwd *pw;
60 struct group *gr; 60 struct group *gr;
61 datum key; 61 datum key;
62 size_t count = 0; 62 size_t count = 0;
63 unsigned char *buffer = NULL; 63 unsigned char *buffer = NULL;
64 size_t bufsize = 0; 64 size_t bufsize = 0;
65 int rc; 65 int rc = 0;
66 66
67 fd = gdbm_fdesc (dbf); 67 fd = gdbm_fdesc (dbf);
68 if (fstat (fd, &st)) 68 if (fstat (fd, &st))
69 return GDBM_FILE_STAT_ERROR; 69 return GDBM_FILE_STAT_ERROR;
70 70
71 /* Print header */ 71 /* Print header */
diff --git a/src/gdbmerrno.c b/src/gdbmerrno.c
index 4ce7f9d..6758272 100644
--- a/src/gdbmerrno.c
+++ b/src/gdbmerrno.c
@@ -135,13 +135,14 @@ const char * const gdbm_errlist[_GDBM_MAX_ERRNO+1] = {
135 [GDBM_BAD_BUCKET] = N_("Malformed bucket header"), 135 [GDBM_BAD_BUCKET] = N_("Malformed bucket header"),
136 [GDBM_BAD_HEADER] = N_("Malformed database file header"), 136 [GDBM_BAD_HEADER] = N_("Malformed database file header"),
137 [GDBM_BAD_AVAIL] = N_("Malformed avail_block"), 137 [GDBM_BAD_AVAIL] = N_("Malformed avail_block"),
138 [GDBM_BAD_HASH_TABLE] = N_("Malformed hash table"), 138 [GDBM_BAD_HASH_TABLE] = N_("Malformed hash table"),
139 [GDBM_BAD_DIR_ENTRY] = N_("Invalid directory entry"), 139 [GDBM_BAD_DIR_ENTRY] = N_("Invalid directory entry"),
140 [GDBM_FILE_CLOSE_ERROR] = N_("Error closing file"), 140 [GDBM_FILE_CLOSE_ERROR] = N_("Error closing file"),
141 [GDBM_FILE_SYNC_ERROR] = N_("Error synchronizing file") 141 [GDBM_FILE_SYNC_ERROR] = N_("Error synchronizing file"),
142 [GDBM_FILE_TRUNCATE_ERROR] = N_("Error truncating file")
142}; 143};
143 144
144const char * 145const char *
145gdbm_strerror (gdbm_error error) 146gdbm_strerror (gdbm_error error)
146{ 147{
147 if (error < _GDBM_MIN_ERRNO || error > _GDBM_MAX_ERRNO) 148 if (error < _GDBM_MIN_ERRNO || error > _GDBM_MAX_ERRNO)
@@ -179,13 +180,14 @@ int const gdbm_syserr[_GDBM_MAX_ERRNO+1] = {
179 [GDBM_FILE_WRITE_ERROR] = 1, 180 [GDBM_FILE_WRITE_ERROR] = 1,
180 [GDBM_FILE_SEEK_ERROR] = 1, 181 [GDBM_FILE_SEEK_ERROR] = 1,
181 [GDBM_FILE_READ_ERROR] = 1, 182 [GDBM_FILE_READ_ERROR] = 1,
182 [GDBM_FILE_STAT_ERROR] = 1, 183 [GDBM_FILE_STAT_ERROR] = 1,
183 [GDBM_BACKUP_FAILED] = 1, 184 [GDBM_BACKUP_FAILED] = 1,
184 [GDBM_FILE_CLOSE_ERROR] = 1, 185 [GDBM_FILE_CLOSE_ERROR] = 1,
185 [GDBM_FILE_SYNC_ERROR] = 1 186 [GDBM_FILE_SYNC_ERROR] = 1,
187 [GDBM_FILE_TRUNCATE_ERROR] = 1
186}; 188};
187 189
188/* Returns true if system errno value is meaningful for GDBM error 190/* Returns true if system errno value is meaningful for GDBM error
189 code N. */ 191 code N. */
190int 192int
191gdbm_check_syserr (gdbm_error n) 193gdbm_check_syserr (gdbm_error n)
diff --git a/src/gdbmload.c b/src/gdbmload.c
index 008bcb9..f5b7869 100644
--- a/src/gdbmload.c
+++ b/src/gdbmload.c
@@ -539,12 +539,13 @@ gdbm_load_bdb_dump (struct dump_file *file, GDBM_FILE dbf, int replace)
539 539
540 if (read_bdb_header (file)) 540 if (read_bdb_header (file))
541 return -1; 541 return -1;
542 memset (&xd, 0, sizeof (xd)); 542 memset (&xd, 0, sizeof (xd));
543 xs[0] = xs[1] = 0; 543 xs[0] = xs[1] = 0;
544 i = 0; 544 i = 0;
545 rc = 0;
545 while ((c = fgetc (file->fp)) == ' ') 546 while ((c = fgetc (file->fp)) == ' ')
546 { 547 {
547 rc = xdatum_read (file->fp, &xd[i], &xs[i]); 548 rc = xdatum_read (file->fp, &xd[i], &xs[i]);
548 if (rc) 549 if (rc)
549 break; 550 break;
550 ++file->line; 551 ++file->line;
diff --git a/src/gdbmopen.c b/src/gdbmopen.c
index 908887c..7ec57e7 100644
--- a/src/gdbmopen.c
+++ b/src/gdbmopen.c
@@ -196,12 +196,27 @@ validate_header (gdbm_file_header const *hdr, struct stat const *st)
196 != hdr->avail.size) 196 != hdr->avail.size)
197 return GDBM_BAD_HEADER; 197 return GDBM_BAD_HEADER;
198 198
199 return 0; 199 return 0;
200} 200}
201 201
202/* Do we have ftruncate? */
203static inline int
204_gdbm_ftruncate (GDBM_FILE dbf)
205{
206#if HAVE_FTRUNCATE
207 return ftruncate (dbf->desc, 0);
208#else
209 int fd;
210 fd = open (dbf->name, O_RDWR|O_TRUNC, mode);
211 if (fd == -1)
212 return -1;
213 return close (fd);
214#endif
215}
216
202GDBM_FILE 217GDBM_FILE
203gdbm_fd_open (int fd, const char *file_name, int block_size, 218gdbm_fd_open (int fd, const char *file_name, int block_size,
204 int flags, void (*fatal_func) (const char *)) 219 int flags, void (*fatal_func) (const char *))
205{ 220{
206 GDBM_FILE dbf; /* The record to return. */