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 12:28:51 -0500 |
commit | 207a213c061b2c3a4dab42e9af1c19edaa39a2a0 (patch) | |
tree | 415a56dca52da589c6fb32b370b67a5973828308 /source3 | |
parent | e5051dd4a6657e265dd5baab828946d4ab52cc9f (diff) | |
download | samba-207a213c061b2c3a4dab42e9af1c19edaa39a2a0.tar.gz samba-207a213c061b2c3a4dab42e9af1c19edaa39a2a0.tar.bz2 samba-207a213c061b2c3a4dab42e9af1c19edaa39a2a0.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 24fed55d72a4922bfd3ddba61449fbae01365feb)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/lib/tdb/common/open.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/source3/lib/tdb/common/open.c b/source3/lib/tdb/common/open.c index eadb3fd2f3..edb0a50916 100644 --- a/source3/lib/tdb/common/open.c +++ b/source3/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); |