2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-18 01:52:17 +00:00

Initial supprort for creating symlinks in the git layout.

[SVN r84524]
This commit is contained in:
Steven Watanabe
2013-05-27 00:02:43 +00:00
parent 1138feb932
commit df2b34d63c
7 changed files with 570 additions and 2 deletions

View File

@@ -29,6 +29,10 @@
#include <ctype.h>
#ifdef OS_NT
#include <windows.h>
#endif
#if defined(USE_EXECUNIX)
# include <sys/types.h>
# include <sys/wait.h>
@@ -425,6 +429,11 @@ void load_builtins()
char const * args [] = { "path", 0 };
bind_builtin( "MAKEDIR", builtin_makedir, 0, args );
}
{
const char * args [] = { "path", 0 };
bind_builtin( "READLINK", builtin_readlink, 0, args );
}
/* Initialize builtin modules. */
init_set();
@@ -1827,6 +1836,94 @@ LIST * builtin_makedir( FRAME * frame, int flags )
: list_new( object_copy( list_front( path ) ) );
}
LIST *builtin_readlink( FRAME * frame, int flags )
{
const char * path = object_str( list_front( lol_get( frame->args, 0 ) ) );
#ifdef OS_NT
/* This struct is declared in ntifs.h which is
* part of the Windows Driver Kit.
*/
typedef struct _REPARSE_DATA_BUFFER {
ULONG ReparseTag;
USHORT ReparseDataLength;
USHORT Reserved;
union {
struct {
USHORT SubstituteNameOffset;
USHORT SubstituteNameLength;
USHORT PrintNameOffset;
USHORT PrintNameLength;
ULONG Flags;
WCHAR PathBuffer[ 1 ];
} SymbolicLinkReparseBuffer;
struct {
USHORT SubstituteNameOffset;
USHORT SubstituteNameLength;
USHORT PrintNameOffset;
USHORT PrintNameLength;
WCHAR PathBuffer[ 1 ];
} MountPointReparseBuffer;
struct {
UCHAR DataBuffer[ 1 ];
} GenericReparseBuffer;
};
} REPARSE_DATA_BUFFER;
HANDLE hLink = CreateFileA( path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL );
DWORD n;
union {
REPARSE_DATA_BUFFER reparse;
char data[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
} buf;
int okay = DeviceIoControl(hLink, FSCTL_GET_REPARSE_POINT, NULL, 0, &buf, sizeof(buf), &n, NULL);
CloseHandle( hLink );
if (okay && buf.reparse.ReparseTag == IO_REPARSE_TAG_SYMLINK )
{
int index = buf.reparse.SymbolicLinkReparseBuffer.SubstituteNameOffset / 2;
int length = buf.reparse.SymbolicLinkReparseBuffer.SubstituteNameLength / 2;
char cbuf[MAX_PATH + 1];
int numchars = WideCharToMultiByte( CP_ACP, 0, buf.reparse.SymbolicLinkReparseBuffer.PathBuffer + index, length, cbuf, sizeof(cbuf), NULL, NULL );
if( numchars >= sizeof(cbuf) )
{
return 0;
}
cbuf[numchars] = '\0';
return list_new( object_new( cbuf ) );
}
return 0;
#else
char static_buf[256];
char * buf = static_buf;
size_t bufsize = 256;
LIST * result = 0;
while (1) {
ssize_t len = readlink( path, buf, bufsize );
if ( len < 0 )
{
break;
}
else if ( len < bufsize )
{
buf[ len ] = '\0';
result = list_new( object_new( buf ) );
break;
}
if ( buf != static_buf )
BJAM_FREE( buf );
bufsize *= 2;
buf = BJAM_MALLOC( bufsize );
}
if ( buf != static_buf )
BJAM_FREE( buf );
return result;
#endif
}
#ifdef HAVE_PYTHON

View File

@@ -63,6 +63,7 @@ LIST *builtin_pad( FRAME * frame, int flags );
LIST *builtin_precious( FRAME * frame, int flags );
LIST *builtin_self_path( FRAME * frame, int flags );
LIST *builtin_makedir( FRAME * frame, int flags );
LIST *builtin_readlink( FRAME * frame, int flags );
void backtrace( FRAME *frame );
extern int last_update_now_status;

View File

@@ -122,6 +122,19 @@ int file_collect_dir_content_( file_info_t * const d )
ff->is_file = !ff->is_dir;
ff->exists = 1;
timestamp_from_filetime( &ff->time, &finfo.ftLastWriteTime );
// Use the timestamp of the link target, not the link itself
// (i.e. stat instead of lstat)
if ( finfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT )
{
HANDLE hLink = CreateFileA( pathname->value, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
BY_HANDLE_FILE_INFORMATION target_finfo[ 1 ];
if ( hLink != INVALID_HANDLE_VALUE && GetFileInformationByHandle( hLink, target_finfo ) )
{
ff->is_file = target_finfo->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? 0 : 1;
ff->is_dir = target_finfo->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? 1 : 0;
timestamp_from_filetime( &ff->time, &target_finfo->ftLastWriteTime );
}
}
}
}
while ( FindNextFile( findHandle, &finfo ) );

View File

@@ -14,7 +14,6 @@
#include "object.h"
#ifdef OS_NT
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif