summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml12
-rw-r--r--NEWS3
-rw-r--r--meson.build41
-rw-r--r--meson_options.txt6
-rw-r--r--src/ring.c5
-rw-r--r--src/win32/filesystem_win32.c53
-rw-r--r--src/zix_config.h45
7 files changed, 129 insertions, 36 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 081c7b6..ad1dcc9 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,4 +1,4 @@
-# Copyright 2019-2022 David Robillard <d@drobilla.net>
+# Copyright 2019-2024 David Robillard <d@drobilla.net>
# SPDX-License-Identifier: 0BSD OR ISC
stages: [build, deploy]
@@ -95,6 +95,10 @@ mingw32:
- ninja -C build test
- meson configure -Dbuildtype=release build
- ninja -C build test
+ - meson configure -Dwin_ver=winxp build
+ - ninja -C build test
+ - meson configure -Dwin_ver=nt4 build
+ - ninja -C build test
variables:
WINEPATH: "Z:\\usr\\lib\\gcc\\i686-w64-mingw32\\10-win32"
@@ -106,6 +110,8 @@ mingw64:
- ninja -C build test
- meson configure -Dbuildtype=release build
- ninja -C build test
+ - meson configure -Dwin_ver=winxp build
+ - ninja -C build test
variables:
WINEPATH: "Z:\\usr\\lib\\gcc\\x86_64-w64-mingw32\\10-win32"
@@ -146,6 +152,10 @@ win:
- ninja -C build test
- meson configure -Dbuildtype=release build
- ninja -C build test
+ - meson configure -Dwin_ver=winxp build
+ - ninja -C build test
+ - meson configure -Dwin_ver=nt4 build
+ - ninja -C build test
# Documentation
diff --git a/NEWS b/NEWS
index 36cb979..5b9e521 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
zix (0.5.1) unstable; urgency=medium
* Add ZIX_NODISCARD attribute
+ * Add option to build for older Windows versions
* Add zix_expand_environment_strings()
* Add zix_string_view_equals()
* Avoid fdatasync() on Darwin
@@ -10,7 +11,7 @@ zix (0.5.1) unstable; urgency=medium
* Fix ring unit test when mlock() is unavailable
* Improve documentation
- -- David Robillard <d@drobilla.net> Sun, 24 Nov 2024 15:48:27 +0000
+ -- David Robillard <d@drobilla.net> Wed, 11 Dec 2024 05:21:56 +0000
zix (0.4.2) stable; urgency=medium
diff --git a/meson.build b/meson.build
index d319296..7a6047f 100644
--- a/meson.build
+++ b/meson.build
@@ -29,15 +29,6 @@ versioned_name = 'zix' + version_suffix
pkg = import('pkgconfig')
cc = meson.get_compiler('c')
-# Restrict Windows API usage to Vista and earlier
-if host_machine.system() == 'windows'
- if cc.get_id() == 'msvc'
- add_project_arguments('/D_WIN32_WINNT=0x0600', language: ['c', 'cpp'])
- else
- add_project_arguments('-D_WIN32_WINNT=0x0600', language: ['c', 'cpp'])
- endif
-endif
-
# Set global warning suppressions
warning_level = get_option('warning_level')
c_suppressions = []
@@ -171,8 +162,14 @@ elif host_machine.system() in ['dragonfly', 'freebsd', 'netbsd', 'openbsd']
'-D_BSD_SOURCE',
]
elif host_machine.system() == 'windows'
+ winvers = {
+ 'nt4': '0x0400',
+ 'winxp': '0x0501',
+ 'vista': '0x0600',
+ }
system_c_args += [
'-DWIN32_LEAN_AND_MEAN',
+ '-D_WIN32_WINNT=' + winvers[get_option('win_ver')],
]
else
system_c_args += [
@@ -251,16 +248,32 @@ else
}
windows_checks = {
+ 'CreateHardLink': template.format(
+ 'windows.h',
+ 'return CreateHardLink("l", "t", NULL);',
+ ),
'CreateSymbolicLink': template.format(
'windows.h',
'return CreateSymbolicLink("l", "t", SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);',
),
+ 'GetFinalPathNameByHandle': template.format(
+ 'windows.h',
+ 'return GetFinalPathNameByHandle(NULL, NULL, 0U, 0U);',
+ ),
+ 'VirtualLock': template.format(
+ 'windows.h',
+ 'return VirtualLock(NULL, sizeof(void*));',
+ ),
}
+ check_c_args = system_c_args
if host_machine.system() == 'darwin'
checks = posix_checks + mac_checks
elif host_machine.system() == 'windows'
checks = windows_checks
+ if cc.get_id() == 'msvc'
+ check_c_args += ['/Wall', '/WX']
+ endif
else
checks = posix_checks
@@ -269,7 +282,7 @@ else
'''#include <semaphore.h>
#include <time.h>
int main(void) { sem_t s; struct timespec t; return sem_timedwait(&s, &t); }''',
- args: system_c_args,
+ args: check_c_args,
dependencies: thread_dep,
name: 'sem_timedwait',
)
@@ -279,7 +292,13 @@ int main(void) { sem_t s; struct timespec t; return sem_timedwait(&s, &t); }''',
endif
foreach name, check_code : checks
- if cc.links(check_code, args: system_c_args, name: name)
+ is_mingw = host_machine.system() == 'windows' and cc.get_id() == 'gcc'
+ if is_mingw and name in ['CreateSymbolicLink']
+ message('Ignoring MinGW stub @0@'.format(name))
+ continue
+ endif
+
+ if cc.links(check_code, args: check_c_args, name: name)
platform_c_args += ['-DHAVE_@0@'.format(name.to_upper())]
endif
endforeach
diff --git a/meson_options.txt b/meson_options.txt
index 0ae44d1..f35da04 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,4 +1,4 @@
-# Copyright 2020-2023 David Robillard <d@drobilla.net>
+# Copyright 2020-2024 David Robillard <d@drobilla.net>
# SPDX-License-Identifier: 0BSD OR ISC
option('benchmarks', type: 'feature', yield: true,
@@ -33,3 +33,7 @@ option('tests_cpp', type: 'feature', yield: true,
option('title', type: 'string', value: 'Zix',
description: 'Project title')
+
+option('win_ver', type: 'combo', value: 'vista',
+ choices: ['nt4', 'winxp', 'vista'],
+ description: 'Latest Windows API version to use')
diff --git a/src/ring.c b/src/ring.c
index 4341906..cb8a47e 100644
--- a/src/ring.c
+++ b/src/ring.c
@@ -9,7 +9,7 @@
#include <zix/allocator.h>
#include <zix/status.h>
-#if defined(_WIN32)
+#if USE_VIRTUALLOCK
# include <windows.h>
#elif USE_MLOCK
# include <sys/mman.h>
@@ -108,7 +108,7 @@ zix_ring_free(ZixRing* const ring)
ZixStatus
zix_ring_mlock(ZixRing* const ring)
{
-#if defined(_WIN32)
+#if USE_VIRTUALLOCK
return (VirtualLock(ring, sizeof(ZixRing)) &&
VirtualLock(ring->buf, ring->size))
? ZIX_STATUS_SUCCESS
@@ -119,6 +119,7 @@ zix_ring_mlock(ZixRing* const ring)
mlock(ring->buf, ring->size));
#else
+ (void)ring;
return ZIX_STATUS_NOT_SUPPORTED;
#endif
}
diff --git a/src/win32/filesystem_win32.c b/src/win32/filesystem_win32.c
index d26d789..d311bf8 100644
--- a/src/win32/filesystem_win32.c
+++ b/src/win32/filesystem_win32.c
@@ -183,13 +183,14 @@ zix_file_unlock(FILE* const file, const ZixFileLockMode mode)
char*
zix_canonical_path(ZixAllocator* const allocator, const char* const path)
{
- char full[MAX_PATH] = {0};
- if (!path || !GetFullPathName(path, MAX_PATH, full, NULL)) {
+ if (!path) {
return NULL;
}
+#if USE_GETFINALPATHNAMEBYHANDLE // Vista+
+
const HANDLE h =
- CreateFile(full,
+ CreateFile(path,
FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
@@ -197,27 +198,39 @@ zix_canonical_path(ZixAllocator* const allocator, const char* const path)
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
- const DWORD flags = FILE_NAME_NORMALIZED | VOLUME_NAME_DOS;
- const DWORD final_size = GetFinalPathNameByHandle(h, NULL, 0U, flags);
- if (!final_size) {
- CloseHandle(h);
+ if (h == INVALID_HANDLE_VALUE) {
return NULL;
}
- char* const final = (char*)zix_calloc(allocator, (size_t)final_size + 1U, 1U);
- if (!final || !GetFinalPathNameByHandle(h, final, final_size + 1U, flags)) {
- zix_free(allocator, final);
- CloseHandle(h);
- return NULL;
- }
-
- if (final_size > 4U && !strncmp(final, "\\\\?\\", 4)) {
- memmove(final, final + 4U, final_size - 4U);
- final[final_size - 4U] = '\0';
+ const DWORD flags = FILE_NAME_NORMALIZED | VOLUME_NAME_DOS;
+ const DWORD length = GetFinalPathNameByHandle(h, NULL, 0U, flags);
+ TCHAR* final = NULL;
+ if (length) {
+ final = (TCHAR*)zix_calloc(allocator, (size_t)length + 1U, sizeof(TCHAR));
+ if (final) {
+ GetFinalPathNameByHandle(h, final, length + 1U, flags);
+ }
}
CloseHandle(h);
return final;
+
+#else // Fall back to "full path iff it exists" for older Windows
+
+ TCHAR* full = NULL;
+ if (GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES) {
+ const DWORD length = GetFullPathName(path, 0U, NULL, NULL);
+ if (length) {
+ full = (TCHAR*)zix_calloc(allocator, (size_t)length + 1U, sizeof(TCHAR));
+ if (full) {
+ GetFullPathName(path, length + 1U, full, NULL);
+ }
+ }
+ }
+
+ return full;
+
+#endif
}
static ZixFileType
@@ -312,7 +325,13 @@ zix_create_directory_symlink(const char* const target_path,
ZixStatus
zix_create_hard_link(const char* const target_path, const char* const link_path)
{
+#if USE_CREATEHARDLINK
return zix_windows_status(CreateHardLink(link_path, target_path, NULL));
+#else
+ (void)target_path;
+ (void)link_path;
+ return ZIX_STATUS_NOT_SUPPORTED;
+#endif
}
char*
diff --git a/src/zix_config.h b/src/zix_config.h
index 0aab586..6bbc92b 100644
--- a/src/zix_config.h
+++ b/src/zix_config.h
@@ -1,4 +1,4 @@
-// Copyright 2021-2023 David Robillard <d@drobilla.net>
+// Copyright 2021-2024 David Robillard <d@drobilla.net>
// SPDX-License-Identifier: ISC
/*
@@ -78,9 +78,16 @@
# endif
# endif
-// Windows: CreateSymbolicLink()
+// Windows XP: CreateHardLink()
+# ifndef HAVE_CREATEHARDLINK
+# if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0501
+# define HAVE_CREATEHARDLINK 1
+# endif
+# endif
+
+// Windows Vista: CreateSymbolicLink()
# ifndef HAVE_CREATESYMBOLICLINK
-# if defined(_MSC_VER) && _MSC_VER >= 1910
+# if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600 && !defined(__MINGW32__)
# define HAVE_CREATESYMBOLICLINK 1
# endif
# endif
@@ -99,6 +106,13 @@
# endif
# endif
+// Windows Vista: GetFinalPathNameByHandle()
+# ifndef HAVE_GETFINALPATHNAMEBYHANDLE
+# if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600
+# define HAVE_GETFINALPATHNAMEBYHANDLE 1
+# endif
+# endif
+
// POSIX.1-2001: mlock()
# ifndef HAVE_MLOCK
# if ZIX_POSIX_VERSION >= 200112L
@@ -148,6 +162,13 @@
# endif
# endif
+// Windows XP: VirtualLock
+# ifndef HAVE_VIRTUALLOCK
+# if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0501
+# define HAVE_VIRTUALLOCK 1
+# endif
+# endif
+
#endif // !defined(ZIX_NO_DEFAULT_CONFIG)
/*
@@ -176,6 +197,12 @@
# define USE_COPY_FILE_RANGE 0
#endif
+#if defined(HAVE_CREATEHARDLINK) && HAVE_CREATEHARDLINK
+# define USE_CREATEHARDLINK 1
+#else
+# define USE_CREATEHARDLINK 0
+#endif
+
#if defined(HAVE_CREATESYMBOLICLINK) && HAVE_CREATESYMBOLICLINK
# define USE_CREATESYMBOLICLINK 1
#else
@@ -194,6 +221,12 @@
# define USE_FLOCK 0
#endif
+#if defined(HAVE_GETFINALPATHNAMEBYHANDLE) && HAVE_GETFINALPATHNAMEBYHANDLE
+# define USE_GETFINALPATHNAMEBYHANDLE 1
+#else
+# define USE_GETFINALPATHNAMEBYHANDLE 0
+#endif
+
#if defined(HAVE_MLOCK) && HAVE_MLOCK
# define USE_MLOCK 1
#else
@@ -236,4 +269,10 @@
# define USE_SYSCONF 0
#endif
+#if defined(HAVE_VIRTUALLOCK) && HAVE_VIRTUALLOCK
+# define USE_VIRTUALLOCK 1
+#else
+# define USE_VIRTUALLOCK 0
+#endif
+
#endif // ZIX_CONFIG_H