Changeset 105631 in vbox for trunk/src/VBox/Runtime/r3/posix
- Timestamp:
- Aug 9, 2024 12:59:18 AM (7 months ago)
- svn:sync-xref-src-repo-rev:
- 164320
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/path-posix.cpp
r98103 r105631 313 313 RTR3DECL(int) RTPathUnlink(const char *pszPath, uint32_t fUnlink) 314 314 { 315 RT_NOREF_PV(pszPath); RT_NOREF_PV(fUnlink); 316 return VERR_NOT_IMPLEMENTED; 315 /* 316 * Validate input. 317 */ 318 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); 319 AssertReturn(*pszPath, VERR_INVALID_NAME); 320 AssertReturn(!(fUnlink & ~RTPATHUNLINK_FLAGS_NO_SYMLINKS), VERR_INVALID_FLAGS); 321 322 /* 323 * Convert the path. 324 */ 325 char const *pszNativePath; 326 int rc = rtPathToNative(&pszNativePath, pszPath, NULL); 327 if (RT_SUCCESS(rc)) 328 { 329 /* 330 * Check if it's a directory using lstat, since unlink() may have adverse 331 * side effects when running as root on some file systems (at least on 332 * Solaris). 333 * 334 * There are of course race conditions here, but w/o a NT style removal 335 * API it is not possible to do this w/o a race. 336 * 337 * Note! We cannot just use rmdir here, in case the final entity is a 338 * symlink pointing at a directory, as we're supposed to remove 339 * the symlink when that's the case. 340 */ 341 struct stat Stat; 342 rc = lstat(pszNativePath, &Stat); 343 if (rc || !S_ISDIR(Stat.st_mode)) 344 { 345 rc = unlink(pszNativePath); 346 if (rc == 0) 347 rc = VINF_SUCCESS; 348 else 349 { 350 rc = errno; 351 if (rc != ENOENT) 352 rc = RTErrConvertFromErrno(rc); 353 else 354 { 355 /* 356 * Make the path-not-found match windows. 357 */ 358 rc = VERR_FILE_NOT_FOUND; 359 size_t cch = strlen(pszNativePath); 360 while (cch > 0 && RTPATH_IS_SLASH(pszNativePath[cch - 1])) 361 cch--; 362 while (cch > 0 && !RTPATH_IS_SLASH(pszNativePath[cch - 1])) 363 cch--; 364 while (cch > 0 && RTPATH_IS_SLASH(pszNativePath[cch - 1])) 365 cch--; 366 if (cch >= 1) 367 { 368 char *pszParent = (char *)RTMemTmpAlloc(cch + 1); 369 if (pszParent) 370 { 371 memcpy(pszParent, pszNativePath, cch); 372 pszParent[cch] = '\0'; 373 if (stat(pszParent, &Stat) && errno == ENOENT) 374 rc = VERR_PATH_NOT_FOUND; 375 RTMemTmpFree(pszParent); 376 } 377 } 378 } 379 } 380 } 381 else 382 { 383 rc = rmdir(pszNativePath); 384 if (rc) 385 { 386 rc = errno; 387 if (rc == EEXIST) /* Solaris returns this, the rest have ENOTEMPTY. */ 388 rc = VERR_DIR_NOT_EMPTY; 389 else 390 rc = RTErrConvertFromErrno(rc); 391 } 392 } 393 394 rtPathFreeNative(pszNativePath, pszPath); 395 } 396 return rc; 317 397 } 318 398
Note:
See TracChangeset
for help on using the changeset viewer.