diff options
author | Michael Adam <obnox@samba.org> | 2007-07-20 15:00:58 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 15:01:14 -0500 |
commit | 7002ed291a5831e0f5f89b038ab63dc31ea3287f (patch) | |
tree | 2ce30a5578b37b19fcaea1ddc54112e75fed050d | |
parent | c94cba5b7bb0c1cc2cfb0eebc8efe0250de29e0a (diff) | |
download | samba-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.c | 27 |
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); |