summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2007-07-20 15:00:58 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 15:01:14 -0500
commit7002ed291a5831e0f5f89b038ab63dc31ea3287f (patch)
tree2ce30a5578b37b19fcaea1ddc54112e75fed050d
parentc94cba5b7bb0c1cc2cfb0eebc8efe0250de29e0a (diff)
downloadsamba-7002ed291a5831e0f5f89b038ab63dc31ea3287f.tar.gz
samba-7002ed291a5831e0f5f89b038ab63dc31ea3287f.tar.bz2
samba-7002ed291a5831e0f5f89b038ab63dc31ea3287f.zip
r23979: Fix another occurence of (written != requested) as an
error condition to write. This is in tdb_new_database. Fix one call to tdb_new_database in tdb_open_ex to not overwrite the newly propagated errno (typically ENOSPC). Michael (This used to be commit eb524df0a52783de6c94a11b44f268e0f26fbb2c)
-rw-r--r--source4/lib/tdb/common/open.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/source4/lib/tdb/common/open.c b/source4/lib/tdb/common/open.c
index eadb3fd2f3..edb0a50916 100644
--- a/source4/lib/tdb/common/open.c
+++ b/source4/lib/tdb/common/open.c
@@ -49,7 +49,9 @@ static unsigned int default_tdb_hash(TDB_DATA *key)
static int tdb_new_database(struct tdb_context *tdb, int hash_size)
{
struct tdb_header *newdb;
- int size, ret = -1;
+ size_t size;
+ int ret = -1;
+ ssize_t written;
/* We make it up in memory, then write it out if not internal */
size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off_t);
@@ -78,10 +80,22 @@ static int tdb_new_database(struct tdb_context *tdb, int hash_size)
memcpy(&tdb->header, newdb, sizeof(tdb->header));
/* Don't endian-convert the magic food! */
memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1);
- if (write(tdb->fd, newdb, size) != size) {
- ret = -1;
- } else {
+ /* we still have "ret == -1" here */
+ written = write(tdb->fd, newdb, size);
+ if (written == size) {
ret = 0;
+ } else if (written != -1) {
+ /* call write once again, this usually should return -1 and
+ * set errno appropriately */
+ size -= written;
+ written = write(tdb->fd, newdb+written, size);
+ if (written == size) {
+ ret = 0;
+ } else if (written >= 0) {
+ /* a second incomplete write - we give up.
+ * guessing the errno... */
+ errno = ENOSPC;
+ }
}
fail:
@@ -220,13 +234,16 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
}
}
+ errno = 0;
if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header)
|| strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0
|| (tdb->header.version != TDB_VERSION
&& !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) {
/* its not a valid database - possibly initialise it */
if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) {
- errno = EIO; /* ie bad format or something */
+ if (errno == 0) {
+ errno = EIO; /* ie bad format or something */
+ }
goto fail;
}
rev = (tdb->flags & TDB_CONVERT);