2 * file_io.c - Helper functions for reading and writing to file descriptors.
6 * Copyright (C) 2013 Eric Biggers
8 * This file is part of wimlib, a library for working with WIM files.
10 * wimlib is free software; you can redistribute it and/or modify it under the
11 * terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 3 of the License, or (at your option)
15 * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
16 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
17 * A PARTICULAR PURPOSE. See the GNU General Public License for more
20 * You should have received a copy of the GNU General Public License
21 * along with wimlib; if not, see http://www.gnu.org/licenses/.
28 #include "wimlib/file_io.h"
30 # include "wimlib/win32.h" /* For pread(), pwrite() replacements */
32 # include <sys/uio.h> /* for writev() and `struct iovec' */
39 /* Like read(), but keep trying until everything has been written or we know for
40 * sure that there was an error (or end-of-file). */
42 full_read(int fd, void *buf, size_t count)
45 size_t bytes_remaining;
47 for (bytes_remaining = count;
49 bytes_remaining -= bytes_read, buf += bytes_read)
51 bytes_read = read(fd, buf, bytes_remaining);
52 if (bytes_read <= 0) {
55 else if (errno == EINTR)
60 return count - bytes_remaining;
63 /* Like write(), but keep trying until everything has been written or we know
64 * for sure that there was an error. */
66 full_write(int fd, const void *buf, size_t count)
68 ssize_t bytes_written;
69 size_t bytes_remaining;
71 for (bytes_remaining = count;
73 bytes_remaining -= bytes_written, buf += bytes_written)
75 bytes_written = write(fd, buf, bytes_remaining);
76 if (bytes_written < 0) {
82 return count - bytes_remaining;
85 /* Like pread(), but keep trying until everything has been read or we know for
86 * sure that there was an error (or end-of-file) */
88 full_pread(int fd, void *buf, size_t count, off_t offset)
91 size_t bytes_remaining;
93 for (bytes_remaining = count;
95 bytes_remaining -= bytes_read, buf += bytes_read,
98 bytes_read = pread(fd, buf, bytes_remaining, offset);
99 if (bytes_read <= 0) {
102 else if (errno == EINTR)
107 return count - bytes_remaining;
110 /* Like pwrite(), but keep trying until everything has been written or we know
111 * for sure that there was an error. */
113 full_pwrite(int fd, const void *buf, size_t count, off_t offset)
115 ssize_t bytes_written;
116 size_t bytes_remaining;
118 for (bytes_remaining = count;
119 bytes_remaining != 0;
120 bytes_remaining -= bytes_written, buf += bytes_written,
121 offset += bytes_written)
123 bytes_written = pwrite(fd, buf, bytes_remaining, offset);
124 if (bytes_written < 0) {
130 return count - bytes_remaining;
133 /* Like writev(), but keep trying until everything has been written or we know
134 * for sure that there was an error. */
136 full_writev(int fd, struct iovec *iov, int iovcnt)
138 size_t total_bytes_written = 0;
140 ssize_t bytes_written;
142 bytes_written = writev(fd, iov, iovcnt);
143 if (bytes_written < 0) {
148 total_bytes_written += bytes_written;
149 while (bytes_written) {
150 if (bytes_written >= iov[0].iov_len) {
151 bytes_written -= iov[0].iov_len;
155 iov[0].iov_base += bytes_written;
156 iov[0].iov_len -= bytes_written;
161 return total_bytes_written;
165 filedes_offset(int fd)
167 return lseek(fd, 0, SEEK_CUR);