From: Ian Jackson Date: Wed, 13 Feb 2008 16:24:30 +0000 (+0000) Subject: check return value from read() and write() properly X-Git-Tag: xen-3.3.0-rc1~250 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=a5975c8e7180095f786ac293c07b320185a25b4b;p=qemu-xen-4.4-testing.git check return value from read() and write() properly The system calls read and write may return less than the whole amount requested for a number of reasons. So the idioms if (read(fd, &object, sizeof(object)) != sizeof(object)) goto fail; and even worse if (read(fd, &object, sizeof(object)) < 0) goto fail; are wrong. Additionally, read and write may sometimes return EINTR on some systems so interruption is not desired or expected a loop is needed. --- diff --git a/Makefile b/Makefile index a4417216a..89c4bd65c 100644 --- a/Makefile +++ b/Makefile @@ -154,7 +154,7 @@ qemu-img-%.o: %.c $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< # dyngen host tool -dyngen$(EXESUF): dyngen.c +dyngen$(EXESUF): dyngen.c osdep.o $(HOST_CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ clean: diff --git a/block-bochs.c b/block-bochs.c index b167e0bbf..ce4480ef4 100644 --- a/block-bochs.c +++ b/block-bochs.c @@ -126,7 +126,7 @@ static int bochs_open(BlockDriverState *bs, const char *filename, int flags) s->fd = fd; - if (read(fd, &bochs, sizeof(bochs)) != sizeof(bochs)) { + if (qemu_read(fd, &bochs, sizeof(bochs)) != sizeof(bochs)) { goto fail; } @@ -151,7 +151,7 @@ static int bochs_open(BlockDriverState *bs, const char *filename, int flags) s->catalog_bitmap = qemu_malloc(s->catalog_size * 4); if (!s->catalog_bitmap) goto fail; - if (read(s->fd, s->catalog_bitmap, s->catalog_size * 4) != + if (qemu_read(s->fd, s->catalog_bitmap, s->catalog_size * 4) != s->catalog_size * 4) goto fail; for (i = 0; i < s->catalog_size; i++) @@ -176,6 +176,7 @@ static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num) int64_t offset = sector_num * 512; int64_t extent_index, extent_offset, bitmap_offset, block_offset; char bitmap_entry; + int r; // seek to sector extent_index = offset / s->extent_size; @@ -200,7 +201,9 @@ static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num) // read in bitmap for current extent lseek(s->fd, bitmap_offset + (extent_offset / 8), SEEK_SET); - read(s->fd, &bitmap_entry, 1); + r = read(s->fd, &bitmap_entry, 1); + if (r < 0) return -1; + if (r == 0) { errno= EIO; return -1; } if (!((bitmap_entry >> (extent_offset % 8)) & 1)) { @@ -223,8 +226,8 @@ static int bochs_read(BlockDriverState *bs, int64_t sector_num, while (nb_sectors > 0) { if (!seek_to_sector(bs, sector_num)) { - ret = read(s->fd, buf, 512); - if (ret != 512) + ret = qemu_read_ok(s->fd, buf, 512); + if (ret < 0) return -1; } else diff --git a/block-cloop.c b/block-cloop.c index 43d380127..6377e1009 100644 --- a/block-cloop.c +++ b/block-cloop.c @@ -66,10 +66,10 @@ cloop_close: close(s->fd); return -1; } - if(read(s->fd,&s->block_size,4)<4) + if(qemu_read_ok(s->fd,&s->block_size,4)<0) goto cloop_close; s->block_size=be32_to_cpu(s->block_size); - if(read(s->fd,&s->n_blocks,4)<4) + if(qemu_read_ok(s->fd,&s->n_blocks,4)<0) goto cloop_close; s->n_blocks=be32_to_cpu(s->n_blocks); @@ -77,7 +77,7 @@ cloop_close: offsets_size=s->n_blocks*sizeof(uint64_t); if(!(s->offsets=(uint64_t*)malloc(offsets_size))) goto cloop_close; - if(read(s->fd,s->offsets,offsets_size)fd,s->offsets,offsets_size)<0) goto cloop_close; for(i=0;in_blocks;i++) { s->offsets[i]=be64_to_cpu(s->offsets[i]); @@ -109,8 +109,8 @@ static inline int cloop_read_block(BDRVCloopState *s,int block_num) uint32_t bytes = s->offsets[block_num+1]-s->offsets[block_num]; lseek(s->fd, s->offsets[block_num], SEEK_SET); - ret = read(s->fd, s->compressed_block, bytes); - if (ret != bytes) + ret = qemu_read_ok(s->fd, s->compressed_block, bytes); + if (ret < 0) return -1; s->zstream.next_in = s->compressed_block; diff --git a/block-cow.c b/block-cow.c index 9e7b64602..6c0d65771 100644 --- a/block-cow.c +++ b/block-cow.c @@ -77,7 +77,7 @@ static int cow_open(BlockDriverState *bs, const char *filename, int flags) } s->fd = fd; /* see if it is a cow image */ - if (read(fd, &cow_header, sizeof(cow_header)) != sizeof(cow_header)) { + if (qemu_read_ok(fd, &cow_header, sizeof(cow_header)) < 0) { goto fail; } @@ -159,8 +159,8 @@ static int cow_read(BlockDriverState *bs, int64_t sector_num, while (nb_sectors > 0) { if (is_changed(s->cow_bitmap, sector_num, nb_sectors, &n)) { lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET); - ret = read(s->fd, buf, n * 512); - if (ret != n * 512) + ret = qemu_read_ok(s->fd, buf, n * 512); + if (ret < 0) return -1; } else { if (bs->backing_hd) { diff --git a/block-dmg.c b/block-dmg.c index 62117c97a..8f17c4e43 100644 --- a/block-dmg.c +++ b/block-dmg.c @@ -60,7 +60,7 @@ static int dmg_probe(const uint8_t *buf, int buf_size, const char *filename) static off_t read_off(int fd) { uint64_t buffer; - if(read(fd,&buffer,8)<8) + if(qemu_read_ok(fd,&buffer,8)<0) return 0; return be64_to_cpu(buffer); } @@ -68,7 +68,7 @@ static off_t read_off(int fd) static off_t read_uint32(int fd) { uint32_t buffer; - if(read(fd,&buffer,4)<4) + if(qemu_read_ok(fd,&buffer,4)<0) return 0; return be32_to_cpu(buffer); } @@ -209,24 +209,15 @@ static inline int dmg_read_chunk(BDRVDMGState *s,int sector_num) s->current_chunk = s->n_chunks; switch(s->types[chunk]) { case 0x80000005: { /* zlib compressed */ - int i; - ret = lseek(s->fd, s->offsets[chunk], SEEK_SET); if(ret<0) return -1; /* we need to buffer, because only the chunk as whole can be * inflated. */ - i=0; - do { - ret = read(s->fd, s->compressed_chunk+i, s->lengths[chunk]-i); - if(ret<0 && errno==EINTR) - ret=0; - i+=ret; - } while(ret>=0 && ret+ilengths[chunk]); - - if (ret != s->lengths[chunk]) - return -1; + ret = qemu_read_ok(s->fd, s->compressed_chunk, s->lengths[chunk]); + if (ret < 0) + return -1; s->zstream.next_in = s->compressed_chunk; s->zstream.avail_in = s->lengths[chunk]; @@ -240,8 +231,8 @@ static inline int dmg_read_chunk(BDRVDMGState *s,int sector_num) return -1; break; } case 1: /* copy */ - ret = read(s->fd, s->uncompressed_chunk, s->lengths[chunk]); - if (ret != s->lengths[chunk]) + ret = qemu_read_ok(s->fd, s->uncompressed_chunk, s->lengths[chunk]); + if (ret < 0) return -1; break; case 2: /* zero */ diff --git a/block-parallels.c b/block-parallels.c index 4654b07b1..bc41f8bf4 100644 --- a/block-parallels.c +++ b/block-parallels.c @@ -84,7 +84,7 @@ static int parallels_open(BlockDriverState *bs, const char *filename, int flags) s->fd = fd; - if (read(fd, &ph, sizeof(ph)) != sizeof(ph)) + if (qemu_read_ok(fd, &ph, sizeof(ph)) < 0) goto fail; if (memcmp(ph.magic, HEADER_MAGIC, 16) || @@ -103,8 +103,7 @@ static int parallels_open(BlockDriverState *bs, const char *filename, int flags) s->catalog_bitmap = qemu_malloc(s->catalog_size * 4); if (!s->catalog_bitmap) goto fail; - if (read(s->fd, s->catalog_bitmap, s->catalog_size * 4) != - s->catalog_size * 4) + if (qemu_read_ok(s->fd, s->catalog_bitmap, s->catalog_size * 4) < 0) goto fail; for (i = 0; i < s->catalog_size; i++) le32_to_cpus(&s->catalog_bitmap[i]); @@ -147,7 +146,7 @@ static int parallels_read(BlockDriverState *bs, int64_t sector_num, while (nb_sectors > 0) { if (!seek_to_sector(bs, sector_num)) { - if (read(s->fd, buf, 512) != 512) + if (qemu_read_ok(s->fd, buf, 512) < 0) return -1; } else memset(buf, 0, 512); diff --git a/block-qcow.c b/block-qcow.c index 0ac2b42b4..cb207b2fb 100644 --- a/block-qcow.c +++ b/block-qcow.c @@ -738,7 +738,7 @@ static void qcow_close(BlockDriverState *bs) static int qcow_create(const char *filename, int64_t total_size, const char *backing_file, int flags) { - int fd, header_size, backing_filename_len, l1_size, i, shift; + int fd, header_size, backing_filename_len, l1_size, i, shift, errno_save; QCowHeader header; uint64_t tmp; @@ -779,18 +779,28 @@ static int qcow_create(const char *filename, int64_t total_size, header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE); } + /* write all the data */ - write(fd, &header, sizeof(header)); + if (qemu_write_ok(fd, &header, sizeof(header)) < 0) + goto fail; if (backing_file) { - write(fd, backing_file, backing_filename_len); + if (qemu_write_ok(fd, backing_file, backing_filename_len) < 0) + goto fail; } lseek(fd, header_size, SEEK_SET); tmp = 0; for(i = 0;i < l1_size; i++) { - write(fd, &tmp, sizeof(tmp)); + if (qemu_write_ok(fd, &tmp, sizeof(tmp)) < 0) + goto fail; } close(fd); return 0; + + fail: + errno_save= errno; + close(fd); + errno= errno_save; + return -1; } static int qcow_make_empty(BlockDriverState *bs) diff --git a/block-raw-posix.c b/block-raw-posix.c index 6b0009e56..28aaf02a6 100644 --- a/block-raw-posix.c +++ b/block-raw-posix.c @@ -163,7 +163,7 @@ static int raw_pread(BlockDriverState *bs, int64_t offset, } s->lseek_err_cnt=0; - ret = read(s->fd, buf, count); + ret = qemu_read(s->fd, buf, count); if (ret == count) goto label__raw_read__success; @@ -175,11 +175,11 @@ static int raw_pread(BlockDriverState *bs, int64_t offset, /* Try harder for CDrom. */ if (bs->type == BDRV_TYPE_CDROM) { lseek(s->fd, offset, SEEK_SET); - ret = read(s->fd, buf, count); + ret = qemu_read(s->fd, buf, count); if (ret == count) goto label__raw_read__success; lseek(s->fd, offset, SEEK_SET); - ret = read(s->fd, buf, count); + ret = qemu_read(s->fd, buf, count); if (ret == count) goto label__raw_read__success; @@ -216,7 +216,7 @@ static int raw_pwrite(BlockDriverState *bs, int64_t offset, } s->lseek_err_cnt = 0; - ret = write(s->fd, buf, count); + ret = qemu_write(s->fd, buf, count); if (ret == count) goto label__raw_write__success; diff --git a/block-vmdk.c b/block-vmdk.c index 9b5fb7346..b6ec89e8f 100644 --- a/block-vmdk.c +++ b/block-vmdk.c @@ -220,13 +220,13 @@ static int vmdk_snapshot_create(const char *filename, const char *backing_file) /* read the header */ if (lseek(p_fd, 0x0, SEEK_SET) == -1) goto fail; - if (read(p_fd, hdr, HEADER_SIZE) != HEADER_SIZE) + if (qemu_read_ok(p_fd, hdr, HEADER_SIZE) < 0) goto fail; /* write the header */ if (lseek(snp_fd, 0x0, SEEK_SET) == -1) goto fail; - if (write(snp_fd, hdr, HEADER_SIZE) == -1) + if (qemu_write_ok(snp_fd, hdr, HEADER_SIZE) == -1) goto fail; memset(&header, 0, sizeof(header)); @@ -236,7 +236,7 @@ static int vmdk_snapshot_create(const char *filename, const char *backing_file) /* the descriptor offset = 0x200 */ if (lseek(p_fd, 0x200, SEEK_SET) == -1) goto fail; - if (read(p_fd, p_desc, DESC_SIZE) != DESC_SIZE) + if (qemu_read_ok(p_fd, p_desc, DESC_SIZE) < 0) goto fail; if ((p_name = strstr(p_desc,"CID")) != 0) { @@ -258,7 +258,7 @@ static int vmdk_snapshot_create(const char *filename, const char *backing_file) /* write the descriptor */ if (lseek(snp_fd, 0x200, SEEK_SET) == -1) goto fail; - if (write(snp_fd, s_desc, strlen(s_desc)) == -1) + if (qemu_write_ok(snp_fd, s_desc, strlen(s_desc)) == -1) goto fail; gd_offset = header.gd_offset * SECTOR_SIZE; // offset of GD table @@ -280,11 +280,11 @@ static int vmdk_snapshot_create(const char *filename, const char *backing_file) goto fail; if (lseek(p_fd, rgd_offset, SEEK_SET) == -1) goto fail_rgd; - if (read(p_fd, rgd_buf, gd_size) != gd_size) + if (qemu_read_ok(p_fd, rgd_buf, gd_size) < 0) goto fail_rgd; if (lseek(snp_fd, rgd_offset, SEEK_SET) == -1) goto fail_rgd; - if (write(snp_fd, rgd_buf, gd_size) == -1) + if (qemu_write_ok(snp_fd, rgd_buf, gd_size) == -1) goto fail_rgd; qemu_free(rgd_buf); @@ -294,11 +294,11 @@ static int vmdk_snapshot_create(const char *filename, const char *backing_file) goto fail_rgd; if (lseek(p_fd, gd_offset, SEEK_SET) == -1) goto fail_gd; - if (read(p_fd, gd_buf, gd_size) != gd_size) + if (qemu_read_ok(p_fd, gd_buf, gd_size) < 0) goto fail_gd; if (lseek(snp_fd, gd_offset, SEEK_SET) == -1) goto fail_gd; - if (write(snp_fd, gd_buf, gd_size) == -1) + if (qemu_write_ok(snp_fd, gd_buf, gd_size) == -1) goto fail_gd; qemu_free(gd_buf); @@ -765,6 +765,8 @@ static int vmdk_create(const char *filename, int64_t total_size, header.check_bytes[2] = 0xd; header.check_bytes[3] = 0xa; + /* BUG XXX No error checking anywhere here! XXX BUG */ + /* write all the data */ write(fd, &magic, sizeof(magic)); write(fd, &header, sizeof(header)); diff --git a/block-vpc.c b/block-vpc.c index f76c45112..9e16c6df6 100644 --- a/block-vpc.c +++ b/block-vpc.c @@ -100,14 +100,14 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags) s->fd = fd; - if (read(fd, &header, HEADER_SIZE) != HEADER_SIZE) + if (qemu_read_ok(fd, &header, HEADER_SIZE) < 0) goto fail; if (strncmp(header.magic, "conectix", 8)) goto fail; lseek(s->fd, be32_to_cpu(header.type.main.subheader_offset), SEEK_SET); - if (read(fd, &header, HEADER_SIZE) != HEADER_SIZE) + if (qemu_read_ok(fd, &header, HEADER_SIZE) < 0) goto fail; if (strncmp(header.magic, "cxsparse", 8)) @@ -122,8 +122,7 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags) s->pagetable = qemu_malloc(s->pagetable_entries * 4); if (!s->pagetable) goto fail; - if (read(s->fd, s->pagetable, s->pagetable_entries * 4) != - s->pagetable_entries * 4) + if (qemu_read_ok(s->fd, s->pagetable, s->pagetable_entries * 4) < 0) goto fail; for (i = 0; i < s->pagetable_entries; i++) be32_to_cpus(&s->pagetable[i]); @@ -175,7 +174,7 @@ static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num) // Scary! Bitmap is stored as big endian 32bit entries, // while we used to look it up byte by byte - read(s->fd, s->pageentry_u8, 512); + read(s->fd, s->pageentry_u8, 512); // no error handling ?! for (i = 0; i < 128; i++) be32_to_cpus(&s->pageentry_u32[i]); } @@ -185,7 +184,7 @@ static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num) #else lseek(s->fd, bitmap_offset + (pageentry_index / 8), SEEK_SET); - read(s->fd, &bitmap_entry, 1); + read(s->fd, &bitmap_entry, 1); // no error handling ?! if ((bitmap_entry >> (pageentry_index % 8)) & 1) return -1; // not allocated @@ -205,8 +204,8 @@ static int vpc_read(BlockDriverState *bs, int64_t sector_num, while (nb_sectors > 0) { if (!seek_to_sector(bs, sector_num)) { - ret = read(s->fd, buf, 512); - if (ret != 512) + ret = qemu_read_ok(s->fd, buf, 512); + if (ret < 0) return -1; } else diff --git a/block-vvfat.c b/block-vvfat.c index a93fde970..cf5e78b6d 100644 --- a/block-vvfat.c +++ b/block-vvfat.c @@ -1173,7 +1173,6 @@ static int open_file(BDRVVVFATState* s,mapping_t* mapping) static inline int read_cluster(BDRVVVFATState *s,int cluster_num) { if(s->current_cluster != cluster_num) { - int result=0; off_t offset; assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY)); if(!s->current_mapping @@ -1208,8 +1207,7 @@ read_cluster_directory: if(lseek(s->current_fd, offset, SEEK_SET)!=offset) return -3; s->cluster=s->cluster_buffer; - result=read(s->current_fd,s->cluster,s->cluster_size); - if(result<0) { + if (qemu_read_ok(s->current_fd,s->cluster,s->cluster_size) < 0) { s->current_cluster = -1; return -1; } @@ -2241,7 +2239,7 @@ static int commit_one_file(BDRVVVFATState* s, if (ret < 0) return ret; - if (write(fd, cluster, rest_size) < 0) + if (qemu_write_ok(fd, cluster, rest_size) < 0) return -2; offset += rest_size; diff --git a/darwin-user/machload.c b/darwin-user/machload.c index 3ba417ed0..d4ab843b2 100644 --- a/darwin-user/machload.c +++ b/darwin-user/machload.c @@ -440,7 +440,7 @@ void *load_data(int fd, long offset, unsigned int size) if (!data) return NULL; lseek(fd, offset, SEEK_SET); - if (read(fd, data, size) != size) { + if (qemu_read_ok(fd, data, size) < 0) { free(data); return NULL; } @@ -472,7 +472,7 @@ int load_object(const char *filename, struct target_pt_regs * regs, void ** mh) qerror("can't open file '%s'", filename); /* Read magic header. */ - if (read(fd, &magic, sizeof (magic)) != sizeof (magic)) + if (qemu_read_ok(fd, &magic, sizeof (magic)) < 0) qerror("unable to read Magic of '%s'", filename); /* Check Mach identification. */ @@ -506,7 +506,7 @@ int load_object(const char *filename, struct target_pt_regs * regs, void ** mh) lseek(fd, 0, SEEK_SET); /* Read Fat header. */ - if (read(fd, &fh, sizeof (fh)) != sizeof (fh)) + if (qemu_read_ok(fd, &fh, sizeof (fh)) < 0) qerror("unable to read file header"); if(need_bswap) @@ -515,7 +515,7 @@ int load_object(const char *filename, struct target_pt_regs * regs, void ** mh) /* Read Fat Arch. */ fa = malloc(sizeof(struct fat_arch)*fh.nfat_arch); - if (read(fd, fa, sizeof(struct fat_arch)*fh.nfat_arch) != sizeof(struct fat_arch)*fh.nfat_arch) + if (qemu_read_ok(fd, fa, sizeof(struct fat_arch)*fh.nfat_arch) < 0) qerror("unable to read file header"); for( i = 0; i < fh.nfat_arch; i++, fa++) @@ -529,7 +529,7 @@ int load_object(const char *filename, struct target_pt_regs * regs, void ** mh) /* Read Mach header. */ - if (read(fd, &mach_hdr, sizeof(struct mach_header)) != sizeof (struct mach_header)) + if (qemu_read_ok(fd, &mach_hdr, sizeof(struct mach_header)) < 0) qerror("unable to read file header"); if(mach_hdr.magic == MH_MAGIC) @@ -549,7 +549,7 @@ int load_object(const char *filename, struct target_pt_regs * regs, void ** mh) { lseek(fd, 0, SEEK_SET); /* Read Mach header */ - if (read(fd, &mach_hdr, sizeof (mach_hdr)) != sizeof (mach_hdr)) + if (qemu_read_ok(fd, &mach_hdr, sizeof (mach_hdr)) < 0) qerror("%s: unable to read file header", filename); } @@ -573,7 +573,7 @@ int load_object(const char *filename, struct target_pt_regs * regs, void ** mh) /* read segment headers */ lcmds = malloc(mach_hdr.sizeofcmds); - if(read(fd, lcmds, mach_hdr.sizeofcmds) != mach_hdr.sizeofcmds) + if(qemu_read_ok(fd, lcmds, mach_hdr.sizeofcmds) < 0) qerror("%s: unable to read load_command", filename); slide = 0; mmapfixed = 0; diff --git a/dyngen.c b/dyngen.c index 3b073c18f..53ba9c694 100644 --- a/dyngen.c +++ b/dyngen.c @@ -31,6 +31,7 @@ #include #include "config-host.h" +#include "osdep.h" /* NOTE: we test CONFIG_WIN32 instead of _WIN32 to enabled cross compilation */ @@ -251,7 +252,7 @@ static void *load_data(int fd, long offset, unsigned int size) if (!data) return NULL; lseek(fd, offset, SEEK_SET); - if (read(fd, data, size) != size) { + if (qemu_read_ok(fd, data, size) < 0) { free(data); return NULL; } @@ -489,7 +490,7 @@ int load_object(const char *filename) error("can't open file '%s'", filename); /* Read ELF header. */ - if (read(fd, &ehdr, sizeof (ehdr)) != sizeof (ehdr)) + if (qemu_read_ok(fd, &ehdr, sizeof (ehdr)) < 0) error("unable to read file header"); /* Check ELF identification. */ @@ -713,7 +714,7 @@ int load_object(const char *filename) error("can't open file '%s'", filename); /* Read COFF header. */ - if (read(fd, &fhdr, sizeof (fhdr)) != sizeof (fhdr)) + if (qemu_read_ok(fd, &fhdr, sizeof (fhdr)) < 0) error("unable to read file header"); /* Check COFF identification. */ @@ -1086,7 +1087,7 @@ int load_object(const char *filename) error("can't open file '%s'", filename); /* Read Mach header. */ - if (read(fd, &mach_hdr, sizeof (mach_hdr)) != sizeof (mach_hdr)) + if (qemu_read_ok(fd, &mach_hdr, sizeof (mach_hdr)) < 0) error("unable to read file header"); /* Check Mach identification. */ @@ -1103,14 +1104,14 @@ int load_object(const char *filename) /* read segment headers */ for(i=0, j=sizeof(mach_hdr); ip_filesz > 0) { if (lseek(fd, ph->p_offset, SEEK_SET) < 0) goto fail; - if (read(fd, data, ph->p_filesz) != ph->p_filesz) + if (qemu_read_ok(fd, data, ph->p_filesz) < 0) goto fail; } addr = ph->p_vaddr + virt_to_phys_addend; diff --git a/hw/pc.c b/hw/pc.c index 2a569c7bc..c46537e9b 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -446,17 +446,16 @@ static int load_kernel(const char *filename, uint8_t *addr, return -1; /* load 16 bit code */ - if (read(fd, real_addr, 512) != 512) + if (qemu_read_ok(fd, real_addr, 512) < 0) goto fail; setup_sects = real_addr[0x1F1]; if (!setup_sects) setup_sects = 4; - if (read(fd, real_addr + 512, setup_sects * 512) != - setup_sects * 512) + if (qemu_read_ok(fd, real_addr + 512, setup_sects * 512) < 0) goto fail; /* load 32 bit code */ - size = read(fd, addr, 16 * 1024 * 1024); + size = qemu_read(fd, addr, 16 * 1024 * 1024); if (size < 0) goto fail; close(fd); diff --git a/linux-user/elfload.c b/linux-user/elfload.c index cde3c49a7..8f7d141db 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -871,7 +871,7 @@ static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex, retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET); if(retval >= 0) { - retval = read(interpreter_fd, + retval = qemu_read_ok(interpreter_fd, (char *) elf_phdata, sizeof(struct elf_phdr) * interp_elf_ex->e_phnum); } @@ -991,7 +991,7 @@ static void load_symbols(struct elfhdr *hdr, int fd) lseek(fd, hdr->e_shoff, SEEK_SET); for (i = 0; i < hdr->e_shnum; i++) { - if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr)) + if (qemu_read_ok(fd, &sechdr, sizeof(sechdr)) < 0) return; #ifdef BSWAP_NEEDED bswap_shdr(&sechdr); @@ -1000,8 +1000,7 @@ static void load_symbols(struct elfhdr *hdr, int fd) symtab = sechdr; lseek(fd, hdr->e_shoff + sizeof(sechdr) * sechdr.sh_link, SEEK_SET); - if (read(fd, &strtab, sizeof(strtab)) - != sizeof(strtab)) + if (qemu_read_ok(fd, &strtab, sizeof(strtab)) < 0) return; #ifdef BSWAP_NEEDED bswap_shdr(&strtab); @@ -1024,7 +1023,7 @@ static void load_symbols(struct elfhdr *hdr, int fd) return; lseek(fd, symtab.sh_offset, SEEK_SET); - if (read(fd, s->disas_symtab, symtab.sh_size) != symtab.sh_size) + if (qemu_read_ok(fd, s->disas_symtab, symtab.sh_size) < 0) return; for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++) { @@ -1047,7 +1046,7 @@ static void load_symbols(struct elfhdr *hdr, int fd) s->disas_symtab = syms32; #endif lseek(fd, strtab.sh_offset, SEEK_SET); - if (read(fd, strings, strtab.sh_size) != strtab.sh_size) + if (qemu_read_ok(fd, strings, strtab.sh_size) < 0) return; s->disas_num_syms = symtab.sh_size / sizeof(struct elf_sym); s->next = syminfos; @@ -1109,7 +1108,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET); if(retval > 0) { - retval = read(bprm->fd, (char *) elf_phdata, + retval = qemu_read_ok(bprm->fd, (char *) elf_phdata, elf_ex.e_phentsize * elf_ex.e_phnum); } @@ -1164,7 +1163,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET); if(retval >= 0) { - retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz); + retval = qemu_read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz); } if(retval < 0) { perror("load_elf_binary2"); @@ -1200,7 +1199,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, if (retval >= 0) { retval = lseek(interpreter_fd, 0, SEEK_SET); if(retval >= 0) { - retval = read(interpreter_fd,bprm->buf,128); + retval = qemu_read_ok(interpreter_fd,bprm->buf,128); } } if (retval >= 0) { diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c index ada7c697d..da08ed1e2 100644 --- a/linux-user/linuxload.c +++ b/linux-user/linuxload.c @@ -99,7 +99,7 @@ static int prepare_binprm(struct linux_binprm *bprm) memset(bprm->buf, 0, sizeof(bprm->buf)); retval = lseek(bprm->fd, 0L, SEEK_SET); if(retval >= 0) { - retval = read(bprm->fd, bprm->buf, 128); + retval = qemu_read_ok(bprm->fd, bprm->buf, 128); } if(retval < 0) { perror("prepare_binprm"); diff --git a/loader.c b/loader.c index 062dee401..813756e9c 100644 --- a/loader.c +++ b/loader.c @@ -47,7 +47,7 @@ int load_image(const char *filename, uint8_t *addr) return -1; size = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); - if (read(fd, addr, size) != size) { + if (qemu_read_ok(fd, addr, size) < 0) { close(fd); return -1; } @@ -115,8 +115,7 @@ int load_aout(const char *filename, uint8_t *addr) if (fd < 0) return -1; - size = read(fd, &e, sizeof(e)); - if (size < 0) + if (qemu_read_ok(fd, &e, sizeof(e)) < 0) goto fail; bswap_ahdr(&e); @@ -127,17 +126,17 @@ int load_aout(const char *filename, uint8_t *addr) case QMAGIC: case OMAGIC: lseek(fd, N_TXTOFF(e), SEEK_SET); - size = read(fd, addr, e.a_text + e.a_data); - if (size < 0) + size = qemu_read(fd, addr, e.a_text + e.a_data); + if (size != e.a_text + e.a_data) goto fail; break; case NMAGIC: lseek(fd, N_TXTOFF(e), SEEK_SET); - size = read(fd, addr, e.a_text); - if (size < 0) + size = qemu_read(fd, addr, e.a_text); + if (size != e.a_text) goto fail; - ret = read(fd, addr + N_DATADDR(e), e.a_data); - if (ret < 0) + ret = qemu_read(fd, addr + N_DATADDR(e), e.a_data); + if (ret != e.a_data) goto fail; size += ret; break; @@ -161,7 +160,7 @@ static void *load_at(int fd, int offset, int size) ptr = qemu_malloc(size); if (!ptr) return NULL; - if (read(fd, ptr, size) != size) { + if (qemu_read_ok(fd, ptr, size) < 0) { qemu_free(ptr); return NULL; } @@ -210,7 +209,7 @@ int load_elf(const char *filename, int64_t virt_to_phys_addend, perror(filename); return -1; } - if (read(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident)) + if (qemu_read_ok(fd, e_ident, sizeof(e_ident)) < 0) goto fail; if (e_ident[0] != ELFMAG0 || e_ident[1] != ELFMAG1 || @@ -276,7 +275,7 @@ int load_uboot(const char *filename, target_ulong *ep, int *is_linux) if (fd < 0) return -1; - size = read(fd, hdr, sizeof(uboot_image_header_t)); + size = qemu_read(fd, hdr, sizeof(uboot_image_header_t)); if (size < 0) goto fail; @@ -310,7 +309,7 @@ int load_uboot(const char *filename, target_ulong *ep, int *is_linux) if (!data) goto fail; - if (read(fd, data, hdr->ih_size) != hdr->ih_size) { + if (qemu_read_ok(fd, data, hdr->ih_size) < 0) { fprintf(stderr, "Error reading file\n"); goto fail; } diff --git a/osdep.c b/osdep.c index f824bc1ea..858f9adf6 100644 --- a/osdep.c +++ b/osdep.c @@ -28,6 +28,7 @@ #include #include #include +#include #ifdef HOST_SOLARIS #include #include @@ -60,6 +61,33 @@ void *qemu_malloc(size_t size) return malloc(size); } +#define define_readwrite(rw, cnst) \ +ssize_t qemu_##rw(int fd, cnst void *buf, size_t count) { \ + ssize_t got, done; \ + done = 0; \ + while (count>0) { \ + got = rw(fd, buf, count); \ + if (got == 0) { errno = 0; return done; } \ + if (got < 0) { \ + if (errno==EINTR) continue; \ + return done ? done : -1; \ + } \ + assert(got <= count); \ + done += got; \ + count -= got; \ + buf = (cnst char*)buf + got; \ + } \ + return done; \ +} \ +int qemu_##rw##_ok(int fd, cnst void *buf, size_t count) { \ + ssize_t got; \ + got = qemu_##rw(fd, buf, count); \ + if (got == count) return 1; \ + return -1; \ +} +define_readwrite(read, /* empty */) +define_readwrite(write, const) + #if defined(_WIN32) void *qemu_memalign(size_t alignment, size_t size) { diff --git a/osdep.h b/osdep.h index eb3198c78..c59cb1ce9 100644 --- a/osdep.h +++ b/osdep.h @@ -2,6 +2,7 @@ #define QEMU_OSDEP_H #include +#include #ifndef glue #define xglue(x, y) x ## y @@ -56,6 +57,17 @@ void *qemu_memalign(size_t alignment, size_t size); void *qemu_vmalloc(size_t size); void qemu_vfree(void *ptr); +ssize_t qemu_read(int fd, void *buf, size_t count); +ssize_t qemu_write(int fd, const void *buf, size_t count); + /* Repeatedly call read/write until the request is satisfied or an error + * occurs, and then returns what read would have done. If it returns + * a short read then errno is set, or zero if it was EOF. */ + +int qemu_read_ok(int fd, void *buf, size_t count); +int qemu_write_ok(int fd, const void *buf, size_t count); + /* Even more simplified versions which return 1 on success or -1 on + * failure. EOF counts as failure but then errno is set to 0. */ + void *get_mmap_addr(unsigned long size); int qemu_create_pidfile(const char *filename); diff --git a/tests/hello-arm.c b/tests/hello-arm.c index e0daa7ad9..9216a6cf1 100644 --- a/tests/hello-arm.c +++ b/tests/hello-arm.c @@ -108,6 +108,6 @@ _syscall3(int,write,int,fd,const char *,buf, int, len); void _start(void) { - write(1, "Hello World\n", 12); + qemu_write(1, "Hello World\n", 12); exit1(0); } diff --git a/tests/linux-test.c b/tests/linux-test.c index 2f82defe0..bf87bdade 100644 --- a/tests/linux-test.c +++ b/tests/linux-test.c @@ -103,7 +103,7 @@ void test_file(void) fd = chk_error(open("file1", O_WRONLY | O_TRUNC | O_CREAT, 0644)); for(i=0;i < FILE_BUF_SIZE; i++) buf[i] = i; - len = chk_error(write(fd, buf, FILE_BUF_SIZE / 2)); + len = chk_error(qemu_write(fd, buf, FILE_BUF_SIZE / 2)); if (len != (FILE_BUF_SIZE / 2)) error("write"); vecs[0].iov_base = buf + (FILE_BUF_SIZE / 2); diff --git a/tests/qruncom.c b/tests/qruncom.c index 7b25fcded..a3032a337 100644 --- a/tests/qruncom.c +++ b/tests/qruncom.c @@ -175,7 +175,7 @@ int main(int argc, char **argv) perror(filename); exit(1); } - ret = read(fd, vm86_mem + COM_BASE_ADDR, 65536 - 256); + ret = qemu_read_ok(fd, vm86_mem + COM_BASE_ADDR, 65536 - 256); if (ret < 0) { perror("read"); exit(1); diff --git a/tests/testthread.c b/tests/testthread.c index 27e4825bc..333dcb1f5 100644 --- a/tests/testthread.c +++ b/tests/testthread.c @@ -15,7 +15,7 @@ void *thread1_func(void *arg) for(i=0;i<10;i++) { snprintf(buf, sizeof(buf), "thread1: %d %s\n", i, (char *)arg); - write(1, buf, strlen(buf)); + qemu_write(1, buf, strlen(buf)); usleep(100 * 1000); } return NULL; @@ -27,7 +27,7 @@ void *thread2_func(void *arg) char buf[512]; for(i=0;i<20;i++) { snprintf(buf, sizeof(buf), "thread2: %d %s\n", i, (char *)arg); - write(1, buf, strlen(buf)); + qemu_write(1, buf, strlen(buf)); usleep(150 * 1000); } return NULL; diff --git a/usb-linux.c b/usb-linux.c index d3e4e2ef4..d8032a80b 100644 --- a/usb-linux.c +++ b/usb-linux.c @@ -348,8 +348,8 @@ static void urb_completion_pipe_read(void *opaque) struct usbdevfs_urb *purb = NULL; int len, ret; - len = read(s->pipe_fds[0], &pending_urb, sizeof(pending_urb)); - if (len != sizeof(pending_urb)) { + ret = qemu_read_ok(s->pipe_fds[0], &pending_urb, sizeof(pending_urb)); + if (ret < 0) { printf("urb_completion: error reading pending_urb, len=%d\n", len); return; } diff --git a/vl.c b/vl.c index 7e0299269..50129a340 100644 --- a/vl.c +++ b/vl.c @@ -1999,29 +1999,9 @@ void socket_set_nonblock(int fd) #else -static int unix_write(int fd, const uint8_t *buf, int len1) -{ - int ret, len; - - len = len1; - while (len > 0) { - ret = write(fd, buf, len); - if (ret < 0) { - if (errno != EINTR && errno != EAGAIN) - return -1; - } else if (ret == 0) { - break; - } else { - buf += ret; - len -= ret; - } - } - return len1 - len; -} - static inline int send_all(int fd, const uint8_t *buf, int len1) { - return unix_write(fd, buf, len1); + return qemu_write(fd, buf, len1); } void socket_set_nonblock(int fd) @@ -2043,7 +2023,7 @@ static int stdio_nb_clients = 0; static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { FDCharDriver *s = chr->opaque; - return unix_write(s->fd_out, buf, len); + return qemu_write(s->fd_out, buf, len); } static int fd_chr_read_poll(void *opaque) @@ -2479,8 +2459,7 @@ static int pp_ioctl(CharDriverState *chr, int cmd, void *arg) case CHR_IOCTL_PP_EPP_READ_ADDR: if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) { struct ParallelIOArg *parg = arg; - int n = read(fd, parg->buffer, parg->count); - if (n != parg->count) { + if (qemu_read_ok(fd, parg->buffer, parg->count) < 0) { return -EIO; } } @@ -2488,8 +2467,7 @@ static int pp_ioctl(CharDriverState *chr, int cmd, void *arg) case CHR_IOCTL_PP_EPP_READ: if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) { struct ParallelIOArg *parg = arg; - int n = read(fd, parg->buffer, parg->count); - if (n != parg->count) { + if (qemu_read_ok(fd, parg->buffer, parg->count) < 0) { return -EIO; } } @@ -2497,8 +2475,7 @@ static int pp_ioctl(CharDriverState *chr, int cmd, void *arg) case CHR_IOCTL_PP_EPP_WRITE_ADDR: if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) { struct ParallelIOArg *parg = arg; - int n = write(fd, parg->buffer, parg->count); - if (n != parg->count) { + if (qemu_write(fd, parg->buffer, parg->count) < 0) { return -EIO; } } @@ -2506,8 +2483,7 @@ static int pp_ioctl(CharDriverState *chr, int cmd, void *arg) case CHR_IOCTL_PP_EPP_WRITE: if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) { struct ParallelIOArg *parg = arg; - int n = write(fd, parg->buffer, parg->count); - if (n != parg->count) { + if (qemu_write_ok(fd, parg->buffer, parg->count) < 0) { return -EIO; } } @@ -3938,7 +3914,7 @@ static void tap_receive(void *opaque, const uint8_t *buf, int size) TAPState *s = opaque; int ret; for(;;) { - ret = write(s->fd, buf, size); + ret = write(s->fd, buf, size); /* No error handling ?! */ if (ret < 0 && (errno == EINTR || errno == EAGAIN)) { } else { break;