diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-08-22 21:35:59 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-08-22 21:35:59 +0000 |
commit | 7c856b66bb161761c8e9ff5b9a71756a2c411f4b (patch) | |
tree | 5d97b6d72a8339555f2a9dd48a1d34c36a0a071b /src/diskio.c | |
parent | 20e08ebe561d4ac2d1e9e26fcf74162b93f8555e (diff) | |
download | wydawca-7c856b66bb161761c8e9ff5b9a71756a2c411f4b.tar.gz wydawca-7c856b66bb161761c8e9ff5b9a71756a2c411f4b.tar.bz2 |
Normalize use of sendfile(2).
* src/wydawca.c (enable_sendfile): New global.
* src/wydawca.h: Likewise.
* src/config.c (enable-sendfile): New statement.
* src/diskio.c (copy_file): Use enable_sendfile to decide whether
to use sendfile.
* doc/wydawca.texi: Document enable-sendfile.
git-svn-id: file:///svnroot/wydawca/trunk@324 6bb4bd81-ecc2-4fd4-a2d4-9571d19c0d33
Diffstat (limited to 'src/diskio.c')
-rw-r--r-- | src/diskio.c | 65 |
1 files changed, 37 insertions, 28 deletions
diff --git a/src/diskio.c b/src/diskio.c index 832b329..43191bb 100644 --- a/src/diskio.c +++ b/src/diskio.c @@ -144,7 +144,7 @@ copy_file (const char *file, const char *dst_file, uid_t uid, gid_t gid) { int in_fd, out_fd; struct stat st; - int rc = 1; + enum { copy_ok, copy_fallback, copy_failed } rc = copy_fallback; in_fd = open (file, O_RDONLY); @@ -173,27 +173,33 @@ copy_file (const char *file, const char *dst_file, uid_t uid, gid_t gid) } #ifdef USE_SENDFILE - { - off_t offset = 0; - ssize_t count; + if (enable_sendfile) + { + off_t offset = 0; + ssize_t count; - count = sendfile (out_fd, in_fd, &offset, st.st_size); - if (count == -1) - { - rc = 1; - logmsg (LOG_ERR, "copying %s to %s failed: %s", - file, dst_file, strerror (errno)); - } - else if (count < st.st_size) - { - rc = 1; - logmsg (LOG_ERR, "copying %s to %s failed: short write", - file, dst_file); - } - else - rc = 0; - } - if (rc && errno == EINVAL) + count = sendfile (out_fd, in_fd, &offset, st.st_size); + if (count == -1) + { + if (errno == EINVAL || errno == ENOSYS) + rc = copy_fallback; + else + rc = copy_failed; + logmsg ((rc == copy_fallback) ? LOG_WARNING : LOG_ERR, + "sendfile: copying %s to %s failed: %s", + file, dst_file, strerror (errno)); + } + else if (count < st.st_size) + { + rc = copy_failed; + logmsg (LOG_ERR, "copying %s to %s failed: short write", + file, dst_file); + } + else + rc = copy_ok; + } + + if (rc == copy_fallback) #endif { char *buf = NULL; @@ -206,7 +212,7 @@ copy_file (const char *file, const char *dst_file, uid_t uid, gid_t gid) if (bufsize == 0) xalloc_die (); - rc = 0; + rc = copy_ok; while (fsize > 0) { size_t rest; @@ -218,7 +224,7 @@ copy_file (const char *file, const char *dst_file, uid_t uid, gid_t gid) { logmsg (LOG_ERR, "unexpected error reading %s: %s", file, strerror (errno)); - rc = 1; + rc = copy_failed; break; } rest = write (out_fd, buf, rdbytes); @@ -226,13 +232,13 @@ copy_file (const char *file, const char *dst_file, uid_t uid, gid_t gid) { logmsg (LOG_ERR, "unexpected error writing to %s: %s", dst_file, strerror (errno)); - rc = 1; + rc = copy_failed; break; } else if (rest != rdbytes) { logmsg (LOG_ERR, "short write on %s", dst_file); - rc = 1; + rc = copy_failed; } fsize -= rdbytes; } @@ -241,9 +247,12 @@ copy_file (const char *file, const char *dst_file, uid_t uid, gid_t gid) close (in_fd); close (out_fd); - if (rc) - unlink (dst_file); - return rc; + if (rc != copy_ok) + { + unlink (dst_file); + return 1; + } + return 0; } /* Move FILE to DST_FILE. If they reside on different devices, use copy_file |