r23979: Fix another occurence of (written != requested) as an
authorMichael Adam <obnox@samba.org>
Fri, 20 Jul 2007 15:00:58 +0000 (15:00 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 20:01:14 +0000 (15:01 -0500)
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

source/lib/tdb/common/open.c

index eadb3fd2f37a305fe905c5acbba168a9e8a313ef..edb0a5091642bd9cc0b083d80cf4a889eb2985bc 100644 (file)
@@ -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);