aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Dowad <alexinbeijing@gmail.com>2015-05-19 20:15:15 +0200
committerTimo Teräs <timo.teras@iki.fi>2015-05-26 08:38:45 +0300
commit4c3712ecb443a141227265ecc4394104a1b15801 (patch)
treec0ce3c848bccec0220558e390bc5b45cf18c9c33
parentc6d273fc34605ed5655a36fda2e35d0a2d85969b (diff)
downloadaports-4c3712ecb443a141227265ecc4394104a1b15801.tar.bz2
aports-4c3712ecb443a141227265ecc4394104a1b15801.tar.xz
detect failures in writing to file during final flush of buffers
In practice this should fix to e.g. not wipe out /etc/apk/world if final flush to /etc/apk/world.new fails. This was prompted by an incident the other day where I ran the root partition of an Alpine box out of space using 'apk add', and apk helpfully wiped the contents of /etc/apk/world at the same time. It might be tricky to try to reproduce exactly the same failure, but from an examination of the code, setting 'rc' before the final call to fdo_flush rather than after is one possible cause of this behavior. (If the entire contents of /etc/apk/world.new are buffered, and all get written out in the final fdo_flush call, and that call fails, fdo_close will still happily rename /etc/apk/world.new to /etc/apk/world.)
-rw-r--r--src/io.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/src/io.c b/src/io.c
index da26a57de4..136153cb14 100644
--- a/src/io.c
+++ b/src/io.c
@@ -778,9 +778,11 @@ static int fdo_close(void *stream)
{
struct apk_fd_ostream *fos =
container_of(stream, struct apk_fd_ostream, os);
- int rc = fos->rc;
+ int rc;
fdo_flush(fos);
+ rc = fos->rc;
+
if (fos->fd > STDERR_FILENO &&
close(fos->fd) < 0)
rc = -errno;