Преглед изворни кода

physfs_platform_posix.c: Retry on EINTR

pastdue пре 5 година
родитељ
комит
3c32cd5600
1 измењених фајлова са 20 додато и 8 уклоњено
  1. 20 8
      src/physfs_platform_posix.c

+ 20 - 8
src/physfs_platform_posix.c

@@ -6,8 +6,6 @@
  *  This file written by Ryan C. Gordon.
  */
 
-/* !!! FIXME: check for EINTR? */
-
 #define __PHYSICSFS_INTERNAL__
 #include "physfs_platforms.h"
 
@@ -167,7 +165,9 @@ static void *doOpen(const char *filename, int mode)
     /* O_APPEND doesn't actually behave as we'd like. */
     mode &= ~O_APPEND;
 
-    fd = open(filename, mode, S_IRUSR | S_IWUSR);
+    do {
+        fd = open(filename, mode, S_IRUSR | S_IWUSR);
+    } while ((fd < 0) && (errno == EINTR));
     BAIL_IF(fd < 0, errcodeFromErrno(), NULL);
 
     if (appending)
@@ -219,7 +219,9 @@ PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
     if (!__PHYSFS_ui64FitsAddressSpace(len))
         BAIL(PHYSFS_ERR_INVALID_ARGUMENT, -1);
 
-    rc = read(fd, buffer, (size_t) len);
+    do {
+        rc = read(fd, buffer, (size_t) len);
+    } while ((rc == -1) && (errno == EINTR));
     BAIL_IF(rc == -1, errcodeFromErrno(), -1);
     assert(rc >= 0);
     assert(rc <= len);
@@ -236,7 +238,9 @@ PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
     if (!__PHYSFS_ui64FitsAddressSpace(len))
         BAIL(PHYSFS_ERR_INVALID_ARGUMENT, -1);
 
-    rc = write(fd, (void *) buffer, (size_t) len);
+    do {
+        rc = write(fd, (void *) buffer, (size_t) len);
+    } while ((rc == -1) && (errno == EINTR));
     BAIL_IF(rc == -1, errcodeFromErrno(), rc);
     assert(rc >= 0);
     assert(rc <= len);
@@ -275,8 +279,13 @@ PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
 int __PHYSFS_platformFlush(void *opaque)
 {
     const int fd = *((int *) opaque);
-    if ((fcntl(fd, F_GETFL) & O_ACCMODE) != O_RDONLY)
-        BAIL_IF(fsync(fd) == -1, errcodeFromErrno(), 0);
+    int rc = -1;
+    if ((fcntl(fd, F_GETFL) & O_ACCMODE) != O_RDONLY) {
+        do {
+            rc = fsync(fd);
+        } while ((rc == -1) && (errno == EINTR));
+        BAIL_IF(rc == -1, errcodeFromErrno(), 0);
+    }
     return 1;
 } /* __PHYSFS_platformFlush */
 
@@ -284,7 +293,10 @@ int __PHYSFS_platformFlush(void *opaque)
 void __PHYSFS_platformClose(void *opaque)
 {
     const int fd = *((int *) opaque);
-    (void) close(fd);  /* we don't check this. You should have used flush! */
+    int rc = -1;
+    do {
+        rc = close(fd);  /* we don't check this. You should have used flush! */
+    } while ((rc == -1) && (errno == EINTR));
     allocator.Free(opaque);
 } /* __PHYSFS_platformClose */