diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/common/data_reader_dump.c | 57 | ||||
| -rw-r--r-- | lib/tar/padd_file.c | 4 | ||||
| -rw-r--r-- | lib/tar/write_header.c | 30 | ||||
| -rw-r--r-- | lib/tar/write_retry.c | 15 | 
4 files changed, 52 insertions, 54 deletions
| diff --git a/lib/common/data_reader_dump.c b/lib/common/data_reader_dump.c index 4053f73..4065677 100644 --- a/lib/common/data_reader_dump.c +++ b/lib/common/data_reader_dump.c @@ -12,26 +12,23 @@  #include <stdio.h>  #include <errno.h> -static int append_block(int fd, const sqfs_block_t *blk) +static int append_block(FILE *fp, const sqfs_block_t *blk)  {  	const unsigned char *ptr = blk->data; -	size_t size = blk->size; -	ssize_t ret; +	size_t ret, size = blk->size;  	while (size > 0) { -		ret = write(fd, ptr, size); - -		if (ret < 0) { -			if (errno == EINTR) -				continue; -			perror("writing data block"); +		if (ferror(fp)) { +			fputs("writing data block: error writing to file\n", +			      stderr);  		} -		if (ret == 0) { +		if (feof(fp)) {  			fputs("writing data block: unexpected end of file\n",  			      stderr);  		} +		ret = fwrite(ptr, 1, size, fp);  		ptr += ret;  		size -= ret;  	} @@ -41,7 +38,7 @@ static int append_block(int fd, const sqfs_block_t *blk)  int sqfs_data_reader_dump(const char *name, sqfs_data_reader_t *data,  			  const sqfs_inode_generic_t *inode, -			  int outfd, size_t block_size, bool allow_sparse) +			  FILE *fp, size_t block_size, bool allow_sparse)  {  	sqfs_block_t *blk;  	sqfs_u64 filesz; @@ -50,21 +47,23 @@ int sqfs_data_reader_dump(const char *name, sqfs_data_reader_t *data,  	sqfs_inode_get_file_size(inode, &filesz); -	if (allow_sparse && ftruncate(outfd, filesz)) -		goto fail_sparse; +#if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 200112L) +	if (allow_sparse) { +		int fd = fileno(fp); + +		if (ftruncate(fd, filesz)) +			goto fail_sparse; +	} +#else +	allow_sparse = false; +#endif  	for (i = 0; i < inode->num_file_blocks; ++i) { +		diff = (filesz < block_size) ? filesz : block_size; +  		if (SQFS_IS_SPARSE_BLOCK(inode->block_sizes[i]) &&  		    allow_sparse) { -			if (filesz < block_size) { -				diff = filesz; -				filesz = 0; -			} else { -				diff = block_size; -				filesz -= block_size; -			} - -			if (lseek(outfd, diff, SEEK_CUR) == (off_t)-1) +			if (fseek(fp, diff, SEEK_CUR) < 0)  				goto fail_sparse;  		} else {  			err = sqfs_data_reader_get_block(data, inode, i, &blk); @@ -73,14 +72,14 @@ int sqfs_data_reader_dump(const char *name, sqfs_data_reader_t *data,  				return -1;  			} -			if (append_block(outfd, blk)) { -				free(blk); -				return -1; -			} - -			filesz -= blk->size; +			err = append_block(fp, blk);  			free(blk); + +			if (err) +				return -1;  		} + +		filesz -= diff;  	}  	if (filesz > 0) { @@ -90,7 +89,7 @@ int sqfs_data_reader_dump(const char *name, sqfs_data_reader_t *data,  			return -1;  		} -		if (append_block(outfd, blk)) { +		if (append_block(fp, blk)) {  			free(blk);  			return -1;  		} diff --git a/lib/tar/padd_file.c b/lib/tar/padd_file.c index f58cfbf..dd945a3 100644 --- a/lib/tar/padd_file.c +++ b/lib/tar/padd_file.c @@ -10,7 +10,7 @@  #include <stdlib.h>  #include <stdio.h> -int padd_file(int outfd, sqfs_u64 size) +int padd_file(FILE *fp, sqfs_u64 size)  {  	size_t padd_sz = size % TAR_RECORD_SIZE;  	int status = -1; @@ -26,7 +26,7 @@ int padd_file(int outfd, sqfs_u64 size)  		goto fail_errno;  	if (write_retry("padding output file to block size", -			outfd, buffer, padd_sz)) { +			fp, buffer, padd_sz)) {  		goto out;  	} diff --git a/lib/tar/write_header.c b/lib/tar/write_header.c index 84aa2d3..6626d00 100644 --- a/lib/tar/write_header.c +++ b/lib/tar/write_header.c @@ -53,7 +53,7 @@ static void write_number_signed(char *dst, sqfs_s64 value, int digits)  	}  } -static int write_header(int fd, const struct stat *sb, const char *name, +static int write_header(FILE *fp, const struct stat *sb, const char *name,  			const char *slink_target, int type)  {  	int maj = 0, min = 0; @@ -88,10 +88,10 @@ static int write_header(int fd, const struct stat *sb, const char *name,  	update_checksum(&hdr); -	return write_retry("writing tar header record", fd, &hdr, sizeof(hdr)); +	return write_retry("writing tar header record", fp, &hdr, sizeof(hdr));  } -static int write_gnu_header(int fd, const struct stat *orig, +static int write_gnu_header(FILE *fp, const struct stat *orig,  			    const char *payload, size_t payload_len,  			    int type, const char *name)  { @@ -101,15 +101,15 @@ static int write_gnu_header(int fd, const struct stat *orig,  	sb.st_mode = S_IFREG | 0644;  	sb.st_size = payload_len; -	if (write_header(fd, &sb, name, NULL, type)) +	if (write_header(fp, &sb, name, NULL, type))  		return -1;  	if (write_retry("writing GNU extension header", -			fd, payload, payload_len)) { +			fp, payload, payload_len)) {  		return -1;  	} -	return padd_file(fd, payload_len); +	return padd_file(fp, payload_len);  }  static size_t num_digits(size_t num) @@ -124,7 +124,7 @@ static size_t num_digits(size_t num)  	return i;  } -static int write_schily_xattr(int fd, const struct stat *orig, +static int write_schily_xattr(FILE *fp, const struct stat *orig,  			      const char *name, const tar_xattr_t *xattr)  {  	static const char *prefix = "SCHILY.xattr."; @@ -142,20 +142,20 @@ static int write_schily_xattr(int fd, const struct stat *orig,  	sb.st_mode = S_IFREG | 0644;  	sb.st_size = total_size; -	if (write_header(fd, &sb, name, NULL, TAR_TYPE_PAX)) +	if (write_header(fp, &sb, name, NULL, TAR_TYPE_PAX))  		return -1;  	for (it = xattr; it != NULL; it = it->next) {  		len = strlen(prefix) + strlen(it->key) + strlen(it->value) + 2;  		len += num_digits(len) + 1; -		dprintf(fd, "%zu %s%s=%s\n", len, prefix, it->key, it->value); +		fprintf(fp, "%zu %s%s=%s\n", len, prefix, it->key, it->value);  	} -	return padd_file(fd, total_size); +	return padd_file(fp, total_size);  } -int write_tar_header(int fd, const struct stat *sb, const char *name, +int write_tar_header(FILE *fp, const struct stat *sb, const char *name,  		     const char *slink_target, const tar_xattr_t *xattr,  		     unsigned int counter)  { @@ -166,7 +166,7 @@ int write_tar_header(int fd, const struct stat *sb, const char *name,  	if (xattr != NULL) {  		sprintf(buffer, "pax/xattr%u", counter); -		if (write_schily_xattr(fd, sb, buffer, xattr)) +		if (write_schily_xattr(fp, sb, buffer, xattr))  			return -1;  	} @@ -175,7 +175,7 @@ int write_tar_header(int fd, const struct stat *sb, const char *name,  	if (S_ISLNK(sb->st_mode) && sb->st_size >= 100) {  		sprintf(buffer, "gnu/target%u", counter); -		if (write_gnu_header(fd, sb, slink_target, sb->st_size, +		if (write_gnu_header(fp, sb, slink_target, sb->st_size,  				     TAR_TYPE_GNU_SLINK, buffer))  			return -1;  		slink_target = NULL; @@ -184,7 +184,7 @@ int write_tar_header(int fd, const struct stat *sb, const char *name,  	if (strlen(name) >= 100) {  		sprintf(buffer, "gnu/name%u", counter); -		if (write_gnu_header(fd, sb, name, strlen(name), +		if (write_gnu_header(fp, sb, name, strlen(name),  				     TAR_TYPE_GNU_PATH, buffer)) {  			return -1;  		} @@ -208,7 +208,7 @@ int write_tar_header(int fd, const struct stat *sb, const char *name,  		goto out_skip;  	} -	return write_header(fd, sb, name, slink_target, type); +	return write_header(fp, sb, name, slink_target, type);  out_skip:  	fprintf(stderr, "WARNING: %s: %s\n", name, reason);  	return 1; diff --git a/lib/tar/write_retry.c b/lib/tar/write_retry.c index 1ff1a7e..3977db1 100644 --- a/lib/tar/write_retry.c +++ b/lib/tar/write_retry.c @@ -12,23 +12,22 @@  #include "tar.h" -int write_retry(const char *errstr, int fd, const void *data, size_t size) +int write_retry(const char *errstr, FILE *fp, const void *data, size_t size)  { -	ssize_t ret; +	size_t ret;  	while (size > 0) { -		ret = write(fd, data, size); -		if (ret == 0) { +		if (feof(fp)) {  			fprintf(stderr, "%s: write truncated\n", errstr);  			return -1;  		} -		if (ret < 0) { -			if (errno == EINTR) -				continue; -			perror(errstr); + +		if (ferror(fp)) { +			fprintf(stderr, "%s: error writing to file\n", errstr);  			return -1;  		} +		ret = fwrite(data, 1, size, fp);  		data = (const char *)data + ret;  		size -= ret;  	} | 
