diff options
Diffstat (limited to 'ubi-utils/src/libubi_sysfs.c')
-rw-r--r-- | ubi-utils/src/libubi_sysfs.c | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/ubi-utils/src/libubi_sysfs.c b/ubi-utils/src/libubi_sysfs.c new file mode 100644 index 0000000..95fd3de --- /dev/null +++ b/ubi-utils/src/libubi_sysfs.c @@ -0,0 +1,232 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * UBI (Unsorted Block Images) library. + * + * Author: Artem B. Bityutskiy + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <unistd.h> +#include <limits.h> +#include <errno.h> +#include <stdarg.h> + +#include "config.h" +#include "libubi_int.h" + +int +sysfs_read_data(const char *file, void *buf, int len) +{ + int fd; + ssize_t rd; + + fd = open(file, O_RDONLY); + if (fd == -1) { + ubi_err("cannot open file %s", file); + return -1; + } + + rd = read(fd, buf, len); + if (rd == -1) + ubi_err("cannot read file %s", file); + + close(fd); + + return rd; +} + +int +sysfs_read_data_subst(const char *patt, void *buf, int len, int n, ...) +{ + va_list args; + char buf1[strlen(patt) + 20 * n]; + + va_start(args, n); + vsprintf(&buf1[0], patt, args); + va_end(args); + + return sysfs_read_data(&buf1[0], buf, len); +} + +int +sysfs_read_dev(const char *file, unsigned int *major, unsigned int *minor) +{ + int fd; + int ret; + ssize_t rd; + int err = -1; + char buf[40]; + + fd = open(file, O_RDONLY); + if (fd == -1) { + ubi_err("cannot open file %s", file); + return -1; + } + + rd = read(fd, &buf[0], 20); + if (rd == -1) { + ubi_err("cannot read file %s", file); + goto error; + } + if (rd < 4) { + ubi_err("bad contents of file %s:", file); + goto error; + } + + err = -1; + if (buf[rd -1] != '\n') { + ubi_err("bad contents of file %s", file); + goto error; + } + + ret = sscanf(&buf[0], "%d:%d\n", major, minor); + if (ret != 2) { + ubi_err("bad contents of file %s", file); + goto error; + } + + err = 0; + +error: + close(fd); + + return err; +} + +int +sysfs_read_dev_subst(const char *patt, unsigned int *major, + unsigned int *minor, int n, ...) +{ + va_list args; + char buf[strlen(patt) + 20 * n]; + + va_start(args, n); + vsprintf(&buf[0], patt, args); + va_end(args); + + return sysfs_read_dev(&buf[0], major, minor); +} + +static int +sysfs_read_ull(const char *file __unused, unsigned long long *num __unused) +{ + return 0; +} + +int +sysfs_read_ull_subst(const char *patt, unsigned long long *num, int n, ...) +{ + va_list args; + char buf[strlen(patt) + 20 * n]; + + va_start(args, n); + vsprintf(&buf[0], patt, args); + va_end(args); + + return sysfs_read_ull(&buf[0], num); +} + +static int +sysfs_read_uint(const char *file __unused, unsigned int *num __unused) +{ + return 0; +} + +int +sysfs_read_uint_subst(const char *patt, unsigned int *num, int n, ...) +{ + va_list args; + char buf[strlen(patt) + 20 * n]; + + va_start(args, n); + vsprintf(&buf[0], patt, args); + va_end(args); + + return sysfs_read_uint(&buf[0], num); +} + +int +sysfs_read_ll(const char *file, long long *num) +{ + int fd; + ssize_t rd; + int err = -1; + char buf[20]; + char *endptr; + + fd = open(file, O_RDONLY); + if (fd == -1) + return -1; + + rd = read(fd, &buf[0], 20); + if (rd == -1) + goto out; + + if (rd < 2) { + ubi_err("bad contents in file %s: \"%c%c...\"", + file, buf[0], buf[1]); + goto out_errno; + } + + *num = strtoll(&buf[0], &endptr, 10); + if (endptr == &buf[0] || *endptr != '\n') { + ubi_err("bad contents in file %s: \"%c%c...\"", + file, buf[0], buf[1]); + goto out_errno; + } + + if (*num < 0) { + ubi_err("bad number in file %s: %lld", file, *num); + goto out_errno; + } + + err = 0; + +out_errno: + errno = EINVAL; + +out: + close(fd); + return err; +} + +int +sysfs_read_int(const char *file, int *num) +{ + int err; + long long res = 0; + + err = sysfs_read_ll(file, &res); + if (err) + return err; + + if (res < 0 || res > INT_MAX) { + ubi_err("bad number in file %s: %lld", file, res); + errno = EINVAL; + return -1; + } + + *num = res; + return 0; +} |