aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-11-23 16:21:08 +0100
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-11-23 16:23:12 +0100
commitb4226fbb569bd39fa0198c0e823400836dd6cc2d (patch)
tree63676a72450e36cfcd80168ec7f7a81f8a7fefc4
parentf6afde3c5dcece3b4980cebcde09a9ecca9e20d8 (diff)
Add windows implementation for chdir in libcompat
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--include/compat.h2
-rw-r--r--lib/compat/Makemodule.am2
-rw-r--r--lib/compat/chdir.c56
3 files changed, 59 insertions, 1 deletions
diff --git a/include/compat.h b/include/compat.h
index 1a8f3a4..af2ac5a 100644
--- a/include/compat.h
+++ b/include/compat.h
@@ -105,6 +105,8 @@ struct stat {
int fchownat(int dirfd, const char *path, int uid, int gid, int flags);
int fchmodat(int dirfd, const char *path, int mode, int flags);
+
+int chdir(const char *path);
#else
#include <sys/types.h>
#include <sys/stat.h>
diff --git a/lib/compat/Makemodule.am b/lib/compat/Makemodule.am
index 7ba3444..fb37b46 100644
--- a/lib/compat/Makemodule.am
+++ b/lib/compat/Makemodule.am
@@ -1,5 +1,5 @@
libcompat_a_SOURCES = lib/compat/getline.c lib/compat/getsubopt.c
libcompat_a_SOURCES += lib/compat/strndup.c lib/compat/mockups.c
-libcompat_a_SOURCES += include/compat.h
+libcompat_a_SOURCES += lib/compat/chdir.c include/compat.h
noinst_LIBRARIES += libcompat.a
diff --git a/lib/compat/chdir.c b/lib/compat/chdir.c
new file mode 100644
index 0000000..b1b2d0c
--- /dev/null
+++ b/lib/compat/chdir.c
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * chdir.c
+ *
+ * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "config.h"
+#include "compat.h"
+
+#include "util/util.h"
+
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdlib.h>
+
+int chdir(const char *path)
+{
+ WCHAR *wpath, *ptr;
+ DWORD length;
+ int ret;
+
+ length = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
+ if (length <= 0) {
+ fprintf(stderr, "Converting '%s' to UTF-16: %ld\n",
+ path, GetLastError());
+ return -1;
+ }
+
+ wpath = alloc_array(sizeof(wpath[0]), length + 1);
+ if (wpath == NULL) {
+ fprintf(stderr, "Converting '%s' to UTF-16: out of memory\n",
+ path);
+ return -1;
+ }
+
+ MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, length + 1);
+ wpath[length] = '\0';
+
+ for (ptr = wpath; *ptr != '\0'; ++ptr) {
+ if (*ptr == '/')
+ *ptr = '\\';
+ }
+
+ if (!SetCurrentDirectoryW(wpath)) {
+ fprintf(stderr, "Switching to directory '%s': %ld\n",
+ path, GetLastError());
+ ret = -1;
+ } else {
+ ret = 0;
+ }
+
+ free(wpath);
+ return ret;
+}
+#endif