aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-08-17 18:20:48 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2011-08-17 18:20:48 +0000
commit9fd45622e2cda584e13bf1d3f08960d4fead3c0d (patch)
tree31ce33c0642a9fde9c9c47514bbdf2022eded831
parente22604d840c4db32fed14e59f56c5e4f419692d8 (diff)
downloadgdbm-9fd45622e2cda584e13bf1d3f08960d4fead3c0d.tar.gz
gdbm-9fd45622e2cda584e13bf1d3f08960d4fead3c0d.tar.bz2
Make sure errno is preserved, if it can contain details about the gdbm error.
* src/gdbmdefs.h (SAVE_ERRNO): New macro. * src/gdbmopen.c: Use SAVE_ERRNO where it is important to preserve system errno. * src/mmap.c: Likewise. * doc/gdbm.texinfo: Document which gdbm errors can be detailed by inspecting the system errno.
-rw-r--r--ChangeLog13
-rw-r--r--doc/gdbm.texinfo15
-rw-r--r--src/gdbmdefs.h10
-rw-r--r--src/gdbmopen.c26
-rw-r--r--src/mmap.c6
5 files changed, 51 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 460ab4f..d3bd1d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
2011-08-17 Sergey Poznyakoff <gray@gnu.org.ua>
+ Make sure errno is preserved, if it can contain details about the
+ gdbm error.
+
+ * src/gdbmdefs.h (SAVE_ERRNO): New macro.
+ * src/gdbmopen.c: Use SAVE_ERRNO where it is important to
+ preserve system errno.
+ * src/mmap.c: Likewise.
+
+ * doc/gdbm.texinfo: Document which gdbm errors can
+ be detailed by inspecting the system errno.
+
+2011-08-17 Sergey Poznyakoff <gray@gnu.org.ua>
+
Introduce new error code.
* configure.ac, NEWS: Raise patchlevel to 90.
diff --git a/doc/gdbm.texinfo b/doc/gdbm.texinfo
index 98e3bc3..8487de2 100644
--- a/doc/gdbm.texinfo
+++ b/doc/gdbm.texinfo
@@ -1350,23 +1350,35 @@ The library was not able to open a disk file. This can be set by
@code{gdbm_open} (@pxref{Open}), @code{gdbm_export} and
@code{gdbm_import} functions (@pxref{Flat files}).
+Inspect the value of the system @code{errno} variable to get more
+detailed diagnostics.
+
@kwindex GDBM_FILE_WRITE_ERROR
@item GDBM_FILE_WRITE_ERROR
Writing to a disk file failed. This can be set by
@code{gdbm_open} (@pxref{Open}), @code{gdbm_export} and
@code{gdbm_import} functions.
+Inspect the value of the system @code{errno} variable to get more
+detailed diagnostics.
+
@kwindex GDBM_FILE_SEEK_ERROR
@item GDBM_FILE_SEEK_ERROR
Positioning in a disk file failed. This can be set by
@code{gdbm_open} (@pxref{Open}) function.
+Inspect the value of the system @code{errno} variable to get a more
+detailed diagnostics.
+
@kwindex GDBM_FILE_READ_ERROR
@item GDBM_FILE_READ_ERROR
Reading from a disk file failed. This can be set by
@code{gdbm_open} (@pxref{Open}), @code{gdbm_export} and
@code{gdbm_import} functions.
+Inspect the value of the system @code{errno} variable to get a more
+detailed diagnostics.
+
@kwindex GDBM_BAD_MAGIC_NUMBER
@item GDBM_BAD_MAGIC_NUMBER
The file given as argument to @code{gdbm_open} function is not a valid
@@ -1464,6 +1476,9 @@ Set by the @code{gdbm_export} function if supplied an invalid
@item GDBM_FILE_STAT_ERROR
Getting information about a disk file failed. The system @code{errno}
will give more details about the error.
+
+This error can be set by the following functions: @code{gdbm_open},
+@code{gdbm_reorganize}.
@end table
@node Compatibility
diff --git a/src/gdbmdefs.h b/src/gdbmdefs.h
index 28995de..b5922e3 100644
--- a/src/gdbmdefs.h
+++ b/src/gdbmdefs.h
@@ -204,5 +204,15 @@ struct gdbm_file_info {
begins */
};
+/* Execute CODE without clobbering errno */
+#define SAVE_ERRNO(code) \
+ do \
+ { \
+ int __ec = errno; \
+ code; \
+ errno = __ec; \
+ } \
+ while (0) \
+
/* Now define all the routines in use. */
#include "proto.h"
diff --git a/src/gdbmopen.c b/src/gdbmopen.c
index 2029499..a8a488f 100644
--- a/src/gdbmopen.c
+++ b/src/gdbmopen.c
@@ -145,8 +145,8 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
}
if (dbf->desc < 0)
{
- free (dbf->name);
- free (dbf);
+ SAVE_ERRNO (free (dbf->name);
+ free (dbf));
gdbm_errno = GDBM_FILE_OPEN_ERROR;
return NULL;
}
@@ -154,12 +154,10 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
/* Get the status of the file. */
if (fstat (dbf->desc, &file_stat))
{
- int ec = errno;
- close (dbf->desc);
- free (dbf->name);
- free (dbf);
+ SAVE_ERRNO (close (dbf->desc);
+ free (dbf->name);
+ free (dbf));
gdbm_errno = GDBM_FILE_STAT_ERROR;
- errno = ec;
return NULL;
}
@@ -286,7 +284,7 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
num_bytes = __write (dbf, dbf->header, dbf->header->block_size);
if (num_bytes != dbf->header->block_size)
{
- gdbm_close (dbf);
+ SAVE_ERRNO (gdbm_close (dbf));
gdbm_errno = GDBM_FILE_WRITE_ERROR;
return NULL;
}
@@ -295,7 +293,7 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
num_bytes = __write (dbf, dbf->dir, dbf->header->dir_size);
if (num_bytes != dbf->header->dir_size)
{
- gdbm_close (dbf);
+ SAVE_ERRNO (gdbm_close (dbf));
gdbm_errno = GDBM_FILE_WRITE_ERROR;
return NULL;
}
@@ -304,7 +302,7 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
num_bytes = __write (dbf, dbf->bucket, dbf->header->bucket_size);
if (num_bytes != dbf->header->bucket_size)
{
- gdbm_close (dbf);
+ SAVE_ERRNO (gdbm_close (dbf));
gdbm_errno = GDBM_FILE_WRITE_ERROR;
return NULL;
}
@@ -325,7 +323,7 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
num_bytes = __read (dbf, &partial_header, sizeof (gdbm_file_header));
if (num_bytes != sizeof (gdbm_file_header))
{
- gdbm_close (dbf);
+ SAVE_ERRNO (gdbm_close (dbf));
gdbm_errno = GDBM_FILE_READ_ERROR;
return NULL;
}
@@ -365,7 +363,7 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
dbf->header->block_size-sizeof (gdbm_file_header));
if (num_bytes != dbf->header->block_size-sizeof (gdbm_file_header))
{
- gdbm_close (dbf);
+ SAVE_ERRNO (gdbm_close (dbf));
gdbm_errno = GDBM_FILE_READ_ERROR;
return NULL;
}
@@ -383,7 +381,7 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
file_pos = __lseek (dbf, dbf->header->dir, L_SET);
if (file_pos != dbf->header->dir)
{
- gdbm_close (dbf);
+ SAVE_ERRNO (gdbm_close (dbf));
gdbm_errno = GDBM_FILE_SEEK_ERROR;
return NULL;
}
@@ -391,7 +389,7 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
num_bytes = __read (dbf, dbf->dir, dbf->header->dir_size);
if (num_bytes != dbf->header->dir_size)
{
- gdbm_close (dbf);
+ SAVE_ERRNO (gdbm_close (dbf));
gdbm_errno = GDBM_FILE_READ_ERROR;
return NULL;
}
diff --git a/src/mmap.c b/src/mmap.c
index 44101e9..8735624 100644
--- a/src/mmap.c
+++ b/src/mmap.c
@@ -134,10 +134,8 @@ _gdbm_mapped_remap (GDBM_FILE dbf, off_t size, int flag)
if (_gdbm_file_size (dbf, &file_size))
{
- int ec = errno;
+ SAVE_ERRNO (_gdbm_mapped_unmap (dbf));
gdbm_errno = GDBM_FILE_STAT_ERROR;
- _gdbm_mapped_unmap (dbf);
- errno = ec;
return -1;
}
@@ -332,9 +330,7 @@ _gdbm_mapped_lseek (GDBM_FILE dbf, off_t offset, int whence)
off_t file_size;
if (_gdbm_file_size (dbf, &file_size))
{
- int ec = errno;
gdbm_errno = GDBM_FILE_STAT_ERROR;
- errno = ec;
return -1;
}
needle = file_size - offset;

Return to:

Send suggestions and report system problems to the System administrator.