Hello Martin, Your patch did a '#define _WIN32_WINNT 0x0500' in order to access the CreateHardLink() function. This means, this function did not exist on Windows NT 4.
Unfortunately, my mingw test system is running in a Windows NT 4 SP5 machine; this is the only version of Windows that I can use without paying bucks to Microsoft. And on this system, the 'test-link.exe' exits with exit code 128 - not 0, 1, or 77. It's a failure in the runtime linking, and would affect any executable that includes the compiled link.c code. In general I am not in favour of supporting systems more than 8 years old. But since this is the only Windows machine I have access to, after the shutdown of testdrive... With the attached patch, I can link and run test-link.exe, and it exits with code 77 - as expected for a platform that does not support hard links. Transforming code that works for Windows 2000 or newer into code that works also for older versions is tedious but straightforward: - Look up the types of the functions, - Look up the decorated names of the functions, and the DLLs where they come from, - Use LoadLibrary and GetProcAddress to get the function pointers. 2009-01-20 Bruno Haible <br...@clisp.org> Make the 'link' module link on Windows NT 4. * lib/link.c (_WIN32_WINNT): Don't define. (CreateHardLinkFuncType): New type. (CreateHardLinkFunc, initialized): New variables. (initialize): New function. (link): Invoke CreateHardLink indirectly through the function pointer. *** lib/link.c.orig 2009-01-21 00:34:52.000000000 +0100 --- lib/link.c 2009-01-21 00:34:24.000000000 +0100 *************** *** 21,36 **** #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ #define WIN32_LEAN_AND_MEAN - #define _WIN32_WINNT 0x0500 #include <unistd.h> #include <windows.h> #include <errno.h> int link (const char *path1, const char *path2) { ! if (CreateHardLink (path2, path1, NULL) == 0) { /* It is not documented which errors CreateHardLink() can produce. * The following conversions are based on tests on a Windows XP SP2 --- 21,62 ---- #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ #define WIN32_LEAN_AND_MEAN #include <unistd.h> #include <windows.h> #include <errno.h> + /* CreateHardLink was introduced only in Windows 2000. */ + typedef BOOL (WINAPI * CreateHardLinkFuncType) (LPCTSTR lpFileName, + LPCTSTR lpExistingFileName, + LPSECURITY_ATTRIBUTES lpSecurityAttributes); + static CreateHardLinkFuncType CreateHardLinkFunc = NULL; + static BOOL initialized = FALSE; + + static void + initialize (void) + { + HMODULE kernel32 = LoadLibrary ("kernel32.dll"); + if (kernel32 != NULL) + { + CreateHardLinkFunc = + (CreateHardLinkFuncType) GetProcAddress (kernel32, "CreateHardLinkA"); + } + initialized = TRUE; + } + int link (const char *path1, const char *path2) { ! if (!initialized) ! initialize (); ! if (CreateHardLinkFunc == NULL) ! { ! /* System does not support hard links. */ ! errno = EPERM; ! return -1; ! } ! if (CreateHardLinkFunc (path2, path1, NULL) == 0) { /* It is not documented which errors CreateHardLink() can produce. * The following conversions are based on tests on a Windows XP SP2