From: Charles Wilson Date: Fri, 4 Sep 2009 06:11:54 +0000 (-0400) Subject: Refine win32 api checks and usage. X-Git-Tag: v2.8.0~386 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=197cc2d1a296cab3b2966e6d5b9dc9e81ea6fbdf;p=thirdparty%2Flibarchive.git Refine win32 api checks and usage. * tar/bsdtar_windows.c: Remove WINVER, _WIN32_WINNT defines. (wequallen): Remove unused function. (canHardLinkW): Ditto. * cpio/cpio_windows.c: Remove WINVER, _WIN32_WINNT defines. * libarchive/archive_windows.c: Remove WINVER, _WIN32_WINNT defines. * configure.ac [mingw|cygwin]: Add WINVER and _WIN32_WINNT defines to config.h. Use new AC_CHECK_STDCALL_FUNC macro to check for CreateHardLinkA symbol. Don't check for CreateSymbolicLink symbol. * CMakeLists.txt [WIN32]: Add WINVER and _WIN32_WINNT defines to cache. Check for CreateHardLinkA symbol, not CreateHardLink. Don't check for CreateSymbolicLink. * build/autoconf/check_stdcall_func.m4: New. SVN-Revision: 1422 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 457601667..fa7d5b28d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,11 @@ IF(WIN32 AND NOT CYGWIN) SET(ENABLE_CPIO_SHARED ON) ENDIF(WIN32 AND NOT CYGWIN) +IF(WIN32) + SET(_WIN32_WINNT 0x0500 CACHE INTERNAL "Setting _WIN32_WINNT to 0x0500 for Windows 2000 APIs") + SET(WINVER 0x0500 CACHE INTERNAL "Setting WINVER to 0x0500 for Windows 2000 APIs") +ENDIF(WIN32) + # INCLUDE(CheckCSourceRuns) INCLUDE(CheckFileOffsetBits) @@ -331,8 +336,7 @@ CHECK_FUNCTION_EXISTS(SHA512_Init HAVE_SHA512) # # Check functions # -CHECK_SYMBOL_EXISTS(CreateHardLink "windows.h" HAVE_CREATEHARDLINK) -CHECK_SYMBOL_EXISTS(CreateSymbolicLink "windows.h" HAVE_CREATESYMBOLICLINK) +CHECK_SYMBOL_EXISTS(CreateHardLinkA "windows.h" HAVE_CREATEHARDLINKA) CHECK_FUNCTION_EXISTS_GLIBC(chflags HAVE_CHFLAGS) CHECK_FUNCTION_EXISTS_GLIBC(chown HAVE_CHOWN) CHECK_FUNCTION_EXISTS_GLIBC(chroot HAVE_CHROOT) diff --git a/build/autoconf/check_stdcall_func.m4 b/build/autoconf/check_stdcall_func.m4 new file mode 100644 index 000000000..926b046c5 --- /dev/null +++ b/build/autoconf/check_stdcall_func.m4 @@ -0,0 +1,51 @@ +# AC_LANG_STDCALL_FUNC_LINK_TRY(FUNCTION, SIGNATURE) +# ------------------------------- +# Produce a source which links correctly iff the FUNCTION exists. +AC_DEFUN([AC_LANG_STDCALL_FUNC_LINK_TRY], +[_AC_LANG_DISPATCH([$0], _AC_LANG, $@)]) + +# AC_CHECK_STDCALL_FUNC(FUNCTION, SIGNATURE, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# ----------------------------------------------------------------- +AC_DEFUN([AC_CHECK_STDCALL_FUNC], +[AS_VAR_PUSHDEF([ac_var], [ac_cv_func_$1])dnl +AC_CACHE_CHECK([for $1], ac_var, +[AC_LINK_IFELSE([AC_LANG_STDCALL_FUNC_LINK_TRY([$1],[$2])], + [AS_VAR_SET(ac_var, yes)], + [AS_VAR_SET(ac_var, no)])]) +AS_IF([test AS_VAR_GET(ac_var) = yes], [$3], [$4])dnl +AS_VAR_POPDEF([ac_var])dnl +])# AC_CHECK_FUNC + +# AC_LANG_STDCALL_FUNC_LINK_TRY(C)(FUNCTION, SIGNATURE) +# ---------------------------------- +# Don't include because on OSF/1 3.0 it includes +# which includes which contains a +# prototype for select. Similarly for bzero. +m4_define([AC_LANG_STDCALL_FUNC_LINK_TRY(C)], +[AC_LANG_PROGRAM( +[/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char __stdcall $1 ( $2 ) below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char __stdcall $1 ( $2 ); +char (*f) ( $2 ); +], +[/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$1) || defined (__stub___$1) +choke me +#else +f = $1; +#endif +])]) + +# AC_LANG_STDCALL_FUNC_LINK_TRY(C++)(FUNCTION) +# ------------------------------------ +m4_copy([AC_LANG_STDCALL_FUNC_LINK_TRY(C)], [AC_LANG_STDCALL_FUNC_LINK_TRY(C++)]) + diff --git a/configure.ac b/configure.ac index 6cd2da1e3..d9652336c 100644 --- a/configure.ac +++ b/configure.ac @@ -179,6 +179,14 @@ esac AM_CONDITIONAL([BUILD_BSDCPIO], [ test "$build_bsdcpio" = yes ]) AM_CONDITIONAL([STATIC_BSDCPIO], [ test "$static_bsdcpio" = yes ]) +# Set up defines needed before including any headers +case $host in + *mingw* | *cygwin* ) + AC_DEFINE([_WIN32_WINNT], 0x0500, [Define to '0x0500' for Windows 2000 APIs.]) + AC_DEFINE([WINVER], 0x0500, [Define to '0x0500' for Windows 2000 APIs.]) + ;; +esac + # Checks for header files. AC_HEADER_STDC AC_HEADER_DIRENT @@ -335,7 +343,11 @@ AC_FUNC_STAT AC_FUNC_STRERROR_R AC_FUNC_STRFTIME AC_FUNC_VPRINTF -AC_CHECK_FUNCS([CreateHardLinkA CreateSymbolicLink]) +# check for: +# CreateHardLinkA(LPCSTR, LPCSTR, LPSECURITY_ATTRIBUTES) +# To avoid necessity for including windows.h or special forward declaration +# workarounds, we use 'void *' for 'struct SECURITY_ATTRIBUTES *' +AC_CHECK_STDCALL_FUNC([CreateHardLinkA],[const char *, const char *, void *]) AC_CHECK_FUNCS([chflags chown chroot]) AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fork]) AC_CHECK_FUNCS([fstat ftruncate futimes geteuid getpid]) diff --git a/cpio/cpio_windows.c b/cpio/cpio_windows.c index 54779641a..5fd253769 100644 --- a/cpio/cpio_windows.c +++ b/cpio/cpio_windows.c @@ -26,8 +26,6 @@ */ #if defined(_WIN32) && !defined(__CYGWIN__) -#define _WIN32_WINNT 0x0500 -#define WINVER 0x0500 #include "cpio_platform.h" #include diff --git a/libarchive/archive_windows.c b/libarchive/archive_windows.c index b4f21a2a4..2e5e8578a 100644 --- a/libarchive/archive_windows.c +++ b/libarchive/archive_windows.c @@ -45,8 +45,6 @@ */ #if defined(_WIN32) && !defined(__CYGWIN__) -#define _WIN32_WINNT 0x0500 -#define WINVER 0x0500 #include "archive_platform.h" #include diff --git a/tar/bsdtar_windows.c b/tar/bsdtar_windows.c index 3f871029b..baf13103a 100644 --- a/tar/bsdtar_windows.c +++ b/tar/bsdtar_windows.c @@ -26,8 +26,6 @@ */ #if defined(_WIN32) && !defined(__CYGWIN__) -#define _WIN32_WINNT 0x0500 -#define WINVER 0x0500 #include "bsdtar_platform.h" #include @@ -206,86 +204,6 @@ __tar_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode, return (handle); } -static size_t -wequallen(const wchar_t *s1, const wchar_t *s2) -{ - size_t i = 0; - - while (*s1 != L'\0' && *s2 != L'\0' && *s1 == *s2) { - ++s1; ++s2; ++i; - } - return (i); -} - -/* Check that path1 and path2 can be hard-linked by each other. - * Both arguments must be made by permissive_name function. - */ -static int -canHardLinkW(const wchar_t *path1, const wchar_t *path2) -{ - wchar_t root[MAX_PATH]; - wchar_t fs[32]; - const wchar_t *s; - int r; - - r = wequallen(path1, path2); - /* Is volume-name the same? */ - if (r < 7) - return (0); - if (wcsncmp(path1, L"\\\\?\\UNC\\", 8) == 0) { - int len; - - s = path1 + 8; - if (*s == L'\\') - return (0); - /* 012345678 - * Name : "\\?\UNC\Server\Share\" - * ^ search - */ - s = wcschr(++s, L'\\'); - if (s == NULL) - return (0); - if (*++s == L'\\') - return (0); - /* 012345678 - * Name : "\\?\UNC\Server\Share\" - * ^ search - */ - s = wcschr(++s, L'\\'); - if (s == NULL) - return (0); - s++; - /* 012345678 - * Name : "\\?\UNC\Server\Share\xxxx" - * ^--- len ----^ - */ - len = (int)(s - path1 - 8); - /* Is volume-name the same? */ - if (r < len + 8) - return (0); - /* Is volume-name too long? */ - if (sizeof(root) -3 < len) - return (0); - root[0] = root[1] = L'\\'; - wcsncpy(root + 2, path1 + 8 , len); - /* root : "\\Server\Share\" */ - root[2 + len] = L'\0'; - } else if (wcsncmp(path1, L"\\\\?\\", 4) == 0) { - s = path1 + 4; - if ((!iswalpha(*s)) || s[1] != L':' || s[2] != L'\\') - return (0); - wcsncpy(root, path1 + 4, 3); - root[3] = L'\0'; - } else - return (0); - if (!GetVolumeInformationW(root, NULL, 0, NULL, NULL, NULL, fs, sizeof(fs))) - return (0); - if (wcscmp(fs, L"NTFS") == 0) - return (1); - else - return (0); -} - int __tar_chdir(const char *path) {