@@ -969,7 +969,8 @@ static int has_valid_directory_prefix(wchar_t *wfilename)
969
969
return 1 ;
970
970
}
971
971
972
- static int get_reparse_point_link_len (const WCHAR * wpath , DWORD * ptag );
972
+ static int readlink_1 (const WCHAR * wpath , char * tmpbuf , int * plen , DWORD * ptag );
973
+
973
974
int mingw_lstat (const char * file_name , struct stat * buf )
974
975
{
975
976
WIN32_FILE_ATTRIBUTE_DATA fdata ;
@@ -989,10 +990,12 @@ int mingw_lstat(const char *file_name, struct stat *buf)
989
990
}
990
991
991
992
if (GetFileAttributesExW (wfilename , GetFileExInfoStandard , & fdata )) {
992
- /* for reparse points, use get_reparse_point_link_len to get the link tag and length */
993
+ /* for reparse points, get the link tag and length */
993
994
if (fdata .dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ) {
994
- link_len = get_reparse_point_link_len (wfilename , & reparse_tag );
995
- if (link_len < 0 )
995
+ char tmpbuf [MAX_LONG_PATH ];
996
+
997
+ if (readlink_1 (wfilename , tmpbuf , & link_len ,
998
+ & reparse_tag ) < 0 )
996
999
return -1 ;
997
1000
}
998
1001
buf -> st_ino = 0 ;
@@ -2969,10 +2972,11 @@ typedef struct _REPARSE_DATA_BUFFER {
2969
2972
} REPARSE_DATA_BUFFER , * PREPARSE_DATA_BUFFER ;
2970
2973
#endif
2971
2974
2972
- static int get_reparse_point (const WCHAR * wpath , REPARSE_DATA_BUFFER * b , size_t siz , WCHAR * * pwbuf )
2975
+ static int readlink_1 (const WCHAR * wpath , char * tmpbuf , int * plen , DWORD * ptag )
2973
2976
{
2974
2977
HANDLE handle ;
2975
2978
WCHAR * wbuf ;
2979
+ REPARSE_DATA_BUFFER * b = alloca (MAXIMUM_REPARSE_DATA_BUFFER_SIZE );
2976
2980
DWORD dummy ;
2977
2981
2978
2982
/* read reparse point data */
@@ -2985,15 +2989,15 @@ static int get_reparse_point(const WCHAR *wpath, REPARSE_DATA_BUFFER *b, size_t
2985
2989
return -1 ;
2986
2990
}
2987
2991
if (!DeviceIoControl (handle , FSCTL_GET_REPARSE_POINT , NULL , 0 , b ,
2988
- siz , & dummy , NULL )) {
2992
+ MAXIMUM_REPARSE_DATA_BUFFER_SIZE , & dummy , NULL )) {
2989
2993
errno = err_win_to_posix (GetLastError ());
2990
2994
CloseHandle (handle );
2991
2995
return -1 ;
2992
2996
}
2993
2997
CloseHandle (handle );
2994
2998
2995
2999
/* get target path for symlinks or mount points (aka 'junctions') */
2996
- switch (b -> ReparseTag ) {
3000
+ switch (( * ptag = b -> ReparseTag ) ) {
2997
3001
case IO_REPARSE_TAG_SYMLINK :
2998
3002
wbuf = (WCHAR * ) (((char * ) b -> SymbolicLinkReparseBuffer .PathBuffer )
2999
3003
+ b -> SymbolicLinkReparseBuffer .SubstituteNameOffset );
@@ -3007,52 +3011,28 @@ static int get_reparse_point(const WCHAR *wpath, REPARSE_DATA_BUFFER *b, size_t
3007
3011
+ b -> MountPointReparseBuffer .SubstituteNameLength ) = 0 ;
3008
3012
break ;
3009
3013
default :
3010
- wbuf = NULL ;
3011
- break ;
3012
- }
3013
-
3014
- * pwbuf = wbuf ;
3015
- return 0 ;
3016
- }
3017
-
3018
- static int get_reparse_point_link_len (const WCHAR * wpath , DWORD * ptag )
3019
- {
3020
- WCHAR * wbuf ;
3021
- REPARSE_DATA_BUFFER * b = alloca (MAXIMUM_REPARSE_DATA_BUFFER_SIZE );
3022
- int len ;
3023
-
3024
- if (get_reparse_point (wpath , b , MAXIMUM_REPARSE_DATA_BUFFER_SIZE , & wbuf ) < 0 )
3014
+ errno = EINVAL ;
3025
3015
return -1 ;
3026
- if (wbuf == NULL ) {
3027
- * ptag = b -> ReparseTag ;
3028
- return MAX_LONG_PATH ; /* return value for compatibility */
3029
3016
}
3030
3017
3031
- len = WideCharToMultiByte (CP_UTF8 , 0 , normalize_ntpath (wbuf ), -1 , 0 , 0 , NULL , NULL );
3032
- if (len ) {
3033
- * ptag = b -> ReparseTag ;
3034
- return len - 1 ;
3035
- }
3036
- errno = ERANGE ;
3037
- return -1 ;
3018
+ if ((* plen =
3019
+ xwcstoutf (tmpbuf , normalize_ntpath (wbuf ), MAX_LONG_PATH )) < 0 )
3020
+ return -1 ;
3021
+ return 0 ;
3038
3022
}
3039
3023
3040
3024
int readlink (const char * path , char * buf , size_t bufsiz )
3041
3025
{
3042
- WCHAR wpath [MAX_LONG_PATH ], * wbuf ;
3043
- REPARSE_DATA_BUFFER * b = alloca (MAXIMUM_REPARSE_DATA_BUFFER_SIZE );
3026
+ WCHAR wpath [MAX_LONG_PATH ];
3044
3027
char tmpbuf [MAX_LONG_PATH ];
3045
3028
int len ;
3029
+ DWORD tag ;
3046
3030
3047
3031
if (xutftowcs_long_path (wpath , path ) < 0 )
3048
3032
return -1 ;
3049
3033
3050
- if (get_reparse_point (wpath , b , MAXIMUM_REPARSE_DATA_BUFFER_SIZE , & wbuf ) < 0 )
3051
- return -1 ;
3052
- if (wbuf == NULL ) {
3053
- errno = EINVAL ;
3034
+ if (readlink_1 (wpath , tmpbuf , & len , & tag ) < 0 )
3054
3035
return -1 ;
3055
- }
3056
3036
3057
3037
/*
3058
3038
* Adapt to strange readlink() API: Copy up to bufsiz *bytes*, potentially
@@ -3061,8 +3041,6 @@ int readlink(const char *path, char *buf, size_t bufsiz)
3061
3041
* so convert to a (hopefully large enough) temporary buffer, then memcpy
3062
3042
* the requested number of bytes (including '\0' for robustness).
3063
3043
*/
3064
- if ((len = xwcstoutf (tmpbuf , normalize_ntpath (wbuf ), MAX_LONG_PATH )) < 0 )
3065
- return -1 ;
3066
3044
memcpy (buf , tmpbuf , min (bufsiz , len + 1 ));
3067
3045
return min (bufsiz , len );
3068
3046
}
0 commit comments