Merge "libsparse: output_file.c, fix large data chunk issue" am: 62c9101646

am: faaeda8e12

Change-Id: I167d7d8083e8e15f89f21b5838fc5b4e97121b10
This commit is contained in:
Colin Cross 2016-10-07 17:24:00 +00:00 committed by android-build-merger
commit 4179f2ec65

View file

@ -63,7 +63,7 @@ struct output_file_ops {
int (*open)(struct output_file *, int fd); int (*open)(struct output_file *, int fd);
int (*skip)(struct output_file *, int64_t); int (*skip)(struct output_file *, int64_t);
int (*pad)(struct output_file *, int64_t); int (*pad)(struct output_file *, int64_t);
int (*write)(struct output_file *, void *, int); int (*write)(struct output_file *, void *, size_t);
void (*close)(struct output_file *); void (*close)(struct output_file *);
}; };
@ -149,18 +149,23 @@ static int file_pad(struct output_file *out, int64_t len)
return 0; return 0;
} }
static int file_write(struct output_file *out, void *data, int len) static int file_write(struct output_file *out, void *data, size_t len)
{ {
int ret; ssize_t ret;
struct output_file_normal *outn = to_output_file_normal(out); struct output_file_normal *outn = to_output_file_normal(out);
ret = write(outn->fd, data, len); while (len > 0) {
if (ret < 0) { ret = write(outn->fd, data, len);
error_errno("write"); if (ret < 0) {
return -1; if (errno == EINTR) {
} else if (ret < len) { continue;
error("incomplete write"); }
return -1; error_errno("write");
return -1;
}
data = (char *)data + ret;
len -= ret;
} }
return 0; return 0;
@ -232,18 +237,20 @@ static int gz_file_pad(struct output_file *out, int64_t len)
return 0; return 0;
} }
static int gz_file_write(struct output_file *out, void *data, int len) static int gz_file_write(struct output_file *out, void *data, size_t len)
{ {
int ret; int ret;
struct output_file_gz *outgz = to_output_file_gz(out); struct output_file_gz *outgz = to_output_file_gz(out);
ret = gzwrite(outgz->gz_fd, data, len); while (len > 0) {
if (ret < 0) { ret = gzwrite(outgz->gz_fd, data,
error_errno("gzwrite"); min(len, (unsigned int)INT_MAX));
return -1; if (ret == 0) {
} else if (ret < len) { error("gzwrite %s", gzerror(outgz->gz_fd, NULL));
error("incomplete gzwrite"); return -1;
return -1; }
len -= ret;
data = (char *)data + ret;
} }
return 0; return 0;
@ -293,7 +300,7 @@ static int callback_file_pad(struct output_file *out __unused, int64_t len __unu
return -1; return -1;
} }
static int callback_file_write(struct output_file *out, void *data, int len) static int callback_file_write(struct output_file *out, void *data, size_t len)
{ {
struct output_file_callback *outc = to_output_file_callback(out); struct output_file_callback *outc = to_output_file_callback(out);
@ -698,14 +705,16 @@ int write_fd_chunk(struct output_file *out, unsigned int len,
int ret; int ret;
int64_t aligned_offset; int64_t aligned_offset;
int aligned_diff; int aligned_diff;
int buffer_size; uint64_t buffer_size;
char *ptr; char *ptr;
aligned_offset = offset & ~(4096 - 1); aligned_offset = offset & ~(4096 - 1);
aligned_diff = offset - aligned_offset; aligned_diff = offset - aligned_offset;
buffer_size = len + aligned_diff; buffer_size = (uint64_t)len + (uint64_t)aligned_diff;
#ifndef _WIN32 #ifndef _WIN32
if (buffer_size > SIZE_MAX)
return -E2BIG;
char *data = mmap64(NULL, buffer_size, PROT_READ, MAP_SHARED, fd, char *data = mmap64(NULL, buffer_size, PROT_READ, MAP_SHARED, fd,
aligned_offset); aligned_offset);
if (data == MAP_FAILED) { if (data == MAP_FAILED) {