@@ -1235,6 +1235,82 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
12351235}
12361236#endif
12371237
1238+ char * mingw_strbuf_realpath (struct strbuf * resolved , const char * path )
1239+ {
1240+ wchar_t wpath [MAX_PATH ];
1241+ HANDLE h ;
1242+ DWORD ret ;
1243+ int len ;
1244+ const char * last_component = NULL ;
1245+ char * append = NULL ;
1246+
1247+ if (xutftowcs_path (wpath , path ) < 0 )
1248+ return NULL ;
1249+
1250+ h = CreateFileW (wpath , 0 ,
1251+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE , NULL ,
1252+ OPEN_EXISTING , FILE_FLAG_BACKUP_SEMANTICS , NULL );
1253+
1254+ /*
1255+ * strbuf_realpath() allows the last path component to not exist. If
1256+ * that is the case, now it's time to try without last component.
1257+ */
1258+ if (h == INVALID_HANDLE_VALUE &&
1259+ GetLastError () == ERROR_FILE_NOT_FOUND ) {
1260+ /* cut last component off of `wpath` */
1261+ wchar_t * p = wpath + wcslen (wpath );
1262+
1263+ while (p != wpath )
1264+ if (* (-- p ) == L'/' || * p == L'\\' )
1265+ break ; /* found start of last component */
1266+
1267+ if (p != wpath && (last_component = find_last_dir_sep (path ))) {
1268+ append = xstrdup (last_component + 1 ); /* skip directory separator */
1269+ /*
1270+ * Do not strip the trailing slash at the drive root, otherwise
1271+ * the path would be e.g. `C:` (which resolves to the
1272+ * _current_ directory on that drive).
1273+ */
1274+ if (p [-1 ] == L':' )
1275+ p [1 ] = L'\0' ;
1276+ else
1277+ * p = L'\0' ;
1278+ h = CreateFileW (wpath , 0 , FILE_SHARE_READ |
1279+ FILE_SHARE_WRITE | FILE_SHARE_DELETE ,
1280+ NULL , OPEN_EXISTING ,
1281+ FILE_FLAG_BACKUP_SEMANTICS , NULL );
1282+ }
1283+ }
1284+
1285+ if (h == INVALID_HANDLE_VALUE ) {
1286+ realpath_failed :
1287+ FREE_AND_NULL (append );
1288+ return NULL ;
1289+ }
1290+
1291+ ret = GetFinalPathNameByHandleW (h , wpath , ARRAY_SIZE (wpath ), 0 );
1292+ CloseHandle (h );
1293+ if (!ret || ret >= ARRAY_SIZE (wpath ))
1294+ goto realpath_failed ;
1295+
1296+ len = wcslen (wpath ) * 3 ;
1297+ strbuf_grow (resolved , len );
1298+ len = xwcstoutf (resolved -> buf , normalize_ntpath (wpath ), len );
1299+ if (len < 0 )
1300+ goto realpath_failed ;
1301+ resolved -> len = len ;
1302+
1303+ if (append ) {
1304+ /* Use forward-slash, like `normalize_ntpath()` */
1305+ strbuf_complete (resolved , '/' );
1306+ strbuf_addstr (resolved , append );
1307+ FREE_AND_NULL (append );
1308+ }
1309+
1310+ return resolved -> buf ;
1311+
1312+ }
1313+
12381314char * mingw_getcwd (char * pointer , int len )
12391315{
12401316 wchar_t cwd [MAX_PATH ], wpointer [MAX_PATH ];
0 commit comments