aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-06-12 23:17:49 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-06-15 13:38:25 +0200
commit89cdef0859259fdea0165b0d3918777d1ed42955 (patch)
tree1773321fd7d1c718b89fe0face92c9c7cdafc2f4
parent043495538ebaf02adba6d40764fb3e6def65cb09 (diff)
libsquashfs: Add sqfs_open_native_file function
Having a function to interpret the flags and open a native file handle simplifies the istream/ostream/file code which shares that decoding part, particularly on windows where the character set needs to be transformed. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--bin/gensquashfs/Makemodule.am19
-rw-r--r--bin/sqfs2tar/Makemodule.am4
-rw-r--r--bin/sqfsdiff/Makemodule.am2
-rw-r--r--bin/tar2sqfs/Makemodule.am2
-rw-r--r--include/io/file.h14
-rw-r--r--include/sqfs/io.h38
-rw-r--r--lib/io/src/unix/istream.c5
-rw-r--r--lib/io/src/unix/ostream.c9
-rw-r--r--lib/io/src/win32/istream.c15
-rw-r--r--lib/io/src/win32/ostream.c28
-rw-r--r--lib/sqfs/src/unix/io_file.c76
-rw-r--r--lib/sqfs/src/win32/io_file.c119
-rw-r--r--lib/tar/Makemodule.am68
-rw-r--r--lib/util/Makemodule.am2
-rw-r--r--lib/util/test/str_table.c1
15 files changed, 210 insertions, 192 deletions
diff --git a/bin/gensquashfs/Makemodule.am b/bin/gensquashfs/Makemodule.am
index 2e14ff6..98153cb 100644
--- a/bin/gensquashfs/Makemodule.am
+++ b/bin/gensquashfs/Makemodule.am
@@ -4,7 +4,7 @@ gensquashfs_SOURCES = bin/gensquashfs/src/mkfs.c bin/gensquashfs/src/mkfs.h \
bin/gensquashfs/src/fstree_from_file.c \
bin/gensquashfs/src/fstree_from_dir.c \
bin/gensquashfs/src/sort_by_file.c bin/gensquashfs/src/glob.c
-gensquashfs_LDADD = libcommon.a libsquashfs.la libfstree.a libio.a
+gensquashfs_LDADD = libcommon.a libio.a libsquashfs.la libfstree.a
gensquashfs_LDADD += libutil.a libcompat.a $(LZO_LIBS) $(PTHREAD_LIBS)
gensquashfs_CPPFLAGS = $(AM_CPPFLAGS)
gensquashfs_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS)
@@ -25,8 +25,8 @@ test_filemap_xattr_SOURCES = bin/gensquashfs/test/filemap_xattr.c \
bin/gensquashfs/src/mkfs.h
test_filemap_xattr_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/bin/gensquashfs/src
test_filemap_xattr_CPPFLAGS += -DTESTPATH=$(GENDATADIR)/xattr1.txt
-test_filemap_xattr_LDADD = libsquashfs.la libfstree.a libutil.a
-test_filemap_xattr_LDADD += libio.a libcompat.a
+test_filemap_xattr_LDADD = libio.a libsquashfs.la libfstree.a libutil.a
+test_filemap_xattr_LDADD += libcompat.a
test_fstree_from_file_SOURCES = bin/gensquashfs/test/fstree_from_file.c \
bin/gensquashfs/src/fstree_from_file.c \
@@ -35,8 +35,8 @@ test_fstree_from_file_SOURCES = bin/gensquashfs/test/fstree_from_file.c \
bin/gensquashfs/src/mkfs.h
test_fstree_from_file_CPPFLAGS = $(AM_CPPFLAGS)
test_fstree_from_file_CPPFLAGS += -I$(top_srcdir)/bin/gensquashfs/src
-test_fstree_from_file_LDADD = libcommon.a libfstree.a libio.a libutil.a \
- libcompat.a
+test_fstree_from_file_LDADD = libio.a libsquashfs.la libcommon.a libfstree.a \
+ libutil.a libcompat.a
test_fstree_glob1_SOURCES = bin/gensquashfs/test/fstree_glob1.c \
bin/gensquashfs/src/fstree_from_file.c \
@@ -45,7 +45,8 @@ test_fstree_glob1_SOURCES = bin/gensquashfs/test/fstree_glob1.c \
bin/gensquashfs/src/mkfs.h
test_fstree_glob1_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/bin/gensquashfs/src
test_fstree_glob1_CPPFLAGS += -DTESTPATH=$(GENDATADIR)
-test_fstree_glob1_LDADD = libcommon.a libfstree.a libio.a libutil.a libcompat.a
+test_fstree_glob1_LDADD = libio.a libsquashfs.la libcommon.a libfstree.a \
+ libutil.a libcompat.a
test_sort_file_SOURCES = bin/gensquashfs/test/sort_file.c \
bin/gensquashfs/src/fstree_from_file.c \
@@ -54,7 +55,8 @@ test_sort_file_SOURCES = bin/gensquashfs/test/sort_file.c \
bin/gensquashfs/src/glob.c \
bin/gensquashfs/src/mkfs.h
test_sort_file_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/bin/gensquashfs/src
-test_sort_file_LDADD = libcommon.a libfstree.a libio.a libutil.a libcompat.a
+test_sort_file_LDADD = libio.a libsquashfs.la libcommon.a libfstree.a \
+ libutil.a libcompat.a
fstree_fuzz_SOURCES = bin/gensquashfs/test/fstree_fuzz.c \
bin/gensquashfs/src/fstree_from_file.c \
@@ -62,7 +64,8 @@ fstree_fuzz_SOURCES = bin/gensquashfs/test/fstree_fuzz.c \
bin/gensquashfs/src/glob.c \
bin/gensquashfs/src/mkfs.h
fstree_fuzz_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/bin/gensquashfs/src
-fstree_fuzz_LDADD = libcommon.a libfstree.a libio.a libutil.a libcompat.a
+fstree_fuzz_LDADD = libio.a libsquashfs.la libcommon.a libfstree.a \
+ libutil.a libcompat.a
GENSQUASHFS_TESTS = \
test_filemap_xattr test_fstree_from_file \
diff --git a/bin/sqfs2tar/Makemodule.am b/bin/sqfs2tar/Makemodule.am
index 9f7abf9..beb373e 100644
--- a/bin/sqfs2tar/Makemodule.am
+++ b/bin/sqfs2tar/Makemodule.am
@@ -1,8 +1,8 @@
sqfs2tar_SOURCES = bin/sqfs2tar/src/sqfs2tar.c bin/sqfs2tar/src/sqfs2tar.h \
bin/sqfs2tar/src/options.c bin/sqfs2tar/src/write_tree.c
sqfs2tar_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS)
-sqfs2tar_LDADD = libcommon.a libutil.a libsquashfs.la libtar.a
-sqfs2tar_LDADD += libio.a libxfrm.a libcompat.a libfstree.a
+sqfs2tar_LDADD = libcommon.a libutil.a libtar.a libio.a libsquashfs.la
+sqfs2tar_LDADD += libxfrm.a libcompat.a libfstree.a
sqfs2tar_LDADD += $(ZLIB_LIBS) $(XZ_LIBS) $(LZO_LIBS) $(ZSTD_LIBS) $(BZIP2_LIBS)
sqfs2tar_LDADD += $(PTHREAD_LIBS)
diff --git a/bin/sqfsdiff/Makemodule.am b/bin/sqfsdiff/Makemodule.am
index 4f21901..f520453 100644
--- a/bin/sqfsdiff/Makemodule.am
+++ b/bin/sqfsdiff/Makemodule.am
@@ -4,7 +4,7 @@ sqfsdiff_SOURCES = bin/sqfsdiff/src/sqfsdiff.c bin/sqfsdiff/src/sqfsdiff.h \
bin/sqfsdiff/src/compare_files.c bin/sqfsdiff/src/super.c \
bin/sqfsdiff/src/extract.c
sqfsdiff_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS)
-sqfsdiff_LDADD = libcommon.a libsquashfs.la libio.a libcompat.a libutil.a
+sqfsdiff_LDADD = libcommon.a libio.a libsquashfs.la libcompat.a libutil.a
sqfsdiff_LDADD += $(LZO_LIBS) libfstree.a $(PTHREAD_LIBS)
dist_man1_MANS += bin/sqfsdiff/sqfsdiff.1
diff --git a/bin/tar2sqfs/Makemodule.am b/bin/tar2sqfs/Makemodule.am
index 44a3346..49cfb7d 100644
--- a/bin/tar2sqfs/Makemodule.am
+++ b/bin/tar2sqfs/Makemodule.am
@@ -1,7 +1,7 @@
tar2sqfs_SOURCES = bin/tar2sqfs/src/tar2sqfs.c bin/tar2sqfs/src/tar2sqfs.h \
bin/tar2sqfs/src/options.c bin/tar2sqfs/src/process_tarball.c
tar2sqfs_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS)
-tar2sqfs_LDADD = libcommon.a libtar.a libsquashfs.la libio.a libxfrm.a
+tar2sqfs_LDADD = libcommon.a libtar.a libio.a libsquashfs.la libxfrm.a
tar2sqfs_LDADD += libfstree.a libcompat.a libfstree.a libutil.a $(LZO_LIBS)
tar2sqfs_LDADD += $(ZLIB_LIBS) $(XZ_LIBS) $(ZSTD_LIBS) $(BZIP2_LIBS)
tar2sqfs_LDADD += $(PTHREAD_LIBS)
diff --git a/include/io/file.h b/include/io/file.h
index fa0abc0..5065619 100644
--- a/include/io/file.h
+++ b/include/io/file.h
@@ -7,15 +7,7 @@
#ifndef IO_FILE_H
#define IO_FILE_H
-#include "io/istream.h"
-
-#if defined(_WIN32) || defined(__WINDOWS__)
-#include <handleapi.h>
-
-typedef HANDLE os_file_t;
-#else
-typedef int os_file_t;
-#endif
+#include "sqfs/io.h"
#ifdef __cplusplus
extern "C" {
@@ -36,7 +28,7 @@ extern "C" {
* @return A pointer to an output stream on success, NULL on failure.
*/
SQFS_INTERNAL
-sqfs_istream_t *istream_open_handle(const char *path, os_file_t fd);
+sqfs_istream_t *istream_open_handle(const char *path, sqfs_file_handle_t fd);
/**
* @brief Create an output stream that writes to an OS native file handle.
@@ -55,7 +47,7 @@ sqfs_istream_t *istream_open_handle(const char *path, os_file_t fd);
* @return A pointer to an output stream on success, NULL on failure.
*/
SQFS_INTERNAL sqfs_ostream_t *ostream_open_handle(const char *path,
- os_file_t hnd,
+ sqfs_file_handle_t hnd,
int flags);
/**
diff --git a/include/sqfs/io.h b/include/sqfs/io.h
index 4291e71..1138fc0 100644
--- a/include/sqfs/io.h
+++ b/include/sqfs/io.h
@@ -34,6 +34,20 @@
*/
/**
+ * @typedef sqfs_file_handle_t
+ *
+ * @brief Native handle type for file I/O
+ */
+
+#if defined(_WIN32) || defined(__WINDOWS__)
+#include <handleapi.h>
+
+typedef HANDLE sqfs_file_handle_t;
+#else
+typedef int sqfs_file_handle_t;
+#endif
+
+/**
* @enum SQFS_FILE_OPEN_FLAGS
*
* @brief Flags for @ref sqfs_open_file
@@ -273,6 +287,30 @@ extern "C" {
#endif
/**
+ * @brief Open a native file handle
+ *
+ * On Unix-like systems, this generates a file descriptor that needs to be
+ * closed with close(). If opening fails, errno is preseved.
+ *
+ * On Windows, a HANDLE is created that needs to be disposed of
+ * using CloseHandle(). If opening fails, GetLastError() is preseved.
+ * If @ref SQFS_FILE_OPEN_NO_CHARSET_XFRM is set, the given string is passed
+ * to the ANSI API that interprets the string according to the the currently
+ * set codepage. If the flag is not present, the string is assumed to be UTF-8,
+ * the function internally converts it to UTF-16 and uses the wide char API.
+ *
+ * @param out Returns a native file handle on success
+ * @param filename The path to the file to open
+ * @param flags A set of @ref SQFS_FILE_OPEN_FLAGS controlling how the
+ * file is opened.
+ *
+ * @return Zero on success, a negative @ref SQFS_ERROR code on failure.
+ * If an unknown flag was used, @ref SQFS_ERROR_UNSUPPORTED is returned.
+ */
+SQFS_API int sqfs_open_native_file(sqfs_file_handle_t *out,
+ const char *filename, sqfs_u32 flags);
+
+/**
* @brief Open a file through the operating systems filesystem API
*
* This function internally creates an instance of a reference implementation
diff --git a/lib/io/src/unix/istream.c b/lib/io/src/unix/istream.c
index 39d570f..ca9a183 100644
--- a/lib/io/src/unix/istream.c
+++ b/lib/io/src/unix/istream.c
@@ -144,11 +144,10 @@ fail_free:
sqfs_istream_t *istream_open_file(const char *path)
{
+ sqfs_file_handle_t fd;
sqfs_istream_t *out;
- int fd;
- fd = open(path, O_RDONLY);
- if (fd < 0) {
+ if (sqfs_open_native_file(&fd, path, SQFS_FILE_OPEN_READ_ONLY)) {
perror(path);
return NULL;
}
diff --git a/lib/io/src/unix/ostream.c b/lib/io/src/unix/ostream.c
index 0e95167..52a566a 100644
--- a/lib/io/src/unix/ostream.c
+++ b/lib/io/src/unix/ostream.c
@@ -177,13 +177,12 @@ fail_free:
sqfs_ostream_t *ostream_open_file(const char *path, int flags)
{
+ sqfs_file_handle_t fd;
sqfs_ostream_t *out;
- int fd;
- if (flags & SQFS_FILE_OPEN_OVERWRITE) {
- fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
- } else {
- fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0644);
+ if (sqfs_open_native_file(&fd, path, flags)) {
+ perror(path);
+ return NULL;
}
out = ostream_open_handle(path, fd, flags);
diff --git a/lib/io/src/win32/istream.c b/lib/io/src/win32/istream.c
index e6cb266..7cc7144 100644
--- a/lib/io/src/win32/istream.c
+++ b/lib/io/src/win32/istream.c
@@ -154,25 +154,14 @@ fail_free:
sqfs_istream_t *istream_open_file(const char *path)
{
- WCHAR *wpath = NULL;
+ sqfs_file_handle_t hnd;
sqfs_istream_t *out;
- HANDLE hnd;
-
- wpath = path_to_windows(path);
- if (wpath == NULL)
- return NULL;
- hnd = CreateFileW(wpath, GENERIC_READ, FILE_SHARE_READ, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-
- if (hnd == INVALID_HANDLE_VALUE) {
+ if (sqfs_open_native_file(&hnd, path, SQFS_FILE_OPEN_READ_ONLY)) {
w32_perror(path);
- free(wpath);
return NULL;
}
- free(wpath);
-
out = istream_open_handle(path, hnd);
if (out == NULL)
CloseHandle(hnd);
diff --git a/lib/io/src/win32/ostream.c b/lib/io/src/win32/ostream.c
index 5b099a4..5b584e5 100644
--- a/lib/io/src/win32/ostream.c
+++ b/lib/io/src/win32/ostream.c
@@ -176,39 +176,19 @@ fail_free:
sqfs_ostream_t *ostream_open_file(const char *path, int flags)
{
- int access_flags, creation_mode;
- WCHAR *wpath = NULL;
+ sqfs_file_handle_t hnd;
sqfs_ostream_t *out;
- HANDLE hnd;
-
- access_flags = GENERIC_WRITE;
-
- if (flags & SQFS_FILE_OPEN_OVERWRITE) {
- creation_mode = CREATE_ALWAYS;
- } else {
- creation_mode = CREATE_NEW;
- }
- if (flags & SQFS_FILE_OPEN_NO_CHARSET_XFRM) {
- hnd = CreateFileA(path, access_flags, 0, NULL, creation_mode,
- FILE_ATTRIBUTE_NORMAL, NULL);
- } else {
- wpath = path_to_windows(path);
- if (wpath == NULL)
- return NULL;
-
- hnd = CreateFileW(wpath, access_flags, 0, NULL, creation_mode,
- FILE_ATTRIBUTE_NORMAL, NULL);
+ if (sqfs_open_native_file(&hnd, path, flags)) {
+ w32_perror(path);
+ return NULL;
}
if (hnd == INVALID_HANDLE_VALUE) {
w32_perror(path);
- free(wpath);
return NULL;
}
- free(wpath);
-
out = ostream_open_handle(path, hnd, flags);
if (out == NULL)
CloseHandle(hnd);
diff --git a/lib/sqfs/src/unix/io_file.c b/lib/sqfs/src/unix/io_file.c
index 886f752..f9b602a 100644
--- a/lib/sqfs/src/unix/io_file.c
+++ b/lib/sqfs/src/unix/io_file.c
@@ -24,7 +24,7 @@ typedef struct {
bool readonly;
sqfs_u64 size;
- int fd;
+ sqfs_file_handle_t fd;
char name[];
} sqfs_file_stdio_t;
@@ -146,18 +146,40 @@ static const char *stdio_get_filename(sqfs_file_t *file)
return ((sqfs_file_stdio_t *)file)->name;
}
+int sqfs_open_native_file(sqfs_file_handle_t *out, const char *filename,
+ sqfs_u32 flags)
+{
+ int open_mode;
+
+ *out = -1;
+
+ if (flags & ~SQFS_FILE_OPEN_ALL_FLAGS)
+ return SQFS_ERROR_UNSUPPORTED;
+
+ if (flags & SQFS_FILE_OPEN_READ_ONLY) {
+ open_mode = O_RDONLY;
+ } else {
+ open_mode = O_CREAT | O_RDWR;
+
+ if (flags & SQFS_FILE_OPEN_OVERWRITE) {
+ open_mode |= O_TRUNC;
+ } else {
+ open_mode |= O_EXCL;
+ }
+ }
+
+ *out = open(filename, open_mode, 0644);
+
+ return (*out < 0) ? SQFS_ERROR_IO : 0;
+}
+
sqfs_file_t *sqfs_open_file(const char *filename, sqfs_u32 flags)
{
sqfs_file_stdio_t *file;
size_t size, namelen;
- int open_mode, temp;
sqfs_file_t *base;
struct stat sb;
-
- if (flags & ~SQFS_FILE_OPEN_ALL_FLAGS) {
- errno = EINVAL;
- return NULL;
- }
+ int temp;
namelen = strlen(filename);
size = sizeof(*file) + 1;
@@ -175,37 +197,14 @@ sqfs_file_t *sqfs_open_file(const char *filename, sqfs_u32 flags)
sqfs_object_init(file, stdio_destroy, stdio_copy);
memcpy(file->name, filename, namelen);
- if (flags & SQFS_FILE_OPEN_READ_ONLY) {
- file->readonly = true;
- open_mode = O_RDONLY;
- } else {
- file->readonly = false;
- open_mode = O_CREAT | O_RDWR;
-
- if (flags & SQFS_FILE_OPEN_OVERWRITE) {
- open_mode |= O_TRUNC;
- } else {
- open_mode |= O_EXCL;
- }
- }
-
- file->fd = open(filename, open_mode, 0644);
- if (file->fd < 0) {
- temp = errno;
- free(file);
- errno = temp;
- return NULL;
- }
+ if (sqfs_open_native_file(&file->fd, filename, flags))
+ goto fail;
- if (fstat(file->fd, &sb)) {
- temp = errno;
- close(file->fd);
- free(file);
- errno = temp;
- return NULL;
- }
+ if (fstat(file->fd, &sb))
+ goto fail;
file->size = sb.st_size;
+ file->readonly = (flags & SQFS_FILE_OPEN_READ_ONLY) != 0;
base->read_at = stdio_read_at;
base->write_at = stdio_write_at;
@@ -213,4 +212,11 @@ sqfs_file_t *sqfs_open_file(const char *filename, sqfs_u32 flags)
base->truncate = stdio_truncate;
base->get_filename = stdio_get_filename;
return base;
+fail:
+ temp = errno;
+ if (file->fd >= 0)
+ close(file->fd);
+ free(file);
+ errno = temp;
+ return NULL;
}
diff --git a/lib/sqfs/src/win32/io_file.c b/lib/sqfs/src/win32/io_file.c
index ec98900..dbd80d8 100644
--- a/lib/sqfs/src/win32/io_file.c
+++ b/lib/sqfs/src/win32/io_file.c
@@ -22,7 +22,7 @@ typedef struct {
bool readonly;
sqfs_u64 size;
- HANDLE fd;
+ sqfs_file_handle_t fd;
char name[];
} sqfs_file_stdio_t;
@@ -158,49 +158,84 @@ static const char *stdio_get_filename(sqfs_file_t *file)
return ((sqfs_file_stdio_t *)file)->name;
}
-sqfs_file_t *sqfs_open_file(const char *filename, sqfs_u32 flags)
+int sqfs_open_native_file(sqfs_file_handle_t *out, const char *filename,
+ sqfs_u32 flags)
{
int access_flags, creation_mode, share_mode;
- sqfs_file_stdio_t *file;
- size_t namelen, total;
- LARGE_INTEGER size;
- sqfs_file_t *base;
WCHAR *wpath = NULL;
- DWORD length;
+ DWORD length, err;
+
+ *out = INVALID_HANDLE_VALUE;
if (flags & ~SQFS_FILE_OPEN_ALL_FLAGS) {
SetLastError(ERROR_INVALID_PARAMETER);
- return NULL;
+ return SQFS_ERROR_UNSUPPORTED;
}
- namelen = strlen(filename);
- total = sizeof(*file) + 1;
+ if (flags & SQFS_FILE_OPEN_READ_ONLY) {
+ access_flags = GENERIC_READ;
+ creation_mode = OPEN_EXISTING;
+ share_mode = FILE_SHARE_READ;
+ } else {
+ access_flags = GENERIC_READ | GENERIC_WRITE;
+ share_mode = 0;
- if (SZ_ADD_OV(total, namelen, &total)) {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return NULL;
+ if (flags & SQFS_FILE_OPEN_OVERWRITE) {
+ creation_mode = CREATE_ALWAYS;
+ } else {
+ creation_mode = CREATE_NEW;
+ }
}
- if (!(flags & SQFS_FILE_OPEN_NO_CHARSET_XFRM)) {
+ if (flags & SQFS_FILE_OPEN_NO_CHARSET_XFRM) {
+ *out = CreateFileA(filename, access_flags, share_mode, NULL,
+ creation_mode, FILE_ATTRIBUTE_NORMAL, NULL);
+ } else {
length = MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0);
if (length <= 0)
- return NULL;
+ return SQFS_ERROR_INTERNAL;
wpath = calloc(sizeof(wpath[0]), length + 1);
if (wpath == NULL) {
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return NULL;
+ return SQFS_ERROR_ALLOC;
}
MultiByteToWideChar(CP_UTF8, 0, filename, -1,
wpath, length + 1);
wpath[length] = '\0';
+
+ *out = CreateFileW(wpath, access_flags, share_mode, NULL,
+ creation_mode, FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ err = GetLastError();
+ free(wpath);
+ SetLastError(err);
+ }
+
+ return (*out == INVALID_HANDLE_VALUE) ? SQFS_ERROR_IO : 0;
+}
+
+sqfs_file_t *sqfs_open_file(const char *filename, sqfs_u32 flags)
+{
+ sqfs_file_stdio_t *file;
+ size_t namelen, total;
+ LARGE_INTEGER size;
+ sqfs_file_t *base;
+ DWORD err;
+
+ namelen = strlen(filename);
+ total = sizeof(*file) + 1;
+
+ if (SZ_ADD_OV(total, namelen, &total)) {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
}
file = calloc(1, total);
base = (sqfs_file_t *)file;
if (file == NULL) {
- free(wpath);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
@@ -208,50 +243,26 @@ sqfs_file_t *sqfs_open_file(const char *filename, sqfs_u32 flags)
sqfs_object_init(file, stdio_destroy, stdio_copy);
memcpy(file->name, filename, namelen);
- if (flags & SQFS_FILE_OPEN_READ_ONLY) {
- file->readonly = true;
- access_flags = GENERIC_READ;
- creation_mode = OPEN_EXISTING;
- share_mode = FILE_SHARE_READ;
- } else {
- file->readonly = false;
- access_flags = GENERIC_READ | GENERIC_WRITE;
- share_mode = 0;
-
- if (flags & SQFS_FILE_OPEN_OVERWRITE) {
- creation_mode = CREATE_ALWAYS;
- } else {
- creation_mode = CREATE_NEW;
- }
- }
-
- if (flags & SQFS_FILE_OPEN_NO_CHARSET_XFRM) {
- file->fd = CreateFileA(filename, access_flags, share_mode, NULL,
- creation_mode, FILE_ATTRIBUTE_NORMAL,
- NULL);
- } else {
- file->fd = CreateFileW(wpath, access_flags, share_mode, NULL,
- creation_mode, FILE_ATTRIBUTE_NORMAL,
- NULL);
- }
+ if (sqfs_open_native_file(&file->fd, filename, flags))
+ goto fail;
- free(wpath);
-
- if (file->fd == INVALID_HANDLE_VALUE) {
- free(file);
- return NULL;
- }
-
- if (!GetFileSizeEx(file->fd, &size)) {
- free(file);
- return NULL;
- }
+ if (!GetFileSizeEx(file->fd, &size))
+ goto fail;
file->size = size.QuadPart;
+ file->readonly = (flags & SQFS_FILE_OPEN_READ_ONLY) != 0;
+
base->read_at = stdio_read_at;
base->write_at = stdio_write_at;
base->get_size = stdio_get_size;
base->truncate = stdio_truncate;
base->get_filename = stdio_get_filename;
return base;
+fail:
+ err = GetLastError();
+ if (file->fd != INVALID_HANDLE_VALUE)
+ CloseHandle(file->fd);
+ free(file);
+ SetLastError(err);
+ return NULL;
}
diff --git a/lib/tar/Makemodule.am b/lib/tar/Makemodule.am
index 4dc5057..983467e 100644
--- a/lib/tar/Makemodule.am
+++ b/lib/tar/Makemodule.am
@@ -11,192 +11,192 @@ noinst_LIBRARIES += libtar.a
TARDATADIR=$(top_srcdir)/lib/tar/test/data
test_tar_gnu0_SOURCES = lib/tar/test/tar_simple.c
-test_tar_gnu0_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_gnu0_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_gnu0_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_gnu0_CPPFLAGS += -DTESTFILE=format-acceptance/gnu.tar
test_tar_gnu1_SOURCES = lib/tar/test/tar_simple.c
-test_tar_gnu1_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_gnu1_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_gnu1_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_gnu1_CPPFLAGS += -DTESTFILE=format-acceptance/gnu-g.tar
test_tar_gnu2_SOURCES = lib/tar/test/tar_simple.c
-test_tar_gnu2_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_gnu2_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_gnu2_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_gnu2_CPPFLAGS += -DTESTFILE=user-group-largenum/gnu.tar
test_tar_gnu2_CPPFLAGS += -DTESTUID=0x80000000 -DTESTGID=0x80000000
test_tar_gnu2_CPPFLAGS += -DTESTTS=1542995392
test_tar_gnu3_SOURCES = lib/tar/test/tar_simple.c
-test_tar_gnu3_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_gnu3_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_gnu3_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_gnu3_CPPFLAGS += -DTESTFILE=negative-mtime/gnu.tar -DTESTTS=-315622800
test_tar_gnu4_SOURCES = lib/tar/test/tar_simple.c
-test_tar_gnu4_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_gnu4_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_gnu4_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_gnu4_CPPFLAGS += -DTESTFILE=long-paths/gnu.tar -DLONG_NAME_TEST
test_tar_gnu4_CPPFLAGS += -DTESTTS=1542909670
test_tar_gnu5_SOURCES = lib/tar/test/tar_simple.c
-test_tar_gnu5_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_gnu5_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_gnu5_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_gnu5_CPPFLAGS += -DTESTFILE=large-mtime/gnu.tar -DTESTTS=8589934592L
test_tar_gnu6_SOURCES = lib/tar/test/tar_big_file.c
-test_tar_gnu6_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_gnu6_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_gnu6_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_gnu6_CPPFLAGS += -DTESTFILE=file-size/gnu.tar
test_tar_pax0_SOURCES = lib/tar/test/tar_simple.c
-test_tar_pax0_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_pax0_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_pax0_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_pax0_CPPFLAGS += -DTESTFILE=format-acceptance/pax.tar
test_tar_pax1_SOURCES = lib/tar/test/tar_simple.c
-test_tar_pax1_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_pax1_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_pax1_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_pax1_CPPFLAGS += -DTESTFILE=user-group-largenum/pax.tar
test_tar_pax1_CPPFLAGS += -DTESTUID=2147483648UL -DTESTGID=2147483648UL
test_tar_pax1_CPPFLAGS += -DTESTTS=1542995392
test_tar_pax2_SOURCES = lib/tar/test/tar_simple.c
-test_tar_pax2_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_pax2_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_pax2_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_pax2_CPPFLAGS += -DTESTFILE=large-mtime/pax.tar -DTESTTS=8589934592L
test_tar_pax3_SOURCES = lib/tar/test/tar_simple.c
-test_tar_pax3_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_pax3_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_pax3_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_pax3_CPPFLAGS += -DTESTFILE=negative-mtime/pax.tar -DTESTTS=-315622800
test_tar_pax4_SOURCES = lib/tar/test/tar_simple.c
-test_tar_pax4_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_pax4_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_pax4_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_pax4_CPPFLAGS += -DTESTFILE=long-paths/pax.tar
test_tar_pax4_CPPFLAGS += -DLONG_NAME_TEST -DTESTTS=1542909670
test_tar_pax5_SOURCES = lib/tar/test/tar_big_file.c
-test_tar_pax5_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_pax5_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_pax5_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_pax5_CPPFLAGS += -DTESTFILE=file-size/pax.tar
test_tar_ustar0_SOURCES = lib/tar/test/tar_simple.c
-test_tar_ustar0_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_ustar0_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_ustar0_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_ustar0_CPPFLAGS += -DTESTFILE=format-acceptance/ustar.tar
test_tar_ustar1_SOURCES = lib/tar/test/tar_simple.c
-test_tar_ustar1_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_ustar1_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_ustar1_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_ustar1_CPPFLAGS += -DTESTFILE=format-acceptance/ustar-pre-posix.tar
test_tar_ustar2_SOURCES = lib/tar/test/tar_simple.c
-test_tar_ustar2_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_ustar2_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_ustar2_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_ustar2_CPPFLAGS += -DTESTFILE=format-acceptance/v7.tar
test_tar_ustar3_SOURCES = lib/tar/test/tar_simple.c
-test_tar_ustar3_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_ustar3_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_ustar3_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_ustar3_CPPFLAGS += -DTESTFILE=user-group-largenum/8-digit.tar
test_tar_ustar3_CPPFLAGS += -DTESTUID=8388608 -DTESTGID=8388608
test_tar_ustar3_CPPFLAGS += -DTESTTS=1542995392
test_tar_ustar4_SOURCES = lib/tar/test/tar_simple.c
-test_tar_ustar4_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_ustar4_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_ustar4_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_ustar4_CPPFLAGS += -DTESTFILE=large-mtime/12-digit.tar
test_tar_ustar4_CPPFLAGS += -DTESTTS=8589934592L
test_tar_ustar5_SOURCES = lib/tar/test/tar_simple.c
-test_tar_ustar5_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_ustar5_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_ustar5_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_ustar5_CPPFLAGS += -DTESTFILE=long-paths/ustar.tar
test_tar_ustar5_CPPFLAGS += -DLONG_NAME_TEST -DTESTTS=1542909670
test_tar_ustar6_SOURCES = lib/tar/test/tar_big_file.c
-test_tar_ustar6_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+test_tar_ustar6_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_ustar6_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_ustar6_CPPFLAGS += -DTESTFILE=file-size/12-digit.tar
test_tar_target_filled_SOURCES = lib/tar/test/tar_target_filled.c
-test_tar_target_filled_LDADD = libtar.a libsquashfs.la libio.a libutil.a \
+test_tar_target_filled_LDADD = libtar.a libio.a libsquashfs.la libutil.a \
libcompat.a
test_tar_target_filled_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_sparse_gnu_SOURCES = lib/tar/test/tar_sparse_gnu.c
-test_tar_sparse_gnu_LDADD = libtar.a libsquashfs.la libio.a libutil.a \
+test_tar_sparse_gnu_LDADD = libtar.a libio.a libsquashfs.la libutil.a \
libcompat.a
test_tar_sparse_gnu_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_sparse_gnu0_SOURCES = lib/tar/test/tar_sparse.c
-test_tar_sparse_gnu0_LDADD = libtar.a libsquashfs.la libio.a libutil.a \
+test_tar_sparse_gnu0_LDADD = libtar.a libio.a libsquashfs.la libutil.a \
libcompat.a
test_tar_sparse_gnu0_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_sparse_gnu0_CPPFLAGS += -DTESTFILE=sparse-files/pax-gnu0-0.tar
test_tar_sparse_gnu1_SOURCES = lib/tar/test/tar_sparse.c
-test_tar_sparse_gnu1_LDADD = libtar.a libsquashfs.la libio.a libutil.a \
+test_tar_sparse_gnu1_LDADD = libtar.a libio.a libsquashfs.la libutil.a \
libcompat.a
test_tar_sparse_gnu1_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_sparse_gnu1_CPPFLAGS += -DTESTFILE=sparse-files/pax-gnu0-1.tar
test_tar_sparse_gnu2_SOURCES = lib/tar/test/tar_sparse.c
-test_tar_sparse_gnu2_LDADD = libtar.a libsquashfs.la libio.a libutil.a \
+test_tar_sparse_gnu2_LDADD = libtar.a libio.a libsquashfs.la libutil.a \
libcompat.a
test_tar_sparse_gnu2_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_sparse_gnu2_CPPFLAGS += -DTESTFILE=sparse-files/pax-gnu1-0.tar
test_tar_sparse_gnu3_SOURCES = lib/tar/test/tar_sparse.c
-test_tar_sparse_gnu3_LDADD = libtar.a libsquashfs.la libio.a libutil.a \
+test_tar_sparse_gnu3_LDADD = libtar.a libio.a libsquashfs.la libutil.a \
libcompat.a
test_tar_sparse_gnu3_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_sparse_gnu3_CPPFLAGS += -DTESTFILE=sparse-files/gnu.tar
test_tar_xattr_bsd_SOURCES = lib/tar/test/tar_xattr.c
-test_tar_xattr_bsd_LDADD = libtar.a libsquashfs.la libio.a libutil.a \
+test_tar_xattr_bsd_LDADD = libtar.a libio.a libsquashfs.la libutil.a \
libcompat.a
test_tar_xattr_bsd_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_xattr_bsd_CPPFLAGS += -DTESTFILE=xattr/xattr-libarchive.tar
test_tar_xattr_schily_SOURCES = lib/tar/test/tar_xattr.c
-test_tar_xattr_schily_LDADD = libtar.a libsquashfs.la libio.a libutil.a \
+test_tar_xattr_schily_LDADD = libtar.a libio.a libsquashfs.la libutil.a \
libcompat.a
test_tar_xattr_schily_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_xattr_schily_CPPFLAGS += -DTESTFILE=xattr/xattr-schily.tar
test_tar_xattr_schily_bin_SOURCES = lib/tar/test/tar_xattr_bin.c
-test_tar_xattr_schily_bin_LDADD = libtar.a libsquashfs.la libio.a libutil.a \
+test_tar_xattr_schily_bin_LDADD = libtar.a libio.a libsquashfs.la libutil.a \
libcompat.a
test_tar_xattr_schily_bin_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_xattr_schily_bin_CPPFLAGS += -DTESTFILE=xattr/xattr-schily-binary.tar
test_tar_iterator_SOURCES = lib/tar/test/tar_iterator.c
-test_tar_iterator_LDADD = libtar.a libsquashfs.la libxfrm.a libio.a \
+test_tar_iterator_LDADD = libtar.a libio.a libsquashfs.la libxfrm.a \
libutil.a libcompat.a $(XZ_LIBS) $(BZIP2_LIBS) \
$(ZLIB_LIBS) $(ZSTD_LIBS)
test_tar_iterator_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_iterator_CPPFLAGS += -DTESTFILE=format-acceptance/gnu.tar
test_tar_iterator2_SOURCES = lib/tar/test/tar_iterator2.c
-test_tar_iterator2_LDADD = libtar.a libsquashfs.la libio.a libxfrm.a \
+test_tar_iterator2_LDADD = libtar.a libio.a libsquashfs.la libxfrm.a \
libutil.a libcompat.a $(XZ_LIBS) $(BZIP2_LIBS) \
$(ZLIB_LIBS) $(ZSTD_LIBS)
test_tar_iterator2_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_iterator2_CPPFLAGS += -DTESTFILE=iterator/sparse.tar
test_tar_iterator3_SOURCES = lib/tar/test/tar_iterator3.c
-test_tar_iterator3_LDADD = libtar.a libsquashfs.la libio.a libxfrm.a \
+test_tar_iterator3_LDADD = libtar.a libio.a libsquashfs.la libxfrm.a \
libutil.a libcompat.a $(XZ_LIBS) $(BZIP2_LIBS) \
$(ZLIB_LIBS) $(ZSTD_LIBS)
test_tar_iterator3_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
tar_fuzz_SOURCES = lib/tar/test/tar_fuzz.c
-tar_fuzz_LDADD = libtar.a libsquashfs.la libio.a libutil.a libcompat.a
+tar_fuzz_LDADD = libtar.a libio.a libsquashfs.la libutil.a libcompat.a
test_tar_write_simple_SOURCES = lib/tar/test/tar_write_simple.c
-test_tar_write_simple_LDADD = libtar.a libsquashfs.la libio.a libutil.a \
+test_tar_write_simple_LDADD = libtar.a libio.a libsquashfs.la libutil.a \
libcompat.a
test_tar_write_simple_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR)
test_tar_write_simple_CPPFLAGS += -DTESTFILE=write/simple.tar
diff --git a/lib/util/Makemodule.am b/lib/util/Makemodule.am
index 0a0e50e..a797930 100644
--- a/lib/util/Makemodule.am
+++ b/lib/util/Makemodule.am
@@ -34,7 +34,7 @@ endif
noinst_LIBRARIES += libutil.a
test_str_table_SOURCES = lib/util/test/str_table.c
-test_str_table_LDADD = libutil.a libio.a libcompat.a
+test_str_table_LDADD = libio.a libsquashfs.la libutil.a libcompat.a
test_str_table_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(top_srcdir)/lib/util/test
test_rbtree_SOURCES = lib/util/test/rbtree.c
diff --git a/lib/util/test/str_table.c b/lib/util/test/str_table.c
index 5408fc0..75658ef 100644
--- a/lib/util/test/str_table.c
+++ b/lib/util/test/str_table.c
@@ -7,6 +7,7 @@
#include "config.h"
#include "util/str_table.h"
+#include "io/istream.h"
#include "io/file.h"
#include "compat.h"
#include "util/test.h"