diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2019-06-11 11:33:34 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-06-11 11:33:34 +0200 |
commit | 06b8bc4d708b8ff4eba1dd9b48ec110a8019d2c8 (patch) | |
tree | 3c7c238c81aa91405159959906f31f6195aa6217 /lib | |
parent | b697fba4a5c5395a9db271efa286870191418040 (diff) | |
parent | b917f7864115a35fbb9e69af2c1d553a110a37fc (diff) | |
download | barebox-06b8bc4d708b8ff4eba1dd9b48ec110a8019d2c8.tar.gz barebox-06b8bc4d708b8ff4eba1dd9b48ec110a8019d2c8.tar.xz |
Merge branch 'for-next/misc'
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libbb.c | 14 | ||||
-rw-r--r-- | lib/libfile.c | 18 | ||||
-rw-r--r-- | lib/misc.c | 49 |
3 files changed, 61 insertions, 20 deletions
diff --git a/lib/libbb.c b/lib/libbb.c index 239611c27b..d0c9bf4d80 100644 --- a/lib/libbb.c +++ b/lib/libbb.c @@ -112,17 +112,3 @@ char * safe_strncpy(char *dst, const char *src, size_t size) return strncpy(dst, src, size); } EXPORT_SYMBOL(safe_strncpy); - -char *simple_itoa(unsigned int i) -{ - /* 21 digits plus null terminator, good for 64-bit or smaller ints */ - static char local[22]; - char *p = &local[21]; - *p-- = '\0'; - do { - *p-- = '0' + i % 10; - i /= 10; - } while (i > 0); - return p + 1; -} -EXPORT_SYMBOL(simple_itoa); diff --git a/lib/libfile.c b/lib/libfile.c index eb12d158d8..b42753c2b5 100644 --- a/lib/libfile.c +++ b/lib/libfile.c @@ -36,7 +36,11 @@ int pwrite_full(int fd, const void *buf, size_t size, loff_t offset) while (size) { now = pwrite(fd, buf, size, offset); - if (now <= 0) + if (now == 0) { + errno = ENOSPC; + return -1; + } + if (now < 0) return now; size -= now; buf += now; @@ -60,7 +64,11 @@ int write_full(int fd, const void *buf, size_t size) while (size) { now = write(fd, buf, size); - if (now <= 0) + if (now == 0) { + errno = ENOSPC; + return -1; + } + if (now < 0) return now; size -= now; buf += now; @@ -80,20 +88,18 @@ int read_full(int fd, void *buf, size_t size) { size_t insize = size; int now; - int total = 0; while (size) { now = read(fd, buf, size); if (now == 0) - return total; + break; if (now < 0) return now; - total += now; size -= now; buf += now; } - return insize; + return insize - size; } EXPORT_SYMBOL(read_full); diff --git a/lib/misc.c b/lib/misc.c index cd420a57d8..18153bb4dc 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -24,6 +24,7 @@ #include <string.h> #include <linux/ctype.h> #include <getopt.h> +#include <libfile.h> /* * Like simple_strtoull() but handles an optional G, M, K or k @@ -171,3 +172,51 @@ int mem_parse_options(int argc, char *argv[], char *optstr, int *mode, return 0; } +int memcpy_parse_options(int argc, char *argv[], int *sourcefd, + int *destfd, loff_t *count) +{ + loff_t dest, src; + int mode = 0; + char *sourcefile = NULL; + char *destfile = NULL; + struct stat statbuf; + + if (mem_parse_options(argc, argv, "bwlqs:d:", &mode, &sourcefile, + &destfile, NULL) < 0) + return -EINVAL; + + if (optind + 2 > argc) + return -EINVAL; + + src = strtoull_suffix(argv[optind], NULL, 0); + dest = strtoull_suffix(argv[optind + 1], NULL, 0); + + if (optind + 2 == argc) { + if (!sourcefile) { + printf("source and count not given\n"); + return -EINVAL; + } + if (stat(sourcefile, &statbuf)) { + perror("stat"); + return -1; + } + *count = statbuf.st_size - src; + } else { + *count = strtoull_suffix(argv[optind + 2], NULL, 0); + } + + sourcefile = sourcefile ?: "/dev/mem"; + destfile = destfile ?: "/dev/mem"; + + *sourcefd = open_and_lseek(sourcefile, mode | O_RDONLY, src); + if (*sourcefd < 0) + return -1; + + *destfd = open_and_lseek(destfile, O_WRONLY | O_CREAT | mode, dest); + if (*destfd < 0) { + close(*sourcefd); + return -1; + } + + return 0; +} |