aboutsummaryrefslogtreecommitdiffstats
path: root/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'common.c')
-rw-r--r--common.c53
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);
+ }
+ }
+}