diff options
Diffstat (limited to 'dev/build/windows/patches_coq/ln.c')
-rw-r--r-- | dev/build/windows/patches_coq/ln.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/dev/build/windows/patches_coq/ln.c b/dev/build/windows/patches_coq/ln.c new file mode 100644 index 00000000..5e02c72b --- /dev/null +++ b/dev/build/windows/patches_coq/ln.c @@ -0,0 +1,137 @@ +// (C) 2016 Intel Deutschland GmbH +// Author: Michael Soegtrop +// Released to the public under CC0 +// See https://creativecommons.org/publicdomain/zero/1.0/ + +// Windows drop in repacement for Linux ln +// Supports command form "ln TARGET LINK_NAME" +// Supports -s and -f options +// Does not support hard links to folders (but symlinks are ok) + +#include <windows.h> +#include <stdio.h> +#include <tchar.h> + +// Cygwin MinGW doesn't have this Vista++ function in windows.h +#ifdef UNICODE + WINBASEAPI BOOLEAN APIENTRY CreateSymbolicLinkW ( LPCWSTR, LPCWSTR, DWORD ); + #define CreateSymbolicLink CreateSymbolicLinkW + #define CommandLineToArgv CommandLineToArgvW +#else + WINBASEAPI BOOLEAN APIENTRY CreateSymbolicLinkA ( LPCSTR, LPCSTR, DWORD ); + #define CreateSymbolicLink CreateSymbolicLinkA + #define CommandLineToArgv CommandLineToArgvA +#endif +#define SYMBOLIC_LINK_FLAG_DIRECTORY 1 + +int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLineA, int nShowCmd ) +{ + int iarg; + BOOL symbolic = FALSE; + BOOL force = FALSE; + BOOL folder; + const _TCHAR *target; + const _TCHAR *link; + LPTSTR lpCmdLine; + int argc; + LPTSTR *argv; + + // Parse command line + // This is done explicitly here for two reasons + // 1.) MinGW doesn't seem to support _tmain, wWinMain and the like + // 2.) We want to make sure that CommandLineToArgv is used + lpCmdLine = GetCommandLine(); + argv = CommandLineToArgv( lpCmdLine, &argc ); + + // Get target and link name + if( argc<3 ) + { + _ftprintf( stderr, _T("Expecting at least 2 arguments, got %d\n"), argc-1 ); + return 1; + } + target = argv[argc-2]; + link = argv[argc-1]; + + // Parse options + // The last two arguments are interpreted as file names + // All other arguments must be -s or -f os multi letter options like -sf + for(iarg=1; iarg<argc-2; iarg++ ) + { + const _TCHAR *pos = argv[iarg]; + if( *pos != _T('-') ) + { + _ftprintf( stderr, _T("Command line option expected in argument %d\n"), iarg ); + return 1; + } + pos ++; + + while( *pos ) + { + switch( *pos ) + { + case _T('s') : symbolic = TRUE; break; + case _T('f') : force = TRUE; break; + default : + _ftprintf( stderr, _T("Unknown option '%c'\n"), *pos ); + return 1; + } + pos ++; + } + } + + #ifdef IGNORE_SYMBOLIC + symbolic = FALSE; + #endif + + // Check if link already exists - delete it if force is given or abort + { + if( GetFileAttributes(link) != INVALID_FILE_ATTRIBUTES ) + { + if( force ) + { + if( !DeleteFile( link ) ) + { + _ftprintf( stderr, _T("Error deleting file '%s'\n"), link ); + return 1; + } + } + else + { + _ftprintf( stderr, _T("File '%s' exists!\n"), link ); + return 1; + } + } + } + + // Check if target is a folder + folder = ( (GetFileAttributes(target) & FILE_ATTRIBUTE_DIRECTORY) ) != 0; + + // Create link + if(symbolic) + { + if( !CreateSymbolicLink( link, target, folder ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0 ) ) + { + _ftprintf( stderr, _T("Error creating symbolic link '%s' -> '%s'!\n"), link, target ); + return 1; + } + } + else + { + if( folder ) + { + _ftprintf( stderr, _T("Cannot create hard link to folder") ); + return 1; + } + else + { + if( !CreateHardLink( link, target, NULL ) ) + { + _ftprintf( stderr, _T("Error creating hard link '%s' -> '%s'!\n"), link, target ); + return 1; + } + } + } + + // Everything is fine + return 0; +}
\ No newline at end of file |