@@ -1207,6 +1207,82 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
12071207}
12081208#endif 
12091209
1210+ char  * mingw_strbuf_realpath (struct  strbuf  * resolved , const  char  * path )
1211+ {
1212+ 	wchar_t  wpath [MAX_PATH ];
1213+ 	HANDLE  h ;
1214+ 	DWORD  ret ;
1215+ 	int  len ;
1216+ 	const  char  * last_component  =  NULL ;
1217+ 	char  * append  =  NULL ;
1218+ 
1219+ 	if  (xutftowcs_path (wpath , path ) <  0 )
1220+ 		return  NULL ;
1221+ 
1222+ 	h  =  CreateFileW (wpath , 0 ,
1223+ 			FILE_SHARE_READ  | FILE_SHARE_WRITE  | FILE_SHARE_DELETE , NULL ,
1224+ 			OPEN_EXISTING , FILE_FLAG_BACKUP_SEMANTICS , NULL );
1225+ 
1226+ 	/* 
1227+ 	 * strbuf_realpath() allows the last path component to not exist. If 
1228+ 	 * that is the case, now it's time to try without last component. 
1229+ 	 */ 
1230+ 	if  (h  ==  INVALID_HANDLE_VALUE  && 
1231+ 	    GetLastError () ==  ERROR_FILE_NOT_FOUND ) {
1232+ 		/* cut last component off of `wpath` */ 
1233+ 		wchar_t  * p  =  wpath  +  wcslen (wpath );
1234+ 
1235+ 		while  (p  !=  wpath )
1236+ 			if  (* (-- p ) ==  L'/'  ||  * p  ==  L'\\' )
1237+ 				break ; /* found start of last component */ 
1238+ 
1239+ 		if  (p  !=  wpath  &&  (last_component  =  find_last_dir_sep (path ))) {
1240+ 			append  =  xstrdup (last_component  +  1 ); /* skip directory separator */ 
1241+ 			/* 
1242+ 			 * Do not strip the trailing slash at the drive root, otherwise 
1243+ 			 * the path would be e.g. `C:` (which resolves to the 
1244+ 			 * _current_ directory on that drive). 
1245+ 			 */ 
1246+ 			if  (p [-1 ] ==  L':' )
1247+ 				p [1 ] =  L'\0' ;
1248+ 			else 
1249+ 				* p  =  L'\0' ;
1250+ 			h  =  CreateFileW (wpath , 0 , FILE_SHARE_READ  |
1251+ 					FILE_SHARE_WRITE  | FILE_SHARE_DELETE ,
1252+ 					NULL , OPEN_EXISTING ,
1253+ 					FILE_FLAG_BACKUP_SEMANTICS , NULL );
1254+ 		}
1255+ 	}
1256+ 
1257+ 	if  (h  ==  INVALID_HANDLE_VALUE ) {
1258+ realpath_failed :
1259+ 		FREE_AND_NULL (append );
1260+ 		return  NULL ;
1261+ 	}
1262+ 
1263+ 	ret  =  GetFinalPathNameByHandleW (h , wpath , ARRAY_SIZE (wpath ), 0 );
1264+ 	CloseHandle (h );
1265+ 	if  (!ret  ||  ret  >= ARRAY_SIZE (wpath ))
1266+ 		goto realpath_failed ;
1267+ 
1268+ 	len  =  wcslen (wpath ) *  3 ;
1269+ 	strbuf_grow (resolved , len );
1270+ 	len  =  xwcstoutf (resolved -> buf , normalize_ntpath (wpath ), len );
1271+ 	if  (len  <  0 )
1272+ 		goto realpath_failed ;
1273+ 	resolved -> len  =  len ;
1274+ 
1275+ 	if  (append ) {
1276+ 		/* Use forward-slash, like `normalize_ntpath()` */ 
1277+ 		strbuf_complete (resolved , '/' );
1278+ 		strbuf_addstr (resolved , append );
1279+ 		FREE_AND_NULL (append );
1280+ 	}
1281+ 
1282+ 	return  resolved -> buf ;
1283+ 
1284+ }
1285+ 
12101286char  * mingw_getcwd (char  * pointer , int  len )
12111287{
12121288	wchar_t  cwd [MAX_PATH ], wpointer [MAX_PATH ];
0 commit comments