@@ -1255,6 +1255,82 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
12551255}
12561256#endif
12571257
1258+ char * mingw_strbuf_realpath (struct strbuf * resolved , const char * path )
1259+ {
1260+ wchar_t wpath [MAX_PATH ];
1261+ HANDLE h ;
1262+ DWORD ret ;
1263+ int len ;
1264+ const char * last_component = NULL ;
1265+ char * append = NULL ;
1266+
1267+ if (xutftowcs_path (wpath , path ) < 0 )
1268+ return NULL ;
1269+
1270+ h = CreateFileW (wpath , 0 ,
1271+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE , NULL ,
1272+ OPEN_EXISTING , FILE_FLAG_BACKUP_SEMANTICS , NULL );
1273+
1274+ /*
1275+ * strbuf_realpath() allows the last path component to not exist. If
1276+ * that is the case, now it's time to try without last component.
1277+ */
1278+ if (h == INVALID_HANDLE_VALUE &&
1279+ GetLastError () == ERROR_FILE_NOT_FOUND ) {
1280+ /* cut last component off of `wpath` */
1281+ wchar_t * p = wpath + wcslen (wpath );
1282+
1283+ while (p != wpath )
1284+ if (* (-- p ) == L'/' || * p == L'\\' )
1285+ break ; /* found start of last component */
1286+
1287+ if (p != wpath && (last_component = find_last_dir_sep (path ))) {
1288+ append = xstrdup (last_component + 1 ); /* skip directory separator */
1289+ /*
1290+ * Do not strip the trailing slash at the drive root, otherwise
1291+ * the path would be e.g. `C:` (which resolves to the
1292+ * _current_ directory on that drive).
1293+ */
1294+ if (p [-1 ] == L':' )
1295+ p [1 ] = L'\0' ;
1296+ else
1297+ * p = L'\0' ;
1298+ h = CreateFileW (wpath , 0 , FILE_SHARE_READ |
1299+ FILE_SHARE_WRITE | FILE_SHARE_DELETE ,
1300+ NULL , OPEN_EXISTING ,
1301+ FILE_FLAG_BACKUP_SEMANTICS , NULL );
1302+ }
1303+ }
1304+
1305+ if (h == INVALID_HANDLE_VALUE ) {
1306+ realpath_failed :
1307+ FREE_AND_NULL (append );
1308+ return NULL ;
1309+ }
1310+
1311+ ret = GetFinalPathNameByHandleW (h , wpath , ARRAY_SIZE (wpath ), 0 );
1312+ CloseHandle (h );
1313+ if (!ret || ret >= ARRAY_SIZE (wpath ))
1314+ goto realpath_failed ;
1315+
1316+ len = wcslen (wpath ) * 3 ;
1317+ strbuf_grow (resolved , len );
1318+ len = xwcstoutf (resolved -> buf , normalize_ntpath (wpath ), len );
1319+ if (len < 0 )
1320+ goto realpath_failed ;
1321+ resolved -> len = len ;
1322+
1323+ if (append ) {
1324+ /* Use forward-slash, like `normalize_ntpath()` */
1325+ strbuf_complete (resolved , '/' );
1326+ strbuf_addstr (resolved , append );
1327+ FREE_AND_NULL (append );
1328+ }
1329+
1330+ return resolved -> buf ;
1331+
1332+ }
1333+
12581334char * mingw_getcwd (char * pointer , int len )
12591335{
12601336 wchar_t cwd [MAX_PATH ], wpointer [MAX_PATH ];
0 commit comments