summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2019-06-11 11:33:34 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2019-06-11 11:33:34 +0200
commit06b8bc4d708b8ff4eba1dd9b48ec110a8019d2c8 (patch)
tree3c7c238c81aa91405159959906f31f6195aa6217 /lib
parentb697fba4a5c5395a9db271efa286870191418040 (diff)
parentb917f7864115a35fbb9e69af2c1d553a110a37fc (diff)
downloadbarebox-06b8bc4d708b8ff4eba1dd9b48ec110a8019d2c8.tar.gz
barebox-06b8bc4d708b8ff4eba1dd9b48ec110a8019d2c8.tar.xz
Merge branch 'for-next/misc'
Diffstat (limited to 'lib')
-rw-r--r--lib/libbb.c14
-rw-r--r--lib/libfile.c18
-rw-r--r--lib/misc.c49
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;
+}