diff options
Diffstat (limited to 'common.c')
-rw-r--r-- | common.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/common.c b/common.c new file mode 100644 index 0000000..5379f89 --- /dev/null +++ b/common.c @@ -0,0 +1,53 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +void +copy_file(int destfd, const char *destfname, int srcfd, const char *srcfname, int *okp) +{ + char buf[BUFSIZ]; + ssize_t r, w, p, ok_off; + size_t read_off; + + if (okp) { + *okp = 0; + ok_off = 1; + read_off = 0; + } else { + ok_off = 0; + read_off = 1; + buf[0] = 0; + } + + for (;;) { + r = read(srcfd, &buf[read_off], sizeof(buf) - read_off); + if (r <= 0) { + if (!r) + break; + fprintf(stderr, "%s: read %s: %s", argv0, srcfname, strerror(errno)); + exit(1); + } + + if (r == ok_off) { /* Only possible if okp != NULL */ + *okp = 1; + break; + } + + r += (ssize_t)read_off; + for (p = ok_off; p < r; p += w) { + w = write(destfd, buf, (size_t)(r - p)); + if (r <= 0) { + fprintf(stderr, "%s: write %s: %s", argv0, destfname, strerror(errno)); + exit(1); + } + } + } + + if (!okp) { + w = write(destfd, buf, 1); + if (r <= 0) { + fprintf(stderr, "%s: write %s: %s", argv0, destfname, strerror(errno)); + exit(1); + } + } +} |