From a382e2bdb22b5b68d83f32c6c339465b2e8f6e46 Mon Sep 17 00:00:00 2001 From: Yabin Cui Date: Fri, 2 Jan 2015 14:00:13 -0800 Subject: Use getmntent when accessing /proc/mounts. Bug: 18887435 Change-Id: Ice44c14fc8ee79eab259caf486e123b6af21ceb0 --- mtdutils/mounts.c | 89 +++++++++---------------------------------------------- 1 file changed, 14 insertions(+), 75 deletions(-) (limited to 'mtdutils') diff --git a/mtdutils/mounts.c b/mtdutils/mounts.c index c90fc8acf..6a9b03d30 100644 --- a/mtdutils/mounts.c +++ b/mtdutils/mounts.c @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include #include @@ -59,10 +60,8 @@ free_volume_internals(const MountedVolume *volume, int zero) int scan_mounted_volumes() { - char buf[2048]; - const char *bufp; - int fd; - ssize_t nbytes; + FILE* fp; + struct mntent* mentry; if (g_mounts_state.volumes == NULL) { const int numv = 32; @@ -84,80 +83,20 @@ scan_mounted_volumes() } g_mounts_state.volume_count = 0; - /* Open and read the file contents. - */ - fd = open(PROC_MOUNTS_FILENAME, O_RDONLY); - if (fd < 0) { - goto bail; - } - nbytes = read(fd, buf, sizeof(buf) - 1); - close(fd); - if (nbytes < 0) { - goto bail; + /* Open and read mount table entries. */ + fp = setmntent(PROC_MOUNTS_FILENAME, "r"); + if (fp == NULL) { + return -1; } - buf[nbytes] = '\0'; - - /* Parse the contents of the file, which looks like: - * - * # cat /proc/mounts - * rootfs / rootfs rw 0 0 - * /dev/pts /dev/pts devpts rw 0 0 - * /proc /proc proc rw 0 0 - * /sys /sys sysfs rw 0 0 - * /dev/block/mtdblock4 /system yaffs2 rw,nodev,noatime,nodiratime 0 0 - * /dev/block/mtdblock5 /data yaffs2 rw,nodev,noatime,nodiratime 0 0 - * /dev/block/mmcblk0p1 /sdcard vfat rw,sync,dirsync,fmask=0000,dmask=0000,codepage=cp437,iocharset=iso8859-1,utf8 0 0 - * - * The zeroes at the end are dummy placeholder fields to make the - * output match Linux's /etc/mtab, but don't represent anything here. - */ - bufp = buf; - while (nbytes > 0) { - char device[64]; - char mount_point[64]; - char filesystem[64]; - char flags[128]; - int matches; - - /* %as is a gnu extension that malloc()s a string for each field. - */ - matches = sscanf(bufp, "%63s %63s %63s %127s", - device, mount_point, filesystem, flags); - - if (matches == 4) { - device[sizeof(device)-1] = '\0'; - mount_point[sizeof(mount_point)-1] = '\0'; - filesystem[sizeof(filesystem)-1] = '\0'; - flags[sizeof(flags)-1] = '\0'; - - MountedVolume *v = - &g_mounts_state.volumes[g_mounts_state.volume_count++]; - v->device = strdup(device); - v->mount_point = strdup(mount_point); - v->filesystem = strdup(filesystem); - v->flags = strdup(flags); - } else { -printf("matches was %d on <<%.40s>>\n", matches, bufp); - } - - /* Eat the line. - */ - while (nbytes > 0 && *bufp != '\n') { - bufp++; - nbytes--; - } - if (nbytes > 0) { - bufp++; - nbytes--; - } + while ((mentry = getmntent(fp)) != NULL) { + MountedVolume* v = &g_mounts_state.volumes[g_mounts_state.volume_count++]; + v->device = strdup(mentry->mnt_fsname); + v->mount_point = strdup(mentry->mnt_dir); + v->filesystem = strdup(mentry->mnt_type); + v->flags = strdup(mentry->mnt_opts); } - + endmntent(fp); return 0; - -bail: -//TODO: free the strings we've allocated. - g_mounts_state.volume_count = 0; - return -1; } const MountedVolume * -- cgit v1.2.3 From 1fdd452f47299be60cac9acbd8e7c864d9c174bd Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Mon, 23 Mar 2015 13:33:57 -0700 Subject: Always use strerror to report errno in recovery. Change-Id: I7009959043150fabf5853a43ee2448c7fbea176e --- mtdutils/mtdutils.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'mtdutils') diff --git a/mtdutils/mtdutils.c b/mtdutils/mtdutils.c index d04b26efa..9a17e38d8 100644 --- a/mtdutils/mtdutils.c +++ b/mtdutils/mtdutils.c @@ -313,8 +313,8 @@ static int read_block(const MtdPartition *partition, int fd, char *data) memcpy(&before, &after, sizeof(struct mtd_ecc_stats)); } else if ((mgbb = ioctl(fd, MEMGETBADBLOCK, &pos))) { fprintf(stderr, - "mtd: MEMGETBADBLOCK returned %d at 0x%08llx (errno=%d)\n", - mgbb, pos, errno); + "mtd: MEMGETBADBLOCK returned %d at 0x%08llx: %s\n", + mgbb, pos, strerror(errno)); } else { return 0; // Success! } @@ -419,8 +419,8 @@ static int write_block(MtdWriteContext *ctx, const char *data) if (ret != 0 && !(ret == -1 && errno == EOPNOTSUPP)) { add_bad_block_offset(ctx, pos); fprintf(stderr, - "mtd: not writing bad block at 0x%08lx (ret %d errno %d)\n", - pos, ret, errno); + "mtd: not writing bad block at 0x%08lx (ret %d): %s\n", + pos, ret, strerror(errno)); pos += partition->erase_size; continue; // Don't try to erase known factory-bad blocks. } -- cgit v1.2.3 From 2f5feedf1d705b53e5bf90c8b5207dd91f4522f1 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 28 Apr 2015 17:24:24 -0700 Subject: Check all lseek calls succeed. Also add missing TEMP_FAILURE_RETRYs on read, write, and lseek. Bug: http://b/20625546 Change-Id: I03b198e11c1921b35518ee2dd005a7cfcf4fd94b (cherry picked from commit 7bad7c4646ee8fd8d6e6ed0ffd3ddbb0c1b41a2f) --- mtdutils/flash_image.c | 8 ++++---- mtdutils/mtdutils.c | 54 ++++++++++++++++++++------------------------------ mtdutils/mtdutils.h | 2 -- 3 files changed, 26 insertions(+), 38 deletions(-) (limited to 'mtdutils') diff --git a/mtdutils/flash_image.c b/mtdutils/flash_image.c index 5657dfc82..36ffa1314 100644 --- a/mtdutils/flash_image.c +++ b/mtdutils/flash_image.c @@ -72,7 +72,7 @@ int main(int argc, char **argv) { if (fd < 0) die("error opening %s", argv[2]); char header[HEADER_SIZE]; - int headerlen = read(fd, header, sizeof(header)); + int headerlen = TEMP_FAILURE_RETRY(read(fd, header, sizeof(header))); if (headerlen <= 0) die("error reading %s header", argv[2]); MtdReadContext *in = mtd_read_partition(partition); @@ -104,7 +104,7 @@ int main(int argc, char **argv) { if (wrote != headerlen) die("error writing %s", argv[1]); int len; - while ((len = read(fd, buf, sizeof(buf))) > 0) { + while ((len = TEMP_FAILURE_RETRY(read(fd, buf, sizeof(buf)))) > 0) { wrote = mtd_write_data(out, buf, len); if (wrote != len) die("error writing %s", argv[1]); } @@ -125,13 +125,13 @@ int main(int argc, char **argv) { if (mtd_partition_info(partition, NULL, &block_size, NULL)) die("error getting %s block size", argv[1]); - if (lseek(fd, headerlen, SEEK_SET) != headerlen) + if (TEMP_FAILURE_RETRY(lseek(fd, headerlen, SEEK_SET)) != headerlen) die("error rewinding %s", argv[2]); int left = block_size - headerlen; while (left < 0) left += block_size; while (left > 0) { - len = read(fd, buf, left > (int)sizeof(buf) ? (int)sizeof(buf) : left); + len = TEMP_FAILURE_RETRY(read(fd, buf, left > (int)sizeof(buf) ? (int)sizeof(buf) : left)); if (len <= 0) die("error reading %s", argv[2]); if (mtd_write_data(out, buf, len) != len) die("error writing %s", argv[1]); diff --git a/mtdutils/mtdutils.c b/mtdutils/mtdutils.c index 9a17e38d8..cc3033444 100644 --- a/mtdutils/mtdutils.c +++ b/mtdutils/mtdutils.c @@ -108,7 +108,7 @@ mtd_scan_partitions() if (fd < 0) { goto bail; } - nbytes = read(fd, buf, sizeof(buf) - 1); + nbytes = TEMP_FAILURE_RETRY(read(fd, buf, sizeof(buf) - 1)); close(fd); if (nbytes < 0) { goto bail; @@ -279,12 +279,6 @@ MtdReadContext *mtd_read_partition(const MtdPartition *partition) return ctx; } -// Seeks to a location in the partition. Don't mix with reads of -// anything other than whole blocks; unpredictable things will result. -void mtd_read_skip_to(const MtdReadContext* ctx, size_t offset) { - lseek64(ctx->fd, offset, SEEK_SET); -} - static int read_block(const MtdPartition *partition, int fd, char *data) { struct mtd_ecc_stats before, after; @@ -293,13 +287,18 @@ static int read_block(const MtdPartition *partition, int fd, char *data) return -1; } - loff_t pos = lseek64(fd, 0, SEEK_CUR); + loff_t pos = TEMP_FAILURE_RETRY(lseek64(fd, 0, SEEK_CUR)); + if (pos == -1) { + printf("mtd: read_block: couldn't SEEK_CUR: %s\n", strerror(errno)); + return -1; + } ssize_t size = partition->erase_size; int mgbb; while (pos + size <= (int) partition->size) { - if (lseek64(fd, pos, SEEK_SET) != pos || read(fd, data, size) != size) { + if (TEMP_FAILURE_RETRY(lseek64(fd, pos, SEEK_SET)) != pos || + TEMP_FAILURE_RETRY(read(fd, data, size)) != size) { printf("mtd: read error at 0x%08llx (%s)\n", pos, strerror(errno)); } else if (ioctl(fd, ECCGETSTATS, &after)) { @@ -409,8 +408,11 @@ static int write_block(MtdWriteContext *ctx, const char *data) const MtdPartition *partition = ctx->partition; int fd = ctx->fd; - off_t pos = lseek(fd, 0, SEEK_CUR); - if (pos == (off_t) -1) return 1; + off_t pos = TEMP_FAILURE_RETRY(lseek(fd, 0, SEEK_CUR)); + if (pos == (off_t) -1) { + printf("mtd: write_block: couldn't SEEK_CUR: %s\n", strerror(errno)); + return -1; + } ssize_t size = partition->erase_size; while (pos + size <= (int) partition->size) { @@ -435,15 +437,15 @@ static int write_block(MtdWriteContext *ctx, const char *data) pos, strerror(errno)); continue; } - if (lseek(fd, pos, SEEK_SET) != pos || - write(fd, data, size) != size) { + if (TEMP_FAILURE_RETRY(lseek(fd, pos, SEEK_SET)) != pos || + TEMP_FAILURE_RETRY(write(fd, data, size)) != size) { printf("mtd: write error at 0x%08lx (%s)\n", pos, strerror(errno)); } char verify[size]; - if (lseek(fd, pos, SEEK_SET) != pos || - read(fd, verify, size) != size) { + if (TEMP_FAILURE_RETRY(lseek(fd, pos, SEEK_SET)) != pos || + TEMP_FAILURE_RETRY(read(fd, verify, size)) != size) { printf("mtd: re-read error at 0x%08lx (%s)\n", pos, strerror(errno)); continue; @@ -512,8 +514,11 @@ off_t mtd_erase_blocks(MtdWriteContext *ctx, int blocks) ctx->stored = 0; } - off_t pos = lseek(ctx->fd, 0, SEEK_CUR); - if ((off_t) pos == (off_t) -1) return pos; + off_t pos = TEMP_FAILURE_RETRY(lseek(ctx->fd, 0, SEEK_CUR)); + if ((off_t) pos == (off_t) -1) { + printf("mtd_erase_blocks: couldn't SEEK_CUR: %s\n", strerror(errno)); + return -1; + } const int total = (ctx->partition->size - pos) / ctx->partition->erase_size; if (blocks < 0) blocks = total; @@ -554,18 +559,3 @@ int mtd_write_close(MtdWriteContext *ctx) free(ctx); return r; } - -/* Return the offset of the first good block at or after pos (which - * might be pos itself). - */ -off_t mtd_find_write_start(MtdWriteContext *ctx, off_t pos) { - int i; - for (i = 0; i < ctx->bad_block_count; ++i) { - if (ctx->bad_block_offsets[i] == pos) { - pos += ctx->partition->erase_size; - } else if (ctx->bad_block_offsets[i] > pos) { - return pos; - } - } - return pos; -} diff --git a/mtdutils/mtdutils.h b/mtdutils/mtdutils.h index 2708c4318..8059d6a4d 100644 --- a/mtdutils/mtdutils.h +++ b/mtdutils/mtdutils.h @@ -49,12 +49,10 @@ typedef struct MtdWriteContext MtdWriteContext; MtdReadContext *mtd_read_partition(const MtdPartition *); ssize_t mtd_read_data(MtdReadContext *, char *data, size_t data_len); void mtd_read_close(MtdReadContext *); -void mtd_read_skip_to(const MtdReadContext *, size_t offset); MtdWriteContext *mtd_write_partition(const MtdPartition *); ssize_t mtd_write_data(MtdWriteContext *, const char *data, size_t data_len); off_t mtd_erase_blocks(MtdWriteContext *, int blocks); /* 0 ok, -1 for all */ -off_t mtd_find_write_start(MtdWriteContext *ctx, off_t pos); int mtd_write_close(MtdWriteContext *); #ifdef __cplusplus -- cgit v1.2.3