summaryrefslogtreecommitdiffstats
path: root/src/tools/files.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/files.c')
-rw-r--r--src/tools/files.c55
1 files changed, 36 insertions, 19 deletions
diff --git a/src/tools/files.c b/src/tools/files.c
index b3b516ea..27ebf72d 100644
--- a/src/tools/files.c
+++ b/src/tools/files.c
@@ -402,7 +402,7 @@ static int copy_file(const char *src,
int ifd = -1;
int ofd = -1;
char buf[1024];
- ssize_t cnt, written, offset;
+ ssize_t cnt, written, res;
struct stat fstatbuf;
ifd = open(src, O_RDONLY);
@@ -454,27 +454,44 @@ static int copy_file(const char *src,
goto fail;
}
- while ((cnt = read(ifd, buf, sizeof(buf))) > 0) {
- offset = 0;
- while (cnt > 0) {
- written = write(ofd, buf+offset, (size_t)cnt);
- if (written == -1) {
- ret = errno;
- DEBUG(1, ("Cannot write() to source file '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- goto fail;
+ while ((cnt = read(ifd, buf, sizeof(buf))) != 0) {
+ if (cnt == -1) {
+ if (errno == EINTR || errno == EAGAIN) {
+ continue;
}
- offset += written;
- cnt -= written;
+
+ DEBUG(1, ("Cannot read() from source file '%s': [%d][%s].\n",
+ src, ret, strerror(ret)));
+ goto fail;
+ }
+ else if (cnt > 0) {
+ /* Copy the buffer to the new file */
+ written = 0;
+ while (written < cnt) {
+ res = write(ofd, buf+written, (size_t)cnt-written);
+ if (res == -1) {
+ ret = errno;
+ if (ret == EINTR || ret == EAGAIN) {
+ /* retry the write */
+ continue;
+ }
+ DEBUG(1, ("Cannot write() to destination file '%s': [%d][%s].\n",
+ dst, ret, strerror(ret)));
+ goto fail;
+ }
+ else if (res <= 0) {
+ DEBUG(1, ("Unexpected result from write(): [%d]\n", res));
+ goto fail;
+ }
+
+ written += res;
+ }
+ }
+ else {
+ DEBUG(1, ("Unexpected return code of read [%d]\n", cnt));
+ goto fail;
}
}
- if (cnt == -1) {
- ret = errno;
- DEBUG(1, ("Cannot read() from source file '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- goto fail;
- }
-
ret = close(ifd);
ifd = -1;