From: Joel Rosdahl Date: Sun, 29 Mar 2015 15:08:37 +0000 (+0200) Subject: Don't assume that succeeding libc calls don't modify errno X-Git-Tag: v3.2.2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1032c0bb24c89bc7d7591fa39aafbce778c433f9;p=thirdparty%2Fccache.git Don't assume that succeeding libc calls don't modify errno --- diff --git a/lockfile.c b/lockfile.c index af4fa43af..f4f2028b7 100644 --- a/lockfile.c +++ b/lockfile.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2014 Joel Rosdahl + * Copyright (C) 2010-2015 Joel Rosdahl * * 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 @@ -31,6 +31,7 @@ bool lockfile_acquire(const char *path, unsigned staleness_limit) { + int saved_errno = 0; char *lockfile = format("%s.lock", path); char *my_content = NULL, *content = NULL, *initial_content = NULL; const char *hostname = get_hostname(); @@ -50,15 +51,16 @@ lockfile_acquire(const char *path, unsigned staleness_limit) #ifdef _WIN32 fd = open(lockfile, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0666); if (fd == -1) { + saved_errno = errno; cc_log("lockfile_acquire: open WRONLY %s: %s", lockfile, strerror(errno)); - if (errno == ENOENT) { + if (saved_errno == ENOENT) { /* Directory doesn't exist? */ if (create_parent_dirs(lockfile) == 0) { /* OK. Retry. */ continue; } } - if (errno != EEXIST) { + if (saved_errno != EEXIST) { /* Directory doesn't exist or isn't writable? */ goto out; } @@ -105,15 +107,16 @@ lockfile_acquire(const char *path, unsigned staleness_limit) acquired = true; goto out; } - cc_log("lockfile_acquire: symlink %s: %s", lockfile, strerror(errno)); - if (errno == ENOENT) { + saved_errno = errno; + cc_log("lockfile_acquire: symlink %s: %s", lockfile, strerror(saved_errno)); + if (saved_errno == ENOENT) { /* Directory doesn't exist? */ if (create_parent_dirs(lockfile) == 0) { /* OK. Retry. */ continue; } } - if (errno == EPERM) { + if (saved_errno == EPERM) { /* * The file system does not support symbolic links. We have no choice but * to grant the lock anyway. @@ -121,7 +124,7 @@ lockfile_acquire(const char *path, unsigned staleness_limit) acquired = true; goto out; } - if (errno != EEXIST) { + if (saved_errno != EEXIST) { /* Directory doesn't exist or isn't writable? */ goto out; } diff --git a/util.c b/util.c index 8b5370510..658cab6a9 100644 --- a/util.c +++ b/util.c @@ -261,7 +261,8 @@ get_umask(void) /* * Copy src to dest, decompressing src if needed. compress_level > 0 decides - * whether dest will be compressed, and with which compression level. + * whether dest will be compressed, and with which compression level. Returns 0 + * on success and -1 on failure. On failure, errno represents the error. */ int copy_file(const char *src, const char *dest, int compress_level) @@ -273,6 +274,7 @@ copy_file(const char *src, const char *dest, int compress_level) char *tmp_name; struct stat st; int errnum; + int saved_errno = 0; /* open destination file */ tmp_name = x_strdup(dest); @@ -283,13 +285,15 @@ copy_file(const char *src, const char *dest, int compress_level) /* open source file */ fd_in = open(src, O_RDONLY | O_BINARY); if (fd_in == -1) { - cc_log("open error: %s", strerror(errno)); + saved_errno = errno; + cc_log("open error: %s", strerror(saved_errno)); goto error; } gz_in = gzdopen(fd_in, "rb"); if (!gz_in) { - cc_log("gzdopen(src) error: %s", strerror(errno)); + saved_errno = errno; + cc_log("gzdopen(src) error: %s", strerror(saved_errno)); close(fd_in); goto error; } @@ -311,7 +315,8 @@ copy_file(const char *src, const char *dest, int compress_level) if (compress_level > 0) { gz_out = gzdopen(dup(fd_out), "wb"); if (!gz_out) { - cc_log("gzdopen(dest) error: %s", strerror(errno)); + saved_errno = errno; + cc_log("gzdopen(dest) error: %s", strerror(saved_errno)); goto error; } gzsetparams(gz_out, compress_level, Z_DEFAULT_STRATEGY); @@ -326,6 +331,7 @@ copy_file(const char *src, const char *dest, int compress_level) do { count = write(fd_out, buf + written, n - written); if (count == -1 && errno != EINTR) { + saved_errno = errno; break; } written += count; @@ -335,9 +341,9 @@ copy_file(const char *src, const char *dest, int compress_level) if (compress_level > 0) { cc_log("gzwrite error: %s (errno: %s)", gzerror(gz_in, &errnum), - strerror(errno)); + strerror(saved_errno)); } else { - cc_log("write error: %s", strerror(errno)); + cc_log("write error: %s", strerror(saved_errno)); } goto error; } @@ -349,8 +355,9 @@ copy_file(const char *src, const char *dest, int compress_level) */ gzerror(gz_in, &errnum); if (!gzeof(gz_in) || (errnum != Z_OK && errnum != Z_STREAM_END)) { + saved_errno = errno; cc_log("gzread error: %s (errno: %s)", - gzerror(gz_in, &errnum), strerror(errno)); + gzerror(gz_in, &errnum), strerror(saved_errno)); gzclose(gz_in); if (gz_out) { gzclose(gz_out); @@ -374,12 +381,14 @@ copy_file(const char *src, const char *dest, int compress_level) /* the close can fail on NFS if out of space */ if (close(fd_out) == -1) { - cc_log("close error: %s", strerror(errno)); + saved_errno = errno; + cc_log("close error: %s", strerror(saved_errno)); goto error; } if (x_rename(tmp_name, dest) == -1) { - cc_log("rename error: %s", strerror(errno)); + saved_errno = errno; + cc_log("rename error: %s", strerror(saved_errno)); goto error; } @@ -399,6 +408,7 @@ error: } tmp_unlink(tmp_name); free(tmp_name); + errno = saved_errno; return -1; } @@ -1488,7 +1498,7 @@ x_unlink(const char *path) */ char *tmp_name = format("%s.rm.%s", path, tmp_string()); int result = 0; - int saved_errno; + int saved_errno = 0; cc_log("Unlink %s via %s", path, tmp_name); if (x_rename(path, tmp_name) == -1) { result = -1; @@ -1507,6 +1517,7 @@ out: if (result) { cc_log("x_unlink failed: %s", strerror(saved_errno)); } + errno = saved_errno; return result; }