summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2014-12-01 20:43:19 -0500
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2014-12-09 21:36:08 -0500
commit553acb7b6b8d4f16a4747b1f978e8b7888fbfb2c (patch)
treeb9a473c853c616b256ed3ea1dc5f8e9c7838b289 /src/shared
parentcb01aedc3b4ba70859267159fe716253e3551ec6 (diff)
treewide: sanitize loop_write
loop_write() didn't follow the usual systemd rules and returned status partially in errno and required extensive checks from callers. Some of the callers dealt with this properly, but many did not, treating partial writes as successful. Simplify things by conforming to usual rules.
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/copy.c11
-rw-r--r--src/shared/util.c9
-rw-r--r--src/shared/util.h2
3 files changed, 11 insertions, 11 deletions
diff --git a/src/shared/copy.c b/src/shared/copy.c
index abb7fbc52b..b8b1ba1866 100644
--- a/src/shared/copy.c
+++ b/src/shared/copy.c
@@ -63,7 +63,7 @@ int copy_bytes(int fdf, int fdt, off_t max_bytes) {
/* As a fallback just copy bits by hand */
{
char buf[m];
- ssize_t k;
+ int r;
n = read(fdf, buf, m);
if (n < 0)
@@ -71,12 +71,9 @@ int copy_bytes(int fdf, int fdt, off_t max_bytes) {
if (n == 0) /* EOF */
break;
- errno = 0;
- k = loop_write(fdt, buf, n, false);
- if (k < 0)
- return k;
- if (k != n)
- return errno ? -errno : -EIO;
+ r = loop_write(fdt, buf, n, false);
+ if (r < 0)
+ return r;
}
diff --git a/src/shared/util.c b/src/shared/util.c
index ff8835b72d..26a4f72b43 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -2292,13 +2292,15 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
return n;
}
-ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
+int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
const uint8_t *p = buf;
ssize_t n = 0;
assert(fd >= 0);
assert(buf);
+ errno = 0;
+
while (nbytes > 0) {
ssize_t k;
@@ -2317,14 +2319,15 @@ ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
}
if (k <= 0)
- return n > 0 ? n : (k < 0 ? -errno : 0);
+ /* We were not done yet, and a write error occured. */
+ return errno ? -errno : -EIO;
p += k;
nbytes -= k;
n += k;
}
- return n;
+ return 0;
}
int parse_size(const char *t, off_t base, off_t *size) {
diff --git a/src/shared/util.h b/src/shared/util.h
index 61094cca2f..73bd9012fd 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -425,7 +425,7 @@ int sigaction_many(const struct sigaction *sa, ...);
int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
-ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
+int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
bool is_device_path(const char *path);