]> wimlib.net Git - wimlib/blobdiff - src/util.c
filedes_t => int
[wimlib] / src / util.c
index 23dfff27e76b1d97480c0b9be6b9828c00f54278..5421a6b5c53beab448e4c23a9d9be1004b92f8ea 100644 (file)
 
 #include "config.h"
 
+
 #undef _GNU_SOURCE
 /* Make sure the POSIX-compatible strerror_r() is declared, rather than the GNU
  * version, which has a different return type. */
-#define _POSIX_C_SOURCE 200112
 #include <string.h>
+
 #define _GNU_SOURCE
 
-#include "wimlib_internal.h"
 #include "endianness.h"
 #include "timestamp.h"
+#include "wimlib_internal.h"
 
 #include <ctype.h>
 #include <errno.h>
-#include <stdlib.h>
 #include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
 
-#include <unistd.h> /* for getpid() */
 
 #ifdef __WIN32__
-#include "win32.h"
+#  include "win32.h"
+#  define pread         win32_pread
+#  define pwrite win32_pwrite
+#  define writev win32_writev
+#else
+#  include <sys/uio.h> /* for writev() and `struct iovec' */
 #endif
 
 static size_t
@@ -301,6 +307,8 @@ static const tchar *error_strings[] = {
                = T("An invalid parameter was given"),
        [WIMLIB_ERR_INVALID_PART_NUMBER]
                = T("The part number or total parts of the WIM is invalid"),
+       [WIMLIB_ERR_INVALID_REPARSE_DATA]
+               = T("The reparse data of a reparse point was invalid"),
        [WIMLIB_ERR_INVALID_RESOURCE_HASH]
                = T("The SHA1 message digest of a WIM resource did not match the expected value"),
        [WIMLIB_ERR_INVALID_RESOURCE_SIZE]
@@ -345,8 +353,8 @@ static const tchar *error_strings[] = {
                = T("Could not read the target of a symbolic link"),
        [WIMLIB_ERR_RENAME]
                = T("Could not rename a file"),
-       [WIMLIB_ERR_REOPEN]
-               = T("Could not re-open the WIM after overwriting it"),
+       [WIMLIB_ERR_REPARSE_POINT_FIXUP_FAILED]
+               = T("Unable to complete reparse point fixup"),
        [WIMLIB_ERR_RESOURCE_ORDER]
                = T("The components of the WIM were arranged in an unexpected order"),
        [WIMLIB_ERR_SPECIAL_FILE]
@@ -561,3 +569,134 @@ zap_backslashes(tchar *s)
                }
        }
 }
+
+/* Like read(), but keep trying until everything has been written or we know for
+ * sure that there was an error (or end-of-file). */
+size_t
+full_read(int fd, void *buf, size_t count)
+{
+       ssize_t bytes_read;
+       size_t bytes_remaining;
+
+       for (bytes_remaining = count;
+            bytes_remaining != 0;
+            bytes_remaining -= bytes_read, buf += bytes_read)
+       {
+               bytes_read = read(fd, buf, bytes_remaining);
+               if (bytes_read <= 0) {
+                       if (bytes_read == 0)
+                               errno = EIO;
+                       else if (errno == EINTR)
+                               continue;
+                       break;
+               }
+       }
+       return count - bytes_remaining;
+}
+
+/* Like write(), but keep trying until everything has been written or we know
+ * for sure that there was an error. */
+size_t
+full_write(int fd, const void *buf, size_t count)
+{
+       ssize_t bytes_written;
+       size_t bytes_remaining;
+
+       for (bytes_remaining = count;
+            bytes_remaining != 0;
+            bytes_remaining -= bytes_written, buf += bytes_written)
+       {
+               bytes_written = write(fd, buf, bytes_remaining);
+               if (bytes_written < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       break;
+               }
+       }
+       return count - bytes_remaining;
+}
+
+/* Like pread(), but keep trying until everything has been read or we know for
+ * sure that there was an error (or end-of-file) */
+size_t
+full_pread(int fd, void *buf, size_t count, off_t offset)
+{
+       ssize_t bytes_read;
+       size_t bytes_remaining;
+
+       for (bytes_remaining = count;
+            bytes_remaining != 0;
+            bytes_remaining -= bytes_read, buf += bytes_read,
+               offset += bytes_read)
+       {
+               bytes_read = pread(fd, buf, bytes_remaining, offset);
+               if (bytes_read <= 0) {
+                       if (bytes_read == 0)
+                               errno = EIO;
+                       else if (errno == EINTR)
+                               continue;
+                       break;
+               }
+       }
+       return count - bytes_remaining;
+}
+
+/* Like pwrite(), but keep trying until everything has been written or we know
+ * for sure that there was an error. */
+size_t
+full_pwrite(int fd, const void *buf, size_t count, off_t offset)
+{
+       ssize_t bytes_written;
+       size_t bytes_remaining;
+
+       for (bytes_remaining = count;
+            bytes_remaining != 0;
+            bytes_remaining -= bytes_written, buf += bytes_written,
+               offset += bytes_written)
+       {
+               bytes_written = pwrite(fd, buf, bytes_remaining, offset);
+               if (bytes_written < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       break;
+               }
+       }
+       return count - bytes_remaining;
+}
+
+/* Like writev(), but keep trying until everything has been written or we know
+ * for sure that there was an error. */
+size_t
+full_writev(int fd, struct iovec *iov, int iovcnt)
+{
+       size_t total_bytes_written = 0;
+       while (iovcnt > 0) {
+               ssize_t bytes_written;
+
+               bytes_written = writev(fd, iov, iovcnt);
+               if (bytes_written < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       break;
+               }
+               total_bytes_written += bytes_written;
+               while (bytes_written) {
+                       if (bytes_written >= iov[0].iov_len) {
+                               bytes_written -= iov[0].iov_len;
+                               iov++;
+                               iovcnt--;
+                       } else {
+                               iov[0].iov_base += bytes_written;
+                               iov[0].iov_len -= bytes_written;
+                               bytes_written = 0;
+                       }
+               }
+       }
+       return total_bytes_written;
+}
+
+off_t
+filedes_offset(int fd)
+{
+       return lseek(fd, 0, SEEK_CUR);
+}