--- gdbm-1.8.3/bucket.c +++ gdbm-1.8.3/bucket.c @@ -30,8 +30,28 @@ /* include system configuration before all else. */ #include "autoconf.h" +#include #include "gdbmdefs.h" +static ssize_t +read_loop(int fd, void *buffer, size_t count) +{ + char *buf = buffer; + ssize_t offset = 0; + + while (count > 0) + { + ssize_t block = + TEMP_FAILURE_RETRY(read(fd, &buf[offset], count)); + + if (block <= 0) + return offset ? : block; + offset += block; + count -= block; + } + return offset; +} + /* Initializing a new hash buckets sets all bucket entries to -1 hash value. */ void @@ -111,7 +131,7 @@ _gdbm_get_bucket (dbf, dir_index) if (file_pos != bucket_adr) _gdbm_fatal (dbf, "lseek error"); - num_bytes = read (dbf->desc, dbf->bucket, dbf->header->bucket_size); + num_bytes = read_loop (dbf->desc, dbf->bucket, dbf->header->bucket_size); if (num_bytes != dbf->header->bucket_size) _gdbm_fatal (dbf, "read error"); } --- gdbm-1.8.3/falloc.c +++ gdbm-1.8.3/falloc.c @@ -30,6 +30,7 @@ /* include system configuration before all else. */ #include "autoconf.h" +#include #include "gdbmdefs.h" @@ -165,6 +166,26 @@ _gdbm_free (dbf, file_adr, num_bytes) /* The following are all utility routines needed by the previous two. */ +static ssize_t +read_loop(int fd, void *buffer, size_t count) +{ + char *buf = buffer; + ssize_t offset = 0; + + while (count > 0) + { + ssize_t block = + TEMP_FAILURE_RETRY(read(fd, &buf[offset], count)); + + if (block <= 0) + return offset ? : block; + offset += block; + count -= block; + } + return offset; +} + + /* Gets the avail block at the top of the stack and loads it into the active avail block. It does a "free" for itself! This can (and is) now called even when the avail block is not empty, so we must be @@ -199,7 +220,7 @@ pop_avail_block (dbf) /* Read the block. */ file_pos = lseek (dbf->desc, new_el.av_adr, L_SET); if (file_pos != new_el.av_adr) _gdbm_fatal (dbf, "lseek error"); - num_bytes = read (dbf->desc, new_blk, new_el.av_size); + num_bytes = read_loop (dbf->desc, new_blk, new_el.av_size); if (num_bytes != new_el.av_size) _gdbm_fatal (dbf, "read error"); /* Add the elements from the new block to the header. */ --- gdbm-1.8.3/findkey.c +++ gdbm-1.8.3/findkey.c @@ -30,8 +30,28 @@ /* include system configuration before all else. */ #include "autoconf.h" +#include #include "gdbmdefs.h" +static ssize_t +read_loop(int fd, void *buffer, size_t count) +{ + char *buf = buffer; + ssize_t offset = 0; + + while (count > 0) + { + ssize_t block = + TEMP_FAILURE_RETRY(read(fd, &buf[offset], count)); + + if (block <= 0) + return offset ? : block; + offset += block; + count -= block; + } + return offset; +} + /* Read the data found in bucket entry ELEM_LOC in file DBF and return a pointer to it. Also, cache the read value. */ @@ -74,7 +94,7 @@ _gdbm_read_entry (dbf, elem_loc) dbf->bucket->h_table[elem_loc].data_pointer, L_SET); if (file_pos != dbf->bucket->h_table[elem_loc].data_pointer) _gdbm_fatal (dbf, "lseek error"); - num_bytes = read (dbf->desc, data_ca->dptr, key_size+data_size); + num_bytes = read_loop (dbf->desc, data_ca->dptr, key_size+data_size); if (num_bytes != key_size+data_size) _gdbm_fatal (dbf, "read error"); return data_ca->dptr; --- gdbm-1.8.3/gdbmopen.c +++ gdbm-1.8.3/gdbmopen.c @@ -30,9 +30,30 @@ /* include system configuration before all else. */ #include "autoconf.h" +#include #include "gdbmdefs.h" #include "gdbmerrno.h" +static ssize_t +read_loop(int fd, void *buffer, size_t count) +{ + char *buf = buffer; + ssize_t offset = 0; + + while (count > 0) + { + ssize_t block = + TEMP_FAILURE_RETRY(read(fd, &buf[offset], count)); + + if (block <= 0) + return offset ? : block; + offset += block; + count -= block; + } + return offset; +} + + /* Initialize dbm system. FILE is a pointer to the file name. If the file has a size of zero bytes, a file initialization procedure is performed, setting up the initial structure in the file. BLOCK_SIZE is used during @@ -321,7 +342,7 @@ gdbm_open (file, block_size, flags, mode, fatal_func) gdbm_file_header partial_header; /* For the first part of it. */ /* Read the partial file header. */ - num_bytes = read (dbf->desc, &partial_header, sizeof (gdbm_file_header)); + num_bytes = read_loop (dbf->desc, &partial_header, sizeof (gdbm_file_header)); if (num_bytes != sizeof (gdbm_file_header)) { gdbm_close (dbf); @@ -346,7 +367,7 @@ gdbm_open (file, block_size, flags, mode, fatal_func) return NULL; } bcopy (&partial_header, dbf->header, sizeof (gdbm_file_header)); - num_bytes = read (dbf->desc, &dbf->header->avail.av_table[1], + num_bytes = read_loop (dbf->desc, &dbf->header->avail.av_table[1], dbf->header->block_size-sizeof (gdbm_file_header)); if (num_bytes != dbf->header->block_size-sizeof (gdbm_file_header)) { @@ -373,7 +394,7 @@ gdbm_open (file, block_size, flags, mode, fatal_func) return NULL; } - num_bytes = read (dbf->desc, dbf->dir, dbf->header->dir_size); + num_bytes = read_loop (dbf->desc, dbf->dir, dbf->header->dir_size); if (num_bytes != dbf->header->dir_size) { gdbm_close (dbf);