[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