aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-06-15 18:13:26 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-06-15 18:13:26 +0200
commit8bff2715bfdfd2e6ce0c707f1310b169d4e454d0 (patch)
tree50c4dfdb2e4daa5b8c94697261ff8081389b449c
parentc9f37f069c6e294e58c64c9f5ad94f0bd3e2fd02 (diff)
libcompat: Add a helper to get/set OS error state
On Unix like OSes, this saves/restores errno, on Windows both errno and GetLastError state are saved/restored. This should make it simpler to preserve that across function calls. Additionally, while tracking down uses of GetLastError, some places where the error code was printed out directly where replaced with instances of w32_perror. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--bin/rdsquashfs/src/restore_fstree.c11
-rw-r--r--include/compat.h28
-rw-r--r--lib/common/src/perror.c32
-rw-r--r--lib/compat/src/chdir.c3
-rw-r--r--lib/compat/src/path_to_windows.c3
-rw-r--r--lib/io/src/win32/dir_iterator.c6
-rw-r--r--lib/sqfs/src/win32/io_file.c15
-rw-r--r--lib/sqfs/src/win32/istream.c20
-rw-r--r--lib/sqfs/src/win32/ostream.c12
-rw-r--r--lib/util/src/mkdir_p.c8
10 files changed, 76 insertions, 62 deletions
diff --git a/bin/rdsquashfs/src/restore_fstree.c b/bin/rdsquashfs/src/restore_fstree.c
index ea9d4f1..d80d24b 100644
--- a/bin/rdsquashfs/src/restore_fstree.c
+++ b/bin/rdsquashfs/src/restore_fstree.c
@@ -20,7 +20,10 @@ static int create_node(const sqfs_tree_node_t *n, const char *name, int flags)
switch (n->inode->base.mode & S_IFMT) {
case S_IFDIR:
if (!CreateDirectoryW(wpath, NULL)) {
- if (GetLastError() != ERROR_ALREADY_EXISTS)
+ os_error_t err = get_os_error_state();
+ set_os_error_state(err);
+
+ if (err.w32_errno != ERROR_ALREADY_EXISTS)
goto fail;
}
break;
@@ -41,12 +44,12 @@ static int create_node(const sqfs_tree_node_t *n, const char *name, int flags)
free(wpath);
return 0;
fail: {
- DWORD err = GetLastError();
+ os_error_t err = get_os_error_state();
free(wpath);
- SetLastError(err);
+ set_os_error_state(err);
w32_perror(name);
- if (err == ERROR_FILE_EXISTS) {
+ if (err.w32_errno == ERROR_FILE_EXISTS) {
fputs("\nHINT: this could be caused by case "
"sensitivity on Windows.\n", stderr);
}
diff --git a/include/compat.h b/include/compat.h
index 7c9f937..f376665 100644
--- a/include/compat.h
+++ b/include/compat.h
@@ -265,4 +265,32 @@ int sqfs_tools_fprintf(FILE *strm, const char *fmt, ...) PRINTF_ATTRIB(2, 3);
#define putc sqfs_tools_fputc
#endif
+/****************************** error handling ******************************/
+
+#if defined(_WIN32) || defined(__WINDOWS__)
+typedef struct {
+ int unix_errno;
+ DWORD w32_errno;
+} os_error_t;
+
+static SQFS_INLINE os_error_t get_os_error_state(void)
+{
+ os_error_t out = { errno, GetLastError() };
+ return out;
+}
+
+static SQFS_INLINE void set_os_error_state(os_error_t err)
+{
+ SetLastError(err.w32_errno);
+ errno = err.unix_errno;
+}
+#else
+#include <errno.h>
+
+typedef int os_error_t;
+
+#define get_os_error_state() errno
+#define set_os_error_state(err) errno = (err)
+#endif
+
#endif /* COMPAT_H */
diff --git a/lib/common/src/perror.c b/lib/common/src/perror.c
index 5f62748..edefc9e 100644
--- a/lib/common/src/perror.c
+++ b/lib/common/src/perror.c
@@ -8,22 +8,10 @@
#include <stdio.h>
-#if defined(_WIN32) || defined(__WINDOWS__)
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#else
-#include <errno.h>
-#include <string.h>
-#endif
-
void sqfs_perror(const char *file, const char *action, int error_code)
{
+ os_error_t syserror;
const char *errstr;
-#if defined(_WIN32) || defined(__WINDOWS__)
- DWORD syserror = GetLastError();
-#else
- int syserror = errno;
-#endif
switch (error_code) {
case SQFS_ERROR_ALLOC:
@@ -82,6 +70,7 @@ void sqfs_perror(const char *file, const char *action, int error_code)
break;
}
+ syserror = get_os_error_state();
if (file != NULL)
fprintf(stderr, "%s: ", file);
@@ -89,24 +78,13 @@ void sqfs_perror(const char *file, const char *action, int error_code)
fprintf(stderr, "%s: ", action);
fprintf(stderr, "%s.\n", errstr);
+ set_os_error_state(syserror);
if (error_code == SQFS_ERROR_IO) {
#if defined(_WIN32) || defined(__WINDOWS__)
- LPVOID msg = NULL;
-
- FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, syserror,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR)&msg, 0, NULL);
-
- fprintf(stderr, "OS error: %s\n", (const char *)msg);
-
- if (msg != NULL)
- LocalFree(msg);
+ w32_perror("OS error");
#else
- fprintf(stderr, "OS error: %s\n", strerror(syserror));
+ perror("OS error");
#endif
}
}
diff --git a/lib/compat/src/chdir.c b/lib/compat/src/chdir.c
index f695e2a..17d814f 100644
--- a/lib/compat/src/chdir.c
+++ b/lib/compat/src/chdir.c
@@ -21,8 +21,7 @@ int chdir(const char *path)
return -1;
if (!SetCurrentDirectoryW(wpath)) {
- fprintf(stderr, "Switching to directory '%s': %ld\n",
- path, GetLastError());
+ w32_perror(path);
ret = -1;
} else {
ret = 0;
diff --git a/lib/compat/src/path_to_windows.c b/lib/compat/src/path_to_windows.c
index ff3a5d2..5a35f50 100644
--- a/lib/compat/src/path_to_windows.c
+++ b/lib/compat/src/path_to_windows.c
@@ -18,8 +18,7 @@ WCHAR *path_to_windows(const char *input)
length = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0);
if (length <= 0) {
- fprintf(stderr, "Converting UTF-8 path to UTF-16: %ld\n",
- GetLastError());
+ w32_perror("Converting UTF-8 path to UTF-16");
return NULL;
}
diff --git a/lib/io/src/win32/dir_iterator.c b/lib/io/src/win32/dir_iterator.c
index c99fd64..22b4870 100644
--- a/lib/io/src/win32/dir_iterator.c
+++ b/lib/io/src/win32/dir_iterator.c
@@ -58,11 +58,15 @@ static int dir_iterator_next(dir_iterator_t *it, dir_entry_t **out)
if (w32->state == 0 && !w32->is_first) {
if (!FindNextFileW(w32->dirhnd, &w32->ent)) {
- if (GetLastError() == ERROR_NO_MORE_FILES) {
+ os_error_t err = get_os_error_state();
+
+ if (err.w32_errno == ERROR_NO_MORE_FILES) {
w32->state = 1;
} else {
w32->state = SQFS_ERROR_IO;
}
+
+ set_os_error_state(err);
}
}
diff --git a/lib/sqfs/src/win32/io_file.c b/lib/sqfs/src/win32/io_file.c
index dbd80d8..4d76b94 100644
--- a/lib/sqfs/src/win32/io_file.c
+++ b/lib/sqfs/src/win32/io_file.c
@@ -60,7 +60,9 @@ static sqfs_object_t *stdio_copy(const sqfs_object_t *base)
0, FALSE, DUPLICATE_SAME_ACCESS);
if (!ret) {
+ os_error_t err = get_os_error_state();
free(copy);
+ set_os_error_state(err);
return NULL;
}
@@ -163,7 +165,8 @@ int sqfs_open_native_file(sqfs_file_handle_t *out, const char *filename,
{
int access_flags, creation_mode, share_mode;
WCHAR *wpath = NULL;
- DWORD length, err;
+ os_error_t err;
+ DWORD length;
*out = INVALID_HANDLE_VALUE;
@@ -209,9 +212,9 @@ int sqfs_open_native_file(sqfs_file_handle_t *out, const char *filename,
creation_mode, FILE_ATTRIBUTE_NORMAL,
NULL);
- err = GetLastError();
+ err = get_os_error_state();
free(wpath);
- SetLastError(err);
+ set_os_error_state(err);
}
return (*out == INVALID_HANDLE_VALUE) ? SQFS_ERROR_IO : 0;
@@ -223,7 +226,7 @@ sqfs_file_t *sqfs_open_file(const char *filename, sqfs_u32 flags)
size_t namelen, total;
LARGE_INTEGER size;
sqfs_file_t *base;
- DWORD err;
+ os_error_t err;
namelen = strlen(filename);
total = sizeof(*file) + 1;
@@ -259,10 +262,10 @@ sqfs_file_t *sqfs_open_file(const char *filename, sqfs_u32 flags)
base->get_filename = stdio_get_filename;
return base;
fail:
- err = GetLastError();
+ err = get_os_error_state();
if (file->fd != INVALID_HANDLE_VALUE)
CloseHandle(file->fd);
free(file);
- SetLastError(err);
+ set_os_error_state(err);
return NULL;
}
diff --git a/lib/sqfs/src/win32/istream.c b/lib/sqfs/src/win32/istream.c
index 3f7eb83..aeb3352 100644
--- a/lib/sqfs/src/win32/istream.c
+++ b/lib/sqfs/src/win32/istream.c
@@ -49,15 +49,15 @@ static int precache(sqfs_istream_t *strm)
if (!ReadFile(file->hnd, file->buffer + file->buffer_used,
diff, &actual, NULL)) {
- DWORD error = GetLastError();
+ os_error_t error = get_os_error_state();
- if (error == ERROR_HANDLE_EOF ||
- error == ERROR_BROKEN_PIPE) {
+ if (error.w32_errno == ERROR_HANDLE_EOF ||
+ error.w32_errno == ERROR_BROKEN_PIPE) {
file->eof = true;
break;
}
- SetLastError(error);
+ set_os_error_state(error);
return SQFS_ERROR_IO;
}
@@ -136,9 +136,9 @@ int sqfs_istream_open_handle(sqfs_istream_t **out, const char *path,
file->path = strdup(path);
if (file->path == NULL) {
- DWORD temp = GetLastError();
+ os_error_t err = get_os_error_state();
free(file);
- SetLastError(temp);
+ set_os_error_state(err);
return SQFS_ERROR_ALLOC;
}
@@ -146,10 +146,10 @@ int sqfs_istream_open_handle(sqfs_istream_t **out, const char *path,
GetCurrentProcess(), &file->hnd,
0, FALSE, DUPLICATE_SAME_ACCESS);
if (!ret) {
- DWORD temp = GetLastError();
+ os_error_t err = get_os_error_state();
free(file->path);
free(file);
- SetLastError(temp);
+ set_os_error_state(err);
return SQFS_ERROR_IO;
}
@@ -180,9 +180,9 @@ int sqfs_istream_open_file(sqfs_istream_t **out, const char *path,
ret = sqfs_istream_open_handle(out, path, hnd, flags);
if (ret) {
- DWORD temp = GetLastError();
+ os_error_t err = get_os_error_state();
CloseHandle(hnd);
- SetLastError(temp);
+ set_os_error_state(err);
return ret;
}
diff --git a/lib/sqfs/src/win32/ostream.c b/lib/sqfs/src/win32/ostream.c
index 3ebeb8b..2f85c29 100644
--- a/lib/sqfs/src/win32/ostream.c
+++ b/lib/sqfs/src/win32/ostream.c
@@ -59,9 +59,9 @@ static int realize_sparse(file_ostream_t *file)
ret = write_data(file, buffer, diff);
if (ret) {
- DWORD temp = GetLastError();
+ os_error_t err = get_os_error_state();
free(buffer);
- SetLastError(temp);
+ set_os_error_state(err);
return ret;
}
@@ -157,10 +157,10 @@ int sqfs_ostream_open_handle(sqfs_ostream_t **out, const char *path,
GetCurrentProcess(), &file->hnd,
0, FALSE, DUPLICATE_SAME_ACCESS);
if (!ret) {
- DWORD temp = GetLastError();
+ os_error_t err = get_os_error_state();
free(file->path);
free(file);
- SetLastError(temp);
+ set_os_error_state(err);
return SQFS_ERROR_IO;
}
@@ -191,9 +191,9 @@ int sqfs_ostream_open_file(sqfs_ostream_t **out, const char *path,
ret = sqfs_ostream_open_handle(out, path, hnd, flags);
if (ret) {
- DWORD temp = GetLastError();
+ os_error_t err = get_os_error_state();
CloseHandle(hnd);
- SetLastError(temp);
+ set_os_error_state(err);
return SQFS_ERROR_IO;
}
diff --git a/lib/util/src/mkdir_p.c b/lib/util/src/mkdir_p.c
index 993d8ec..784e4ae 100644
--- a/lib/util/src/mkdir_p.c
+++ b/lib/util/src/mkdir_p.c
@@ -113,11 +113,11 @@ int mkdir_p(const char *path)
}
if (!CreateDirectoryW(wpath, NULL)) {
- error = GetLastError();
+ os_error_t err = get_os_error_state();
+ set_os_error_state(err);
- if (error != ERROR_ALREADY_EXISTS) {
- fprintf(stderr, "Creating %s: %ld\n",
- path, error);
+ if (err.w32_errno != ERROR_ALREADY_EXISTS) {
+ w32_perror(path);
goto fail;
}
}