Changeset 1165 in kBuild for trunk/src/kmk/w32
- Timestamp:
- Sep 30, 2007 7:36:23 AM (18 years ago)
- Location:
- trunk/src/kmk/w32
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/w32/pathstuff.c
r1127 r1165 83 83 84 84 #if 1 /* bird */ 85 /* 86 * Corrects the case of a path. 87 * Expects a fullpath! 88 * Added by bird for the $(abspath ) function and w32ify 89 */ 90 void 91 w32_fixcase(char *pszPath) 92 { 93 static char s_szLast[260]; 94 unsigned cchLast; 95 96 #ifndef NDEBUG 97 # define my_assert(expr) \ 98 do { \ 99 if (!(expr)) { \ 100 printf("my_assert: %s, file %s, line %d\npszPath=%s\npsz=%s\n", \ 101 #expr, __FILE__, __LINE__, pszPath, psz); \ 102 __debugbreak(); \ 103 exit(1); \ 104 } \ 105 } while (0) 106 #else 107 # define my_assert(expr) do {} while (0) 108 #endif 109 110 char *psz = pszPath; 111 if (*psz == '/' || *psz == '\\') 112 { 113 if (psz[1] == '/' || psz[1] == '\\') 114 { 115 /* UNC */ 116 my_assert(psz[1] == '/' || psz[1] == '\\'); 117 my_assert(psz[2] != '/' && psz[2] != '\\'); 118 119 /* skip server name */ 120 psz += 2; 121 while (*psz != '\\' && *psz != '/') 122 { 123 if (!*psz) 124 return; 125 *psz++ = toupper(*psz); 126 } 127 128 /* skip the share name */ 129 psz++; 130 my_assert(*psz != '/' && *psz != '\\'); 131 while (*psz != '\\' && *psz != '/') 132 { 133 if (!*psz) 134 return; 135 *psz++ = toupper(*psz); 136 } 137 my_assert(*psz == '/' || *psz == '\\'); 138 psz++; 139 } 140 else 141 { 142 /* Unix spec */ 143 psz++; 144 } 145 } 146 else 147 { 148 /* Drive letter */ 149 my_assert(psz[1] == ':'); 150 *psz = toupper(*psz); 151 my_assert(psz[0] >= 'A' && psz[0] <= 'Z'); 152 my_assert(psz[2] == '/' || psz[2] == '\\'); 153 psz += 3; 154 } 155 156 /* 157 * Try make use of the result from the previous call. 158 * This is ignorant to slashes and similar, but may help even so. 159 */ 160 if ( s_szLast[0] == pszPath[0] 161 && (psz - pszPath == 1 || s_szLast[1] == pszPath[1]) 162 && (psz - pszPath <= 2 || s_szLast[2] == pszPath[2]) 163 ) 164 { 165 char *pszLast = &s_szLast[psz - pszPath]; 166 char *pszCur = psz; 167 for (;;) 168 { 169 const char ch1 = *pszCur; 170 const char ch2 = *pszLast; 171 if ( ch1 != ch2 172 && (ch1 != '\\' || ch2 != '/') 173 && (ch1 != '/' || ch2 != '\\')) 174 { 175 if ( tolower(ch1) != tolower(ch2) 176 && toupper(ch1) != toupper(ch2)) 177 break; 178 /* optimistic, component mismatch will be corrected in the next loop. */ 179 *pszCur = ch2; 180 } 181 if (ch1 == '/' || ch1 == '\\') 182 psz = pszCur + 1; 183 else if (ch1 == '\0') 184 { 185 psz = pszCur; 186 break; 187 } 188 pszCur++; 189 pszLast++; 190 } 191 } 192 193 /* 194 * Pointing to the first char after the unc or drive specifier, 195 * or in case of a cache hit, the first non-matching char (following a slash of course). 196 */ 197 while (*psz) 198 { 199 WIN32_FIND_DATA FindFileData; 200 HANDLE hDir; 201 char chSaved0; 202 char chSaved1; 203 char *pszEnd; 204 int iLongNameDiff; 205 206 207 /* find the end of the component. */ 208 pszEnd = psz; 209 while (*pszEnd && *pszEnd != '/' && *pszEnd != '\\') 210 pszEnd++; 211 212 /* replace the end with "?\0" */ 213 chSaved0 = pszEnd[0]; 214 chSaved1 = pszEnd[1]; 215 pszEnd[0] = '?'; 216 pszEnd[1] = '\0'; 217 218 /* find the right filename. */ 219 hDir = FindFirstFile(pszPath, &FindFileData); 220 pszEnd[1] = chSaved1; 221 if (!hDir) 222 { 223 cchLast = psz - pszPath; 224 memcpy(s_szLast, pszPath, cchLast + 1); 225 pszEnd[0] = chSaved0; 226 return; 227 } 228 pszEnd[0] = '\0'; 229 while ( (iLongNameDiff = stricmp(FindFileData.cFileName, psz)) 230 && stricmp(FindFileData.cAlternateFileName, psz)) 231 { 232 if (!FindNextFile(hDir, &FindFileData)) 233 { 234 cchLast = psz - pszPath; 235 memcpy(s_szLast, pszPath, cchLast + 1); 236 pszEnd[0] = chSaved0; 237 return; 238 } 239 } 240 strcpy(psz, !iLongNameDiff ? FindFileData.cFileName : FindFileData.cAlternateFileName); 241 pszEnd[0] = chSaved0; 242 FindClose(hDir); 243 244 /* advance to the next component */ 245 if (!chSaved0) 246 { 247 psz = pszEnd; 248 break; 249 } 250 psz = pszEnd + 1; 251 my_assert(*psz != '/' && *psz != '\\'); 252 } 253 254 /* *psz == '\0', the end. */ 255 cchLast = psz - pszPath; 256 memcpy(s_szLast, pszPath, cchLast + 1); 257 #undef my_assert 258 } 259 260 #define MY_FileNameInformation 9 261 262 typedef struct _MY_FILE_NAME_INFORMATION 263 { 264 ULONG FileNameLength; 265 WCHAR FileName[1]; 266 } MY_FILE_NAME_INFORMATION, *PMY_FILE_NAME_INFORMATION; 267 268 typedef struct _IO_STATUS_BLOCK 269 { 270 union 271 { 272 LONG Status; 273 PVOID Pointer; 274 }; 275 ULONG_PTR Information; 276 } MY_IO_STATUS_BLOCK, *PMY_IO_STATUS_BLOCK; 277 278 static BOOL g_fInitialized = FALSE; 279 static LONG (NTAPI *g_pfnNtQueryInformationFile)(HANDLE FileHandle, 280 PMY_IO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, 281 ULONG Length, ULONG FileInformationClass); 282 283 284 int 285 nt_get_filename_info(const char *pszPath, char *pszFull, size_t cchFull) 286 { 287 static char abBuf[8192]; 288 PMY_FILE_NAME_INFORMATION pFileNameInfo = (PMY_FILE_NAME_INFORMATION)abBuf; 289 MY_IO_STATUS_BLOCK Ios; 290 LONG rcNt; 291 HANDLE hFile; 292 293 /* 294 * Check for NtQueryInformationFile the first time around. 295 */ 296 if (!g_fInitialized) 297 { 298 g_fInitialized = TRUE; 299 if (!getenv("KMK_DONT_USE_NT_QUERY_INFORMATION_FILE")) 300 *(FARPROC *)&g_pfnNtQueryInformationFile = 301 GetProcAddress(LoadLibrary("ntdll.dll"), "NtQueryInformationFile"); 302 } 303 if (!g_pfnNtQueryInformationFile) 304 return -1; 305 306 /* 307 * Try open the path and query its file name information. 308 */ 309 hFile = CreateFile(pszPath, 310 GENERIC_READ, 311 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 312 NULL, 313 OPEN_EXISTING, 314 FILE_FLAG_BACKUP_SEMANTICS, 315 NULL); 316 if (hFile) 317 { 318 memset(&Ios, 0, sizeof(Ios)); 319 rcNt = g_pfnNtQueryInformationFile(hFile, &Ios, abBuf, sizeof(abBuf), MY_FileNameInformation); 320 CloseHandle(hFile); 321 if (rcNt >= 0) 322 { 323 /* 324 * The FileNameInformation we get is relative to where the volume is mounted, 325 * so we have to extract the driveletter prefix ourselves. 326 * 327 * FIXME: This will probably not work for volumes mounted in NTFS sub-directories. 328 */ 329 int cchOut; 330 int fUnc = 0; 331 char *psz = pszFull; 332 if (pszPath[0] == '\\' || pszPath[0] == '/') 333 { 334 /* unc or root of volume */ 335 if ( (pszPath[1] == '\\' || pszPath[1] == '/') 336 && (pszPath[2] != '\\' || pszPath[2] == '/')) 337 { 338 /* unc - we get the server + name back */ 339 *psz++ = '\\'; 340 fUnc = 1; 341 } 342 else 343 { 344 /* root slash */ 345 *psz++ = _getdrive() + 'A' - 1; 346 *psz++ = ':'; 347 } 348 } 349 else if (pszPath[1] == ':' && isalpha(pszPath[0])) 350 { 351 /* drive letter */ 352 *psz++ = toupper(pszPath[0]); 353 *psz++ = ':'; 354 } 355 else 356 { 357 /* relative */ 358 *psz++ = _getdrive() + 'A' - 1; 359 *psz++ = ':'; 360 } 361 362 cchOut = WideCharToMultiByte(CP_ACP, 0, 363 pFileNameInfo->FileName, pFileNameInfo->FileNameLength / sizeof(WCHAR), 364 psz, cchFull - (psz - pszFull) - 2, NULL, NULL); 365 if (cchOut > 0) 366 { 367 const char *pszEnd; 368 369 /* upper case the server and share */ 370 if (fUnc) 371 { 372 for (psz++; *psz != '/' && *psz != '\\'; psz++) 373 *psz = toupper(*psz); 374 for (psz++; *psz != '/' && *psz != '\\'; psz++) 375 *psz = toupper(*psz); 376 } 377 378 /* add trailing slash on directories if input has it. */ 379 pszEnd = strchr(pszPath, '\0'); 380 if ( (pszEnd[-1] == '/' || pszEnd[-1] == '\\') 381 && psz[cchOut - 1] != '\\' 382 && psz[cchOut - 1] != '//') 383 psz[cchOut++] = '\\'; 384 385 /* make sure it's terminated */ 386 psz[cchOut] = '\0'; 387 return 0; 388 } 389 return -3; 390 } 391 } 392 return -2; 393 } 394 395 void 396 nt_fullpath(const char *pszPath, char *pszFull, size_t cchFull) 397 { 398 #if 0 399 static int s_cHits = 0; 400 static int s_cFallbacks = 0; 401 #endif 402 403 /* 404 * The simple case, the file / dir / whatever exists and can be 405 * queried without problems. 406 */ 407 if (nt_get_filename_info(pszPath, pszFull, cchFull) == 0) 408 { 409 #if 0 410 fprintf(stderr, "nt #%d - %s\n", ++s_cHits, pszFull); 411 #endif 412 return; 413 } 414 if (g_pfnNtQueryInformationFile) 415 { 416 /* do _fullpath and drop off path elements until we get a hit... - later */ 417 } 418 419 /* 420 * For now, simply fall back on the old method. 421 */ 422 _fullpath(pszFull, pszPath, cchFull); 423 w32_fixcase(pszFull); 424 #if 0 425 fprintf(stderr, "fb #%d - %s\n", ++s_cFallbacks, pszFull); 426 #endif 427 } 428 429 #endif /* bird */ 430 85 extern void nt_fullpath(const char *pszPath, char *pszFull, size_t cchFull); 86 #endif 431 87 432 88 /* … … 441 97 if (resolve) { 442 98 #if 1 /* bird */ 443 # if 1444 99 nt_fullpath(filename, w32_path, sizeof(w32_path)); 445 # else446 _fullpath(w32_path, filename, sizeof(w32_path));447 w32_fixcase(w32_path);448 # endif449 100 #else /* !bird */ 450 101 _fullpath(w32_path, filename, sizeof (w32_path)); -
trunk/src/kmk/w32/subproc/sub_proc.c
r540 r1165 737 737 738 738 while (!stdin_eof || !stdout_eof || !stderr_eof || !child_dead) { 739 long tick; 739 740 wait_count = 0; 740 741 if (!stdin_eof) { … … 751 752 } 752 753 754 tick = GetTickCount(); 753 755 wait_return = WaitForMultipleObjects(wait_count, wait_list, 754 756 FALSE, /* don't wait for all: one ready will do */ 755 757 child_dead? 1000 :INFINITE); /* after the child dies, subthreads have 756 758 one second to collect all remaining output */ 759 printf("waitformultipleobjects: %d ms rc=%d\n", GetTickCount() - tick, wait_return); 757 760 758 761 if (wait_return == WAIT_FAILED) { … … 1075 1078 #ifdef KMK /* for the space before the final " in case we need it. */ 1076 1079 bytes_required++; 1077 #endif 1080 #endif 1078 1081 1079 1082 command_line = (char*) malloc(bytes_required); … … 1125 1128 */ 1126 1129 backslash_count++; 1127 1130 1128 1131 while(backslash_count) { 1129 1132 *(command_line_i++) = '\\';
Note:
See TracChangeset
for help on using the changeset viewer.