return false;
}
+static bool read_all(int fd, void *buf, size_t len)
+{
+ while (len) {
+ ssize_t ret;
+ ret = read(fd, buf, len);
+ if (ret < 0)
+ return false;
+ if (ret == 0) {
+ /* ETOOSHORT? */
+ errno = EWOULDBLOCK;
+ return false;
+ }
+ buf = (char *)buf + ret;
+ len -= ret;
+ }
+ return true;
+}
+
static uint64_t random_number(struct tdb_context *tdb)
{
int fd;
fd = open("/dev/urandom", O_RDONLY);
if (fd >= 0) {
- if (tdb_read_all(fd, &ret, sizeof(ret))) {
+ if (read_all(fd, &ret, sizeof(ret))) {
tdb_logerr(tdb, TDB_SUCCESS, TDB_DEBUG_TRACE,
"tdb_open: random from /dev/urandom");
close(fd);
/* We make it up in memory, then write it out if not internal */
struct new_database newdb;
unsigned int magic_len;
+ ssize_t rlen;
/* Fill in the header */
newdb.hdr.version = TDB_VERSION;
if (ftruncate(tdb->fd, 0) == -1)
return -1;
- if (!tdb_pwrite_all(tdb->fd, &newdb, sizeof(newdb), 0)) {
+ rlen = write(tdb->fd, &newdb, sizeof(newdb));
+ if (rlen != sizeof(newdb)) {
+ if (rlen >= 0)
+ errno = ENOSPC;
tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_FATAL,
- "tdb_new_database: failed to write: %s",
- strerror(errno));
+ "tdb_new_database: %zi writing header: %s",
+ rlen, strerror(errno));
return -1;
}
return 0;
int saved_errno = 0;
uint64_t hash_test;
unsigned v;
+ ssize_t rlen;
struct tdb_header hdr;
struct tdb_attribute_seed *seed = NULL;
goto fail;
}
- if (!tdb_pread_all(tdb->fd, &hdr, sizeof(hdr), 0)
- || strcmp(hdr.magic_food, TDB_MAGIC_FOOD) != 0) {
- if (!(open_flags & O_CREAT)) {
- tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_ERROR,
- "tdb_open: %s is not a tdb file", name);
- goto fail;
- }
+ /* If they used O_TRUNC, read will return 0. */
+ rlen = read(tdb->fd, &hdr, sizeof(hdr));
+ if (rlen == 0 && (open_flags & O_CREAT)) {
if (tdb_new_database(tdb, seed, &hdr) == -1) {
goto fail;
}
- } else if (hdr.version != TDB_VERSION) {
+ } else if (rlen < 0) {
+ tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_ERROR,
+ "tdb_open: error %s reading %s",
+ strerror(errno), name);
+ goto fail;
+ } else if (rlen < sizeof(hdr)
+ || strcmp(hdr.magic_food, TDB_MAGIC_FOOD) != 0) {
+ tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_ERROR,
+ "tdb_open: %s is not a tdb file", name);
+ goto fail;
+ }
+
+ if (hdr.version != TDB_VERSION) {
if (hdr.version == bswap_64(TDB_VERSION))
tdb->flags |= TDB_CONVERT;
else {