platform/posix.c
changeset 251 0f4615263e32
parent 249 fed886543e40
child 255 f3726b21d48f
--- a/platform/posix.c	Mon May 27 19:12:44 2002 +0000
+++ b/platform/posix.c	Sun Jun 02 03:48:56 2002 +0000
@@ -33,15 +33,15 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 #include <ctype.h>
-#include <unistd.h>
 #include <sys/types.h>
-#include <pwd.h>
 #include <sys/stat.h>
-#include <sys/param.h>
+#include <pwd.h>
 #include <dirent.h>
-#include <time.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <assert.h>
 
 #define __PHYSICSFS_INTERNAL__
 #include "physfs_internal.h"
@@ -351,72 +351,86 @@
 } /* __PHYSFS_platformMkDir */
 
 
-static void *doOpen(const char *filename, const char *mode)
+static void *doOpen(const char *filename, int mode)
 {
-    FILE *retval;
+    int fd;
+    int *retval;
     errno = 0;
 
-    retval = fopen(filename, mode);
-    if (retval == NULL)
+    fd = open(filename, mode, S_IRUSR | S_IWUSR);
+    if (fd < 0)
         __PHYSFS_setError(strerror(errno));
 
+    retval = (int *) malloc(sizeof (int));
+    if (retval == NULL)
+    {
+        close(fd);
+        BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
+    } /* if */
+
+    *retval = fd;
     return((void *) retval);
 } /* doOpen */
 
 
 void *__PHYSFS_platformOpenRead(const char *filename)
 {
-    return(doOpen(filename, "rb"));
+    return(doOpen(filename, O_RDONLY));
 } /* __PHYSFS_platformOpenRead */
 
 
 void *__PHYSFS_platformOpenWrite(const char *filename)
 {
-    return(doOpen(filename, "wb"));
+    return(doOpen(filename, O_WRONLY | O_CREAT | O_TRUNC));
 } /* __PHYSFS_platformOpenWrite */
 
 
 void *__PHYSFS_platformOpenAppend(const char *filename)
 {
-    return(doOpen(filename, "ab"));
+    return(doOpen(filename, O_WRONLY | O_CREAT | O_APPEND));
 } /* __PHYSFS_platformOpenAppend */
 
 
 PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
                                     PHYSFS_uint32 size, PHYSFS_uint32 count)
 {
-    FILE *io = (FILE *) opaque;
-    int rc = fread(buffer, size, count, io);
-    if (rc < count)
-    {
-        int err = errno;
-        BAIL_IF_MACRO(ferror(io), strerror(err), rc);
-        BAIL_MACRO(ERR_PAST_EOF, rc);
-    } /* if */
+    int fd = *((int *) opaque);
+    int max = size * count;
+    int rc = read(fd, buffer, max);
 
-    return(rc);
+    BAIL_IF_MACRO(rc == -1, strerror(errno), rc);
+    assert(rc <= max);
+
+    if ((rc < max) && (size > 1))
+        lseek(fd, -(rc % size), SEEK_CUR); /* rollback to object boundary. */
+
+    return(rc / size);
 } /* __PHYSFS_platformRead */
 
 
 PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
                                      PHYSFS_uint32 size, PHYSFS_uint32 count)
 {
-    FILE *io = (FILE *) opaque;
-    int rc = fwrite((void *) buffer, size, count, io);
-    if (rc < count)
-        __PHYSFS_setError(strerror(errno));
+    int fd = *((int *) opaque);
+    int max = size * count;
+    int rc = write(fd, (void *) buffer, max);
 
-    return(rc);
+    BAIL_IF_MACRO(rc == -1, strerror(errno), rc);
+    assert(rc <= max);
+
+    if ((rc < max) && (size > 1))
+        lseek(fd, -(rc % size), SEEK_CUR); /* rollback to object boundary. */
+
+    return(rc / size);
 } /* __PHYSFS_platformWrite */
 
 
 int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
 {
-    FILE *io = (FILE *) opaque;
+    int fd = *((int *) opaque);
 
     /* !!! FIXME: Use llseek where available. */
-    errno = 0;
-    BAIL_IF_MACRO(fseek(io, pos, SEEK_SET) != 0, strerror(errno), 0);
+    BAIL_IF_MACRO(lseek(fd, (int) pos, SEEK_SET) != 0, strerror(errno), 0);
 
     return(1);
 } /* __PHYSFS_platformSeek */
@@ -424,8 +438,8 @@
 
 PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
 {
-    FILE *io = (FILE *) opaque;
-    PHYSFS_sint64 retval = ftell(io);
+    int fd = *((int *) opaque);
+    PHYSFS_sint64 retval = lseek(fd, 0, SEEK_CUR);
     BAIL_IF_MACRO(retval == -1, strerror(errno), -1);
     return(retval);
 } /* __PHYSFS_platformTell */
@@ -433,39 +447,39 @@
 
 PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
 {
-    FILE *io = (FILE *) opaque;
+    int fd = *((int *) opaque);
     struct stat statbuf;
-    errno = 0;
-    BAIL_IF_MACRO(fstat(fileno(io), &statbuf) == -1, strerror(errno), -1);
+    BAIL_IF_MACRO(fstat(fd, &statbuf) == -1, strerror(errno), -1);
     return((PHYSFS_sint64) statbuf.st_size);
 } /* __PHYSFS_platformFileLength */
 
 
 int __PHYSFS_platformEOF(void *opaque)
 {
-    return(feof((FILE *) opaque));
+    PHYSFS_sint64 pos = __PHYSFS_platformTell(opaque);
+    PHYSFS_sint64 len = __PHYSFS_platformFileLength(opaque);
+    return(pos >= len);
 } /* __PHYSFS_platformEOF */
 
 
 int __PHYSFS_platformFlush(void *opaque)
 {
-    errno = 0;
-    BAIL_IF_MACRO(fflush((FILE *) opaque) == EOF, strerror(errno), 0);
+    int fd = *((int *) opaque);
+    BAIL_IF_MACRO(fsync(fd) == -1, strerror(errno), 0);
     return(1);
 } /* __PHYSFS_platformFlush */
 
 
 int __PHYSFS_platformClose(void *opaque)
 {
-    errno = 0;
-    BAIL_IF_MACRO(fclose((FILE *) opaque) == EOF, strerror(errno), 0);
+    int fd = *((int *) opaque);
+    BAIL_IF_MACRO(close(fd) == -1, strerror(errno), 0);
     return(1);
 } /* __PHYSFS_platformClose */
 
 
 int __PHYSFS_platformDelete(const char *path)
 {
-    errno = 0;
     BAIL_IF_MACRO(remove(path) == -1, strerror(errno), 0);
     return(1);
 } /* __PHYSFS_platformDelete */