[libbluray-devel] posix: bypass stdio

hpi1 git at videolan.org
Wed Mar 4 10:30:19 CET 2015


libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Wed Mar  4 11:14:30 2015 +0200| [23ff0a3b51e64b8be7ea5c354d55d8461b4eaa0e] | committer: hpi1

posix: bypass stdio

> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=23ff0a3b51e64b8be7ea5c354d55d8461b4eaa0e
---

 src/file/file_posix.c |  106 ++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 79 insertions(+), 27 deletions(-)

diff --git a/src/file/file_posix.c b/src/file/file_posix.c
index 739b718..7257c9d 100644
--- a/src/file/file_posix.c
+++ b/src/file/file_posix.c
@@ -26,14 +26,20 @@
 #include "util/macro.h"
 #include "util/logging.h"
 
-#include <stdio.h>
-#include <stdlib.h>
 #include <inttypes.h>
+#include <stdio.h> // remove()
+#include <stdlib.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 
 static void file_close_linux(BD_FILE_H *file)
 {
     if (file) {
-        fclose((FILE *)file->internal);
+        close((int)(intptr_t)file->internal);
 
         BD_DEBUG(DBG_FILE, "Closed LINUX file (%p)\n", (void*)file);
 
@@ -43,12 +49,17 @@ static void file_close_linux(BD_FILE_H *file)
 
 static int64_t file_seek_linux(BD_FILE_H *file, int64_t offset, int32_t origin)
 {
-    return fseeko((FILE *)file->internal, offset, origin);
+    off_t result = lseek((int)(intptr_t)file->internal, offset, origin);
+    if (result == (off_t)-1) {
+        BD_DEBUG(DBG_FILE, "lseek() failed (%p)\n", (void*)file);
+        return -1;
+    }
+    return (int64_t)result;
 }
 
 static int64_t file_tell_linux(BD_FILE_H *file)
 {
-    return ftello((FILE *)file->internal);
+    return file_seek_linux(file, 0, SEEK_CUR);
 }
 
 #if 0
@@ -60,30 +71,78 @@ static int file_eof_linux(BD_FILE_H *file)
 
 static int64_t file_read_linux(BD_FILE_H *file, uint8_t *buf, int64_t size)
 {
-    if (size > 0 && size < BD_MAX_SSIZE) {
-        return (int64_t)fread(buf, 1, (size_t)size, (FILE *)file->internal);
+    ssize_t got, result;
+
+    if (size <= 0 || size >= BD_MAX_SSIZE) {
+        BD_DEBUG(DBG_FILE | DBG_CRIT, "Ignoring invalid read of size %"PRId64" (%p)\n", size, (void*)file);
+        return 0;
     }
 
-    BD_DEBUG(DBG_FILE | DBG_CRIT, "Ignoring invalid read of size %"PRId64" (%p)\n", size, (void*)file);
-    return 0;
+    for (got = 0; got < (ssize_t)size; got += result) {
+        result = read((int)(intptr_t)file->internal, buf + got, size - got);
+        if (result < 0) {
+            BD_DEBUG(DBG_FILE, "read() failed (%p)\n", (void*)file);
+            break;
+        } else if (result == 0) {
+            // hit EOF.
+            break;
+        }
+    }
+    return (int64_t)got;
 }
 
 static int64_t file_write_linux(BD_FILE_H *file, const uint8_t *buf, int64_t size)
 {
-    if (size > 0 && size < BD_MAX_SSIZE) {
-        return (int64_t)fwrite(buf, 1, (size_t)size, (FILE *)file->internal);
+    ssize_t written, result;
+
+    if (size <= 0 || size >= BD_MAX_SSIZE) {
+        BD_DEBUG(DBG_FILE | DBG_CRIT, "Ignoring invalid write of size %"PRId64" (%p)\n", size, (void*)file);
+        return 0;
     }
 
-    BD_DEBUG(DBG_FILE | DBG_CRIT, "Ignoring invalid write of size %"PRId64" (%p)\n", size, (void*)file);
-    return 0;
+    for (written = 0; written < (ssize_t)size; written += result) {
+        result = write((int)(intptr_t)file->internal, buf + written, size - written);
+        if (result < 0) {
+            BD_DEBUG(DBG_FILE, "write() failed (%p)\n", (void*)file);
+            break;
+        }
+    }
+    return (int64_t)written;
 }
 
-static BD_FILE_H *file_open_linux(const char* filename, const char *mode)
+static BD_FILE_H *file_open_linux(const char* filename, const char *cmode)
 {
-    FILE *fp = NULL;
-    BD_FILE_H *file = calloc(1, sizeof(BD_FILE_H));
+    BD_FILE_H *file;
+    int fd    = -1;
+    int flags = 0;
+    int mode  = 0;
+
+    if (strchr(cmode, 'w')) {
+        flags = O_WRONLY | O_CREAT | O_TRUNC;
+        mode  = S_IRUSR | S_IWUSR;
+    } else {
+        flags = O_RDONLY;
+    }
+
+#ifdef O_CLOEXEC
+    flags |= O_CLOEXEC;
+#endif
+#ifdef O_BINARY
+    flags |= O_BINARY;
+#endif
+
+    if ((fd = open(filename, flags, mode)) < 0) {
+        BD_DEBUG(DBG_FILE, "Error opening file %s\n", filename);
+        return NULL;
+    }
+
+    file = calloc(1, sizeof(BD_FILE_H));
+    if (!file) {
+        close(fd);
+        BD_DEBUG(DBG_FILE, "Error opening file %s (out of memory)\n", filename);
+        return NULL;
+    }
 
-    BD_DEBUG(DBG_FILE, "Opening LINUX file %s... (%p)\n", filename, (void*)file);
     file->close = file_close_linux;
     file->seek = file_seek_linux;
     file->read = file_read_linux;
@@ -91,17 +150,10 @@ static BD_FILE_H *file_open_linux(const char* filename, const char *mode)
     file->tell = file_tell_linux;
     //file->eof = file_eof_linux;
 
-    if ((fp = fopen(filename, mode))) {
-        file->internal = fp;
-
-        return file;
-    }
-
-    BD_DEBUG(DBG_FILE, "Error opening file! (%p)\n", (void*)file);
-
-    X_FREE(file);
+    file->internal = (void*)(intptr_t)fd;
 
-    return NULL;
+    BD_DEBUG(DBG_FILE, "Opened LINUX file %s... (%p)\n", filename, (void*)file);
+    return file;
 }
 
 BD_FILE_H* (*file_open)(const char* filename, const char *mode) = file_open_linux;



More information about the libbluray-devel mailing list