Changeset 34029 in vbox
- Timestamp:
- Nov 12, 2010 2:21:59 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/vfslowlevel.h
r34002 r34029 40 40 */ 41 41 42 43 /** @name VFS Lock Abstraction 44 * @todo This should be moved somewhere else as it is of general use. 45 * @{ */ 46 47 /** 48 * VFS lock types. 49 */ 50 typedef enum RTVFSLOCKTYPE 51 { 52 /** Invalid lock type. */ 53 RTVFSLOCKTYPE_INVALID = 0, 54 /** Read write semaphore. */ 55 RTVFSLOCKTYPE_RW, 56 /** Fast mutex semaphore (critical section in ring-3). */ 57 RTVFSLOCKTYPE_FASTMUTEX, 58 /** Full fledged mutex semaphore. */ 59 RTVFSLOCKTYPE_MUTEX, 60 /** The end of valid lock types. */ 61 RTVFSLOCKTYPE_END, 62 /** The customary 32-bit type hack. */ 63 RTVFSLOCKTYPE_32BIT_HACK = 0x7fffffff 64 } RTVFSLOCKTYPE; 65 66 /** VFS lock handle. */ 67 typedef struct RTVFSLOCKINTERNAL *RTVFSLOCK; 68 /** Pointer to a VFS lock handle. */ 69 typedef RTVFSLOCK *PRTVFSLOCK; 70 /** Nil VFS lock handle. */ 71 #define NIL_RTVFSLOCK ((RTVFSLOCK)~(uintptr_t)0) 72 73 /** Special handle value for creating a new read/write semaphore based lock. */ 74 #define RTVFSLOCK_CREATE_RW ((RTVFSLOCK)~(uintptr_t)1) 75 /** Special handle value for creating a new fast mutex semaphore based lock. */ 76 #define RTVFSLOCK_CREATE_FASTMUTEX ((RTVFSLOCK)~(uintptr_t)2) 77 /** Special handle value for creating a new mutex semaphore based lock. */ 78 #define RTVFSLOCK_CREATE_MUTEX ((RTVFSLOCK)~(uintptr_t)3) 79 80 /** 81 * Retains a reference to the VFS lock handle. 82 * 83 * @returns New reference count on success, UINT32_MAX on failure. 84 * @param hLock The VFS lock handle. 85 */ 86 RTDECL(uint32_t) RTVfsLockRetain(RTVFSLOCK hLock); 87 88 /** 89 * Releases a reference to the VFS lock handle. 90 * 91 * @returns New reference count on success (0 if closed), UINT32_MAX on failure. 92 * @param hLock The VFS lock handle. 93 */ 94 RTDECL(uint32_t) RTVfsLockRelease(RTVFSLOCK hLock); 95 96 /** 97 * Gets the lock type. 98 * 99 * @returns The lock type on success, RTVFSLOCKTYPE_INVALID if the handle is 100 * not valid. 101 * @param hLock The lock handle. 102 */ 103 RTDECL(RTVFSLOCKTYPE) RTVfsLockGetType(RTVFSLOCK hLock); 104 105 106 107 RTDECL(void) RTVfsLockAcquireReadSlow(RTVFSLOCK hLock); 108 RTDECL(void) RTVfsLockReleaseReadSlow(RTVFSLOCK hLock); 109 RTDECL(void) RTVfsLockAcquireWriteSlow(RTVFSLOCK hLock); 110 RTDECL(void) RTVfsLockReleaseWriteSlow(RTVFSLOCK hLock); 111 /** @} */ 112 113 /** 114 * Acquire a read lock. 115 * 116 * @param hLock The lock handle, can be NIL. 117 */ 118 DECLINLINE(void) RTVfsLockAcquireRead(RTVFSLOCK hLock) 119 { 120 if (hLock != NIL_RTVFSLOCK) 121 RTVfsLockAcquireReadSlow(hLock); 122 } 123 124 125 /** 126 * Release a read lock. 127 * 128 * @param hLock The lock handle, can be NIL. 129 */ 130 DECLINLINE(void) RTVfsLockReleaseRead(RTVFSLOCK hLock) 131 { 132 if (hLock != NIL_RTVFSLOCK) 133 RTVfsLockReleaseReadSlow(hLock); 134 } 135 136 137 /** 138 * Acquire a write lock. 139 * 140 * @param hLock The lock handle, can be NIL. 141 */ 142 DECLINLINE(void) RTVfsLockAcquireWrite(RTVFSLOCK hLock) 143 { 144 if (hLock != NIL_RTVFSLOCK) 145 RTVfsLockAcquireWriteSlow(hLock); 146 } 147 148 149 /** 150 * Release a write lock. 151 * 152 * @param hLock The lock handle, can be NIL. 153 */ 154 DECLINLINE(void) RTVfsLockReleaseWrite(RTVFSLOCK hLock) 155 { 156 if (hLock != NIL_RTVFSLOCK) 157 RTVfsLockReleaseWriteSlow(hLock); 158 } 159 160 /** @} */ 161 42 162 /** 43 163 * The VFS operations. … … 141 261 /** The RTVFSOBJOPS structure version. */ 142 262 #define RTVFSOBJOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x1f,1,0) 263 264 265 /** 266 * Creates a new VFS base object handle. 267 * 268 * @returns IPRT status code 269 * @param pObjOps The base object operations. 270 * @param cbInstance The size of the instance data. 271 * @param hVfs The VFS handle to associate this base object 272 * with. NIL_VFS is ok. 273 * @param hLock Handle to a custom lock to be used with the new 274 * object. The reference is consumed. NIL and 275 * special lock handles are fine. 276 * @param phVfsFss Where to return the new handle. 277 * @param ppvInstance Where to return the pointer to the instance data 278 * (size is @a cbInstance). 279 */ 280 RTDECL(int) RTVfsNewBaseObj(PCRTVFSOBJOPS pObjOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock, 281 PRTVFSOBJ phVfsObj, void **ppvInstance); 143 282 144 283 … … 255 394 * @param cbInstance The size of the instance data. 256 395 * @param hVfs The VFS handle to associate this filesystem 257 * steram with. NIL_VFS is ok. 258 * @param hSemRW The read-write semaphore to use to protect the 259 * handle if this differs from the one the VFS 260 * uses. NIL_RTSEMRW is ok if no locking is 261 * desired. 396 * stream with. NIL_VFS is ok. 397 * @param hLock Handle to a custom lock to be used with the new 398 * object. The reference is consumed. NIL and 399 * special lock handles are fine. 262 400 * @param phVfsFss Where to return the new handle. 263 401 * @param ppvInstance Where to return the pointer to the instance data 264 402 * (size is @a cbInstance). 265 403 */ 266 RTDECL(int) RTVfsNewFsStream(PCRTVFSFSSTREAMOPS pFsStreamOps, size_t cbInstance, RTVFS hVfs, RT SEMRW hSemRW,404 RTDECL(int) RTVfsNewFsStream(PCRTVFSFSSTREAMOPS pFsStreamOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock, 267 405 PRTVFSFSSTREAM phVfsFss, void **ppvInstance); 268 406 … … 450 588 /** The RTVFSSYMLINKOPS structure version. */ 451 589 #define RTVFSSYMLINKOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x5f,1,0) 590 591 592 /** 593 * Creates a new VFS symlink handle. 594 * 595 * @returns IPRT status code 596 * @param pSymlinkOps The symlink operations. 597 * @param cbInstance The size of the instance data. 598 * @param hVfs The VFS handle to associate this symlink object 599 * with. NIL_VFS is ok. 600 * @param hLock Handle to a custom lock to be used with the new 601 * object. The reference is consumed. NIL and 602 * special lock handles are fine. 603 * @param phVfsSym Where to return the new handle. 604 * @param ppvInstance Where to return the pointer to the instance data 605 * (size is @a cbInstance). 606 */ 607 RTDECL(int) RTVfsNewSymlink(PCRTVFSSYMLINKOPS pSymlinkOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock, 608 PRTVFSSYMLINK phVfsSym, void **ppvInstance); 452 609 453 610 … … 576 733 * @param hVfs The VFS handle to associate this I/O stream 577 734 * with. NIL_VFS is ok. 578 * @param hSemRW The read-write semaphore to use to protect the 579 * handle if this differs from the one the VFS 580 * uses. NIL_RTSEMRW is ok if no locking is 581 * desired. 735 * @param hLock Handle to a custom lock to be used with the new 736 * object. The reference is consumed. NIL and 737 * special lock handles are fine. 582 738 * @param phVfsIos Where to return the new handle. 583 739 * @param ppvInstance Where to return the pointer to the instance data 584 740 * (size is @a cbInstance). 585 741 */ 586 RTDECL(int) RTVfsNewIoStream(PCRTVFSIOSTREAMOPS pIoStreamOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RT SEMRW hSemRW,742 RTDECL(int) RTVfsNewIoStream(PCRTVFSIOSTREAMOPS pIoStreamOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RTVFSLOCK hLock, 587 743 PRTVFSIOSTREAM phVfsIos, void **ppvInstance); 588 744 … … 647 803 * @param hVfs The VFS handle to associate this file with. 648 804 * NIL_VFS is ok. 805 * @param hLock Handle to a custom lock to be used with the new 806 * object. The reference is consumed. NIL and 807 * special lock handles are fine. 649 808 * @param phVfsFile Where to return the new handle. 650 809 * @param ppvInstance Where to return the pointer to the instance data 651 810 * (size is @a cbInstance). 652 811 */ 653 RTDECL(int) RTVfsNewFile(PCRTVFSFILEOPS pFileOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, 812 RTDECL(int) RTVfsNewFile(PCRTVFSFILEOPS pFileOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RTVFSLOCK hLock, 654 813 PRTVFSFILE phVfsFile, void **ppvInstance); 655 814 -
trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
r34014 r34029 71 71 72 72 /** Asserts that the VFS base object vtable is valid. */ 73 #define RTVFSOBJ_ASSERT_OPS( pObj, enmTypeArg) \73 #define RTVFSOBJ_ASSERT_OPS(a_pObjOps, a_enmType) \ 74 74 do \ 75 75 { \ 76 Assert(( pObj)->uVersion == RTVFSOBJOPS_VERSION); \77 Assert(( pObj)->enmType == (enmTypeArg) || (enmTypeArg) == RTVFSOBJTYPE_INVALID); \78 AssertPtr(( pObj)->pszName); \79 Assert(*( pObj)->pszName); \80 AssertPtr(( pObj)->pfnClose); \81 AssertPtr(( pObj)->pfnQueryInfo); \82 Assert(( pObj)->uEndMarker == RTVFSOBJOPS_VERSION); \76 Assert((a_pObjOps)->uVersion == RTVFSOBJOPS_VERSION); \ 77 Assert((a_pObjOps)->enmType == (a_enmType) || (a_enmType) == RTVFSOBJTYPE_INVALID); \ 78 AssertPtr((a_pObjOps)->pszName); \ 79 Assert(*(a_pObjOps)->pszName); \ 80 AssertPtr((a_pObjOps)->pfnClose); \ 81 AssertPtr((a_pObjOps)->pfnQueryInfo); \ 82 Assert((a_pObjOps)->uEndMarker == RTVFSOBJOPS_VERSION); \ 83 83 } while (0) 84 84 85 /** Asserts that the VFS set object vtable is valid. */ 86 #define RTVFSOBJSET_ASSERT_OPS(a_pSetOps, a_offObjOps) \ 87 do \ 88 { \ 89 Assert((a_pSetOps)->uVersion == RTVFSOBJSETOPS_VERSION); \ 90 Assert((a_pSetOps)->offObjOps == (a_offObjOps)); \ 91 AssertPtr((a_pSetOps)->pfnSetMode); \ 92 AssertPtr((a_pSetOps)->pfnSetTimes); \ 93 AssertPtr((a_pSetOps)->pfnSetOwner); \ 94 Assert((a_pSetOps)->uEndMarker == RTVFSOBJSETOPS_VERSION); \ 95 } while (0) 96 85 97 /** Asserts that the VFS I/O stream vtable is valid. */ 86 #define RTVFSIOSTREAM_ASSERT_OPS(pIoStreamOps, enmTypeArg) \98 #define RTVFSIOSTREAM_ASSERT_OPS(pIoStreamOps, a_enmType) \ 87 99 do { \ 88 RTVFSOBJ_ASSERT_OPS(&(pIoStreamOps)->Obj, enmTypeArg); \100 RTVFSOBJ_ASSERT_OPS(&(pIoStreamOps)->Obj, a_enmType); \ 89 101 Assert((pIoStreamOps)->uVersion == RTVFSIOSTREAMOPS_VERSION); \ 90 102 Assert(!(pIoStreamOps)->fReserved); \ … … 99 111 } while (0) 100 112 113 /** Asserts that the VFS symlink vtable is valid. */ 114 #define RTVFSSYMLINK_ASSERT_OPS(pSymlinkOps, a_enmType) \ 115 do { \ 116 RTVFSOBJ_ASSERT_OPS(&(pSymlinkOps)->Obj, a_enmType); \ 117 RTVFSOBJSET_ASSERT_OPS(&(pSymlinkOps)->ObjSet, \ 118 RT_OFFSETOF(RTVFSSYMLINKOPS, Obj) - RT_OFFSETOF(RTVFSSYMLINKOPS, ObjSet)); \ 119 Assert((pSymlinkOps)->uVersion == RTVFSSYMLINKOPS_VERSION); \ 120 Assert(!(pSymlinkOps)->fReserved); \ 121 AssertPtr((pSymlinkOps)->pfnRead); \ 122 Assert((pSymlinkOps)->uEndMarker == RTVFSSYMLINKOPS_VERSION); \ 123 } while (0) 124 125 126 /** Validates a VFS handle and returns @a rcRet if it's invalid. */ 127 #define RTVFS_ASSERT_VALID_HANDLE_OR_NIL_RETURN(hVfs, rcRet) \ 128 do { \ 129 if ((hVfs) != NIL_RTVFS) \ 130 { \ 131 AssertPtrReturn((hVfs), (rcRet)); \ 132 AssertReturn((hVfs)->uMagic == RTVFS_MAGIC, (rcRet)); \ 133 } \ 134 } while (0) 101 135 102 136 … … 105 139 *******************************************************************************/ 106 140 /** @todo Move all this stuff to internal/vfs.h */ 141 142 143 /** 144 * The VFS internal lock data. 145 */ 146 typedef struct RTVFSLOCKINTERNAL 147 { 148 /** The number of references to the this lock. */ 149 uint32_t volatile cRefs; 150 /** The lock type. */ 151 RTVFSLOCKTYPE enmType; 152 /** Type specific data. */ 153 union 154 { 155 /** Read/Write semaphore handle. */ 156 RTSEMRW hSemRW; 157 /** Fast mutex semaphore handle. */ 158 RTSEMFASTMUTEX hFastMtx; 159 /** Regular mutex semaphore handle. */ 160 RTSEMMUTEX hMtx; 161 } u; 162 } RTVFSLOCKINTERNAL; 163 107 164 108 165 /** … … 122 179 /** The vtable. */ 123 180 PCRTVFSOBJOPS pOps; 124 /** Read-write semaphore protecting all access to the VFS125 * Only valid RTVFS_C_THREAD_SAFE is set, otherwise it is NIL_RT SEMRW. */126 RT SEMRW hSemRW;181 /** The lock protecting all access to the VFS. 182 * Only valid RTVFS_C_THREAD_SAFE is set, otherwise it is NIL_RTVFSLOCK. */ 183 RTVFSLOCK hLock; 127 184 /** Reference back to the VFS containing this object. */ 128 185 RTVFS hVfs; … … 279 336 280 337 338 339 /* 340 * 341 * V F S L o c k A b s t r a c t i o n 342 * V F S L o c k A b s t r a c t i o n 343 * V F S L o c k A b s t r a c t i o n 344 * 345 * 346 */ 347 348 349 RTDECL(uint32_t) RTVfsLockRetain(RTVFSLOCK hLock) 350 { 351 RTVFSLOCKINTERNAL *pThis = hLock; 352 AssertPtrReturn(pThis, UINT32_MAX); 353 AssertPtrReturn(pThis->enmType > RTVFSLOCKTYPE_INVALID && pThis->enmType < RTVFSLOCKTYPE_END, UINT32_MAX); 354 355 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs); 356 AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p %d\n", cRefs, pThis, pThis->enmType)); 357 return cRefs; 358 } 359 360 361 /** 362 * Destroys a VFS lock handle. 363 * 364 * @param pThis The lock to destroy. 365 */ 366 static void rtVfsLockDestroy(RTVFSLOCKINTERNAL *pThis) 367 { 368 switch (pThis->enmType) 369 { 370 case RTVFSLOCKTYPE_RW: 371 RTSemRWDestroy(pThis->u.hSemRW); 372 pThis->u.hSemRW = NIL_RTSEMRW; 373 break; 374 375 case RTVFSLOCKTYPE_FASTMUTEX: 376 RTSemFastMutexDestroy(pThis->u.hFastMtx); 377 pThis->u.hFastMtx = NIL_RTSEMFASTMUTEX; 378 break; 379 380 case RTVFSLOCKTYPE_MUTEX: 381 RTSemMutexDestroy(pThis->u.hMtx); 382 pThis->u.hFastMtx = NIL_RTSEMMUTEX; 383 break; 384 385 default: 386 AssertMsgFailedReturnVoid(("%p %d\n", pThis, pThis->enmType)); 387 } 388 389 pThis->enmType = RTVFSLOCKTYPE_INVALID; 390 RTMemFree(pThis); 391 } 392 393 394 RTDECL(uint32_t) RTVfsLockRelease(RTVFSLOCK hLock) 395 { 396 RTVFSLOCKINTERNAL *pThis = hLock; 397 AssertPtrReturn(pThis, UINT32_MAX); 398 AssertPtrReturn(pThis->enmType > RTVFSLOCKTYPE_INVALID && pThis->enmType < RTVFSLOCKTYPE_END, UINT32_MAX); 399 400 uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs); 401 AssertMsg(cRefs < _1M, ("%#x %p %d\n", cRefs, pThis, pThis->enmType)); 402 if (cRefs == 0) 403 rtVfsLockDestroy(pThis); 404 return cRefs; 405 } 406 407 408 /** 409 * Creates a read/write lock. 410 * 411 * @returns IPRT status code 412 * @param phLock Where to return the lock handle. 413 */ 414 static int rtVfsLockCreateRW(PRTVFSLOCK phLock) 415 { 416 RTVFSLOCKINTERNAL *pThis = (RTVFSLOCKINTERNAL *)RTMemAlloc(sizeof(*pThis)); 417 if (!pThis) 418 return VERR_NO_MEMORY; 419 420 pThis->cRefs = 1; 421 pThis->enmType = RTVFSLOCKTYPE_RW; 422 423 int rc = RTSemRWCreate(&pThis->u.hSemRW); 424 if (RT_FAILURE(rc)) 425 { 426 RTMemFree(pThis); 427 return rc; 428 } 429 430 *phLock = pThis; 431 return VINF_SUCCESS; 432 } 433 434 435 /** 436 * Creates a fast mutex lock. 437 * 438 * @returns IPRT status code 439 * @param phLock Where to return the lock handle. 440 */ 441 static int rtVfsLockCreateFastMutex(PRTVFSLOCK phLock) 442 { 443 RTVFSLOCKINTERNAL *pThis = (RTVFSLOCKINTERNAL *)RTMemAlloc(sizeof(*pThis)); 444 if (!pThis) 445 return VERR_NO_MEMORY; 446 447 pThis->cRefs = 1; 448 pThis->enmType = RTVFSLOCKTYPE_FASTMUTEX; 449 450 int rc = RTSemFastMutexCreate(&pThis->u.hFastMtx); 451 if (RT_FAILURE(rc)) 452 { 453 RTMemFree(pThis); 454 return rc; 455 } 456 457 *phLock = pThis; 458 return VINF_SUCCESS; 459 460 } 461 462 463 /** 464 * Creates a mutex lock. 465 * 466 * @returns IPRT status code 467 * @param phLock Where to return the lock handle. 468 */ 469 static int rtVfsLockCreateMutex(PRTVFSLOCK phLock) 470 { 471 RTVFSLOCKINTERNAL *pThis = (RTVFSLOCKINTERNAL *)RTMemAlloc(sizeof(*pThis)); 472 if (!pThis) 473 return VERR_NO_MEMORY; 474 475 pThis->cRefs = 1; 476 pThis->enmType = RTVFSLOCKTYPE_MUTEX; 477 478 int rc = RTSemMutexCreate(&pThis->u.hMtx); 479 if (RT_FAILURE(rc)) 480 { 481 RTMemFree(pThis); 482 return rc; 483 } 484 485 *phLock = pThis; 486 return VINF_SUCCESS; 487 } 488 489 490 /** 491 * Acquires the lock for reading. 492 * 493 * @param hLock Non-nil lock handle. 494 * @internal 495 */ 496 RTDECL(void) RTVfsLockAcquireReadSlow(RTVFSLOCK hLock) 497 { 498 RTVFSLOCKINTERNAL *pThis = hLock; 499 int rc; 500 501 AssertPtr(pThis); 502 switch (pThis->enmType) 503 { 504 case RTVFSLOCKTYPE_RW: 505 rc = RTSemRWRequestRead(pThis->u.hSemRW, RT_INDEFINITE_WAIT); 506 AssertRC(rc); 507 break; 508 509 case RTVFSLOCKTYPE_FASTMUTEX: 510 rc = RTSemFastMutexRequest(pThis->u.hFastMtx); 511 AssertRC(rc); 512 break; 513 514 case RTVFSLOCKTYPE_MUTEX: 515 rc = RTSemMutexRequest(pThis->u.hMtx, RT_INDEFINITE_WAIT); 516 AssertRC(rc); 517 break; 518 default: 519 AssertFailed(); 520 } 521 } 522 523 524 /** 525 * Release a lock held for reading. 526 * 527 * @param hLock Non-nil lock handle. 528 * @internal 529 */ 530 RTDECL(void) RTVfsLockReleaseReadSlow(RTVFSLOCK hLock) 531 { 532 RTVFSLOCKINTERNAL *pThis = hLock; 533 int rc; 534 535 AssertPtr(pThis); 536 switch (pThis->enmType) 537 { 538 case RTVFSLOCKTYPE_RW: 539 rc = RTSemRWReleaseRead(pThis->u.hSemRW); 540 AssertRC(rc); 541 break; 542 543 case RTVFSLOCKTYPE_FASTMUTEX: 544 rc = RTSemFastMutexRelease(pThis->u.hFastMtx); 545 AssertRC(rc); 546 break; 547 548 case RTVFSLOCKTYPE_MUTEX: 549 rc = RTSemMutexRelease(pThis->u.hMtx); 550 AssertRC(rc); 551 break; 552 default: 553 AssertFailed(); 554 } 555 } 556 557 558 /** 559 * Acquires the lock for writing. 560 * 561 * @param hLock Non-nil lock handle. 562 * @internal 563 */ 564 RTDECL(void) RTVfsLockAcquireWriteSlow(RTVFSLOCK hLock) 565 { 566 RTVFSLOCKINTERNAL *pThis = hLock; 567 int rc; 568 569 AssertPtr(pThis); 570 switch (pThis->enmType) 571 { 572 case RTVFSLOCKTYPE_RW: 573 rc = RTSemRWRequestWrite(pThis->u.hSemRW, RT_INDEFINITE_WAIT); 574 AssertRC(rc); 575 break; 576 577 case RTVFSLOCKTYPE_FASTMUTEX: 578 rc = RTSemFastMutexRequest(pThis->u.hFastMtx); 579 AssertRC(rc); 580 break; 581 582 case RTVFSLOCKTYPE_MUTEX: 583 rc = RTSemMutexRequest(pThis->u.hMtx, RT_INDEFINITE_WAIT); 584 AssertRC(rc); 585 break; 586 default: 587 AssertFailed(); 588 } 589 } 590 591 592 /** 593 * Release a lock held for writing. 594 * 595 * @param hLock Non-nil lock handle. 596 * @internal 597 */ 598 RTDECL(void) RTVfsLockReleaseWriteSlow(RTVFSLOCK hLock) 599 { 600 RTVFSLOCKINTERNAL *pThis = hLock; 601 int rc; 602 603 AssertPtr(pThis); 604 switch (pThis->enmType) 605 { 606 case RTVFSLOCKTYPE_RW: 607 rc = RTSemRWReleaseWrite(pThis->u.hSemRW); 608 AssertRC(rc); 609 break; 610 611 case RTVFSLOCKTYPE_FASTMUTEX: 612 rc = RTSemFastMutexRelease(pThis->u.hFastMtx); 613 AssertRC(rc); 614 break; 615 616 case RTVFSLOCKTYPE_MUTEX: 617 rc = RTSemMutexRelease(pThis->u.hMtx); 618 AssertRC(rc); 619 break; 620 default: 621 AssertFailed(); 622 } 623 } 624 625 626 281 627 /* 282 628 * … … 288 634 289 635 /** 636 * Internal object retainer that asserts sanity in strict builds. 637 * 638 * @param pThis The base object handle data. 639 */ 640 DECLINLINE(void) rtVfsObjRetainVoid(RTVFSOBJINTERNAL *pThis) 641 { 642 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs); 643 AssertMsg(cRefs > 1 && cRefs < _1M, 644 ("%#x %p ops=%p %s (%d)\n", cRefs, pThis, pThis->pOps, pThis->pOps->pszName, pThis->pOps->enmType)); 645 NOREF(cRefs); 646 } 647 648 649 /** 650 * Initializes the base object part of a new object. 651 * 652 * @returns IPRT status code. 653 * @param pThis Pointer to the base object part. 654 * @param pObjOps The base object vtable. 655 * @param hVfs The VFS handle to associate with. 656 * @param hLock The lock handle, pseudo handle or nil. 657 * @param pvThis Pointer to the private data. 658 */ 659 static int rtVfsObjInitNewObject(RTVFSOBJINTERNAL *pThis, PCRTVFSOBJOPS pObjOps, RTVFS hVfs, RTVFSLOCK hLock, void *pvThis) 660 { 661 /* 662 * Deal with the lock first as that's the most complicated matter. 663 */ 664 if (hLock != NIL_RTVFSLOCK) 665 { 666 int rc; 667 if (hLock == RTVFSLOCK_CREATE_RW) 668 { 669 rc = rtVfsLockCreateRW(&hLock); 670 AssertRCReturn(rc, rc); 671 } 672 else if (hLock == RTVFSLOCK_CREATE_FASTMUTEX) 673 { 674 rc = rtVfsLockCreateFastMutex(&hLock); 675 AssertRCReturn(rc, rc); 676 } 677 else if (hLock == RTVFSLOCK_CREATE_MUTEX) 678 { 679 rc = rtVfsLockCreateMutex(&hLock); 680 AssertRCReturn(rc, rc); 681 } 682 else 683 { 684 /* 685 * The caller specified a lock, we consume the this reference. 686 */ 687 AssertPtrReturn(hLock, VERR_INVALID_HANDLE); 688 AssertPtrReturn(hLock->enmType > RTVFSLOCKTYPE_INVALID && hLock->enmType < RTVFSLOCKTYPE_END, VERR_INVALID_HANDLE); 689 AssertPtrReturn(hLock->cRefs > 0, VERR_INVALID_HANDLE); 690 } 691 } 692 else if (hVfs != NIL_RTVFS) 693 { 694 /* 695 * Retain a reference to the VFS lock, if there is one. 696 */ 697 hLock = hVfs->Base.hLock; 698 if (hLock != NIL_RTVFSLOCK) 699 { 700 uint32_t cRefs = RTVfsLockRetain(hLock); 701 if (RT_UNLIKELY(cRefs == UINT32_MAX)) 702 return VERR_INVALID_HANDLE; 703 } 704 } 705 706 707 /* 708 * Do the actual initializing. 709 */ 710 pThis->uMagic = RTVFSOBJ_MAGIC; 711 pThis->pvThis = pvThis; 712 pThis->pOps = pObjOps; 713 pThis->cRefs = 1; 714 pThis->hVfs = hVfs; 715 pThis->hLock = hLock; 716 if (hVfs != NIL_RTVFS) 717 rtVfsObjRetainVoid(&hVfs->Base); 718 719 return VINF_SUCCESS; 720 } 721 722 723 RTDECL(int) RTVfsNewBaseObj(PCRTVFSOBJOPS pObjOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock, 724 PRTVFSOBJ phVfsObj, void **ppvInstance) 725 { 726 /* 727 * Validate the input, be extra strict in strict builds. 728 */ 729 AssertPtr(pObjOps); 730 AssertReturn(pObjOps->uVersion == RTVFSOBJOPS_VERSION, VERR_VERSION_MISMATCH); 731 AssertReturn(pObjOps->uEndMarker == RTVFSOBJOPS_VERSION, VERR_VERSION_MISMATCH); 732 RTVFSOBJ_ASSERT_OPS(pObjOps, RTVFSOBJTYPE_BASE); 733 Assert(cbInstance > 0); 734 AssertPtr(ppvInstance); 735 AssertPtr(phVfsObj); 736 RTVFS_ASSERT_VALID_HANDLE_OR_NIL_RETURN(hVfs, VERR_INVALID_HANDLE); 737 738 /* 739 * Allocate the handle + instance data. 740 */ 741 size_t const cbThis = RT_ALIGN_Z(sizeof(RTVFSOBJINTERNAL), RTVFS_INST_ALIGNMENT) 742 + RT_ALIGN_Z(cbInstance, RTVFS_INST_ALIGNMENT); 743 RTVFSOBJINTERNAL *pThis = (RTVFSOBJINTERNAL *)RTMemAllocZ(cbThis); 744 if (!pThis) 745 return VERR_NO_MEMORY; 746 747 int rc = rtVfsObjInitNewObject(pThis, pObjOps, hVfs, hLock, 748 (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT)); 749 if (RT_FAILURE(rc)) 750 { 751 RTMemFree(pThis); 752 return rc; 753 } 754 755 *phVfsObj = pThis; 756 *ppvInstance = pThis->pvThis; 757 return VINF_SUCCESS; 758 } 759 760 761 /** 290 762 * Write locks the object. 291 763 * … … 294 766 DECLINLINE(void) rtVfsObjWriteLock(RTVFSOBJINTERNAL *pThis) 295 767 { 296 if (pThis->hSemRW != NIL_RTSEMRW) 297 { 298 int rc = RTSemRWRequestWrite(pThis->hSemRW, RT_INDEFINITE_WAIT); 299 AssertRC(rc); 300 } 768 RTVfsLockAcquireWrite(pThis->hLock); 301 769 } 302 770 … … 309 777 DECLINLINE(void) rtVfsObjWriteUnlock(RTVFSOBJINTERNAL *pThis) 310 778 { 311 if (pThis->hSemRW != NIL_RTSEMRW) 312 { 313 int rc = RTSemRWReleaseWrite(pThis->hSemRW); 314 AssertRC(rc); 315 } 779 RTVfsLockReleaseWrite(pThis->hLock); 316 780 } 317 781 … … 323 787 DECLINLINE(void) rtVfsObjReadLock(RTVFSOBJINTERNAL *pThis) 324 788 { 325 if (pThis->hSemRW != NIL_RTSEMRW) 326 { 327 int rc = RTSemRWRequestRead(pThis->hSemRW, RT_INDEFINITE_WAIT); 328 AssertRC(rc); 329 } 789 RTVfsLockAcquireRead(pThis->hLock); 330 790 } 331 791 … … 338 798 DECLINLINE(void) rtVfsObjReadUnlock(RTVFSOBJINTERNAL *pThis) 339 799 { 340 if (pThis->hSemRW != NIL_RTSEMRW) 341 { 342 int rc = RTSemRWReleaseRead(pThis->hSemRW); 343 AssertRC(rc); 344 } 800 RTVfsLockReleaseRead(pThis->hLock); 345 801 } 346 802 … … 359 815 ("%#x %p ops=%p %s (%d)\n", cRefs, pThis, pThis->pOps, pThis->pOps->pszName, pThis->pOps->enmType)); 360 816 return cRefs; 361 }362 363 364 /**365 * Internal object retainer that asserts sanity in strict builds.366 *367 * @param pThis The base object handle data.368 */369 DECLINLINE(void) rtVfsObjRetainVoid(RTVFSOBJINTERNAL *pThis)370 {371 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);372 AssertMsg(cRefs > 1 && cRefs < _1M,373 ("%#x %p ops=%p %s (%d)\n", cRefs, pThis, pThis->pOps, pThis->pOps->pszName, pThis->pOps->enmType));374 NOREF(cRefs);375 817 } 376 818 … … 1122 1564 1123 1565 1124 RTDECL(int) RTVfsNewFsStream(PCRTVFSFSSTREAMOPS pFsStreamOps, size_t cbInstance, RTVFS hVfs, RT SEMRW hSemRW,1566 RTDECL(int) RTVfsNewFsStream(PCRTVFSFSSTREAMOPS pFsStreamOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock, 1125 1567 PRTVFSFSSTREAM phVfsFss, void **ppvInstance) 1126 1568 { … … 1137 1579 AssertPtr(ppvInstance); 1138 1580 AssertPtr(phVfsFss); 1139 1140 RTVFSINTERNAL *pVfs = NULL; 1141 if (hVfs != NIL_RTVFS) 1142 { 1143 pVfs = hVfs; 1144 AssertPtrReturn(pVfs, VERR_INVALID_HANDLE); 1145 AssertReturn(pVfs->uMagic == RTVFS_MAGIC, VERR_INVALID_HANDLE); 1146 } 1581 RTVFS_ASSERT_VALID_HANDLE_OR_NIL_RETURN(hVfs, VERR_INVALID_HANDLE); 1147 1582 1148 1583 /* … … 1155 1590 return VERR_NO_MEMORY; 1156 1591 1157 pThis->uMagic = RTVFSFSSTREAM_MAGIC; 1158 pThis->fFlags = RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE; 1159 pThis->pOps = pFsStreamOps; 1160 pThis->Base.uMagic = RTVFSOBJ_MAGIC; 1161 pThis->Base.pvThis = (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT); 1162 pThis->Base.pOps = &pFsStreamOps->Obj; 1163 pThis->Base.hSemRW = hSemRW != NIL_RTSEMRW ? hSemRW : pVfs ? pVfs->Base.hSemRW : NIL_RTSEMRW; 1164 pThis->Base.hVfs = hVfs; 1165 pThis->Base.cRefs = 1; 1166 if (hVfs != NIL_RTVFS) 1167 rtVfsObjRetainVoid(&pVfs->Base); 1168 1169 *phVfsFss = pThis; 1170 *ppvInstance = pThis->Base.pvThis; 1592 int rc = rtVfsObjInitNewObject(&pThis->Base, &pFsStreamOps->Obj, hVfs, hLock, 1593 (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT)); 1594 1595 if (RT_FAILURE(rc)) 1596 { 1597 RTMemFree(pThis); 1598 return rc; 1599 } 1600 1601 pThis->uMagic = RTVFSFSSTREAM_MAGIC; 1602 pThis->fFlags = RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE; 1603 pThis->pOps = pFsStreamOps; 1604 1605 *phVfsFss = pThis; 1606 *ppvInstance = pThis->Base.pvThis; 1171 1607 return VINF_SUCCESS; 1172 1608 } … … 1256 1692 */ 1257 1693 1694 RTDECL(int) RTVfsNewSymlink(PCRTVFSSYMLINKOPS pSymlinkOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock, 1695 PRTVFSSYMLINK phVfsSym, void **ppvInstance) 1696 { 1697 /* 1698 * Validate the input, be extra strict in strict builds. 1699 */ 1700 AssertPtr(pSymlinkOps); 1701 AssertReturn(pSymlinkOps->uVersion == RTVFSSYMLINKOPS_VERSION, VERR_VERSION_MISMATCH); 1702 AssertReturn(pSymlinkOps->uEndMarker == RTVFSSYMLINKOPS_VERSION, VERR_VERSION_MISMATCH); 1703 Assert(!pSymlinkOps->fReserved); 1704 RTVFSSYMLINK_ASSERT_OPS(pSymlinkOps, RTVFSOBJTYPE_SYMLINK); 1705 Assert(cbInstance > 0); 1706 AssertPtr(ppvInstance); 1707 AssertPtr(phVfsSym); 1708 RTVFS_ASSERT_VALID_HANDLE_OR_NIL_RETURN(hVfs, VERR_INVALID_HANDLE); 1709 1710 /* 1711 * Allocate the handle + instance data. 1712 */ 1713 size_t const cbThis = RT_ALIGN_Z(sizeof(RTVFSSYMLINKINTERNAL), RTVFS_INST_ALIGNMENT) 1714 + RT_ALIGN_Z(cbInstance, RTVFS_INST_ALIGNMENT); 1715 RTVFSSYMLINKINTERNAL *pThis = (RTVFSSYMLINKINTERNAL *)RTMemAllocZ(cbThis); 1716 if (!pThis) 1717 return VERR_NO_MEMORY; 1718 1719 int rc = rtVfsObjInitNewObject(&pThis->Base, &pSymlinkOps->Obj, hVfs, hLock, 1720 (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT)); 1721 if (RT_FAILURE(rc)) 1722 { 1723 RTMemFree(pThis); 1724 return rc; 1725 } 1726 1727 pThis->uMagic = RTVFSSYMLINK_MAGIC; 1728 pThis->pOps = pSymlinkOps; 1729 1730 *phVfsSym = pThis; 1731 *ppvInstance = pThis->Base.pvThis; 1732 return VINF_SUCCESS; 1733 } 1734 1735 1258 1736 RTDECL(uint32_t) RTVfsSymlinkRetain(RTVFSSYMLINK hVfsSym) 1259 1737 { … … 1297 1775 */ 1298 1776 1299 RTDECL(int) RTVfsNewIoStream(PCRTVFSIOSTREAMOPS pIoStreamOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RT SEMRW hSemRW,1777 RTDECL(int) RTVfsNewIoStream(PCRTVFSIOSTREAMOPS pIoStreamOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RTVFSLOCK hLock, 1300 1778 PRTVFSIOSTREAM phVfsIos, void **ppvInstance) 1301 1779 { … … 1312 1790 AssertPtr(ppvInstance); 1313 1791 AssertPtr(phVfsIos); 1314 1315 RTVFSINTERNAL *pVfs = NULL; 1316 if (hVfs != NIL_RTVFS) 1317 { 1318 pVfs = hVfs; 1319 AssertPtrReturn(pVfs, VERR_INVALID_HANDLE); 1320 AssertReturn(pVfs->uMagic == RTVFS_MAGIC, VERR_INVALID_HANDLE); 1321 } 1792 RTVFS_ASSERT_VALID_HANDLE_OR_NIL_RETURN(hVfs, VERR_INVALID_HANDLE); 1322 1793 1323 1794 /* … … 1330 1801 return VERR_NO_MEMORY; 1331 1802 1332 pThis->uMagic = RTVFSIOSTREAM_MAGIC;1333 pThis->fFlags = fOpen;1334 pThis->pOps = pIoStreamOps;1335 pThis->Base.uMagic = RTVFSOBJ_MAGIC;1336 pThis->Base.pvThis = (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT);1337 pThis->Base.pOps = &pIoStreamOps->Obj;1338 pThis->Base.hSemRW = hSemRW != NIL_RTSEMRW ? hSemRW : pVfs ? pVfs->Base.hSemRW : NIL_RTSEMRW;1339 pThis->Base.hVfs = hVfs; 1340 pThis-> Base.cRefs = 1;1341 if (hVfs != NIL_RTVFS)1342 rtVfsObjRetainVoid(&pVfs->Base);1343 1344 *phVfsIos = pThis;1345 *ppvInstance = pThis->Base.pvThis;1803 int rc = rtVfsObjInitNewObject(&pThis->Base, &pIoStreamOps->Obj, hVfs, hLock, 1804 (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT)); 1805 if (RT_FAILURE(rc)) 1806 { 1807 RTMemFree(pThis); 1808 return rc; 1809 } 1810 1811 pThis->uMagic = RTVFSIOSTREAM_MAGIC; 1812 pThis->fFlags = fOpen; 1813 pThis->pOps = pIoStreamOps; 1814 1815 *phVfsIos = pThis; 1816 *ppvInstance = pThis->Base.pvThis; 1346 1817 return VINF_SUCCESS; 1347 1818 } … … 1604 2075 */ 1605 2076 1606 RTDECL(int) RTVfsNewFile(PCRTVFSFILEOPS pFileOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, 2077 RTDECL(int) RTVfsNewFile(PCRTVFSFILEOPS pFileOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RTVFSLOCK hLock, 1607 2078 PRTVFSFILE phVfsFile, void **ppvInstance) 1608 2079 { … … 1619 2090 AssertPtr(ppvInstance); 1620 2091 AssertPtr(phVfsFile); 1621 1622 RTVFSINTERNAL *pVfs = NULL; 1623 if (hVfs != NIL_RTVFS) 1624 { 1625 pVfs = hVfs; 1626 AssertPtrReturn(pVfs, VERR_INVALID_HANDLE); 1627 AssertReturn(pVfs->uMagic == RTVFS_MAGIC, VERR_INVALID_HANDLE); 1628 } 2092 RTVFS_ASSERT_VALID_HANDLE_OR_NIL_RETURN(hVfs, VERR_INVALID_HANDLE); 1629 2093 1630 2094 /* … … 1637 2101 return VERR_NO_MEMORY; 1638 2102 1639 pThis->uMagic = RTVFSFILE_MAGIC; 1640 pThis->fReserved = 0; 1641 pThis->pOps = pFileOps; 1642 pThis->Stream.uMagic = RTVFSIOSTREAM_MAGIC; 1643 pThis->Stream.fFlags = fOpen; 1644 pThis->Stream.pOps = &pFileOps->Stream; 1645 pThis->Stream.Base.pvThis = (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT); 1646 pThis->Stream.Base.pOps = &pFileOps->Stream.Obj; 1647 pThis->Stream.Base.hSemRW = pVfs ? pVfs->Base.hSemRW : NIL_RTSEMRW; 1648 pThis->Stream.Base.hVfs = hVfs; 1649 pThis->Stream.Base.cRefs = 1; 1650 if (hVfs != NIL_RTVFS) 1651 rtVfsObjRetainVoid(&pVfs->Base); 2103 int rc = rtVfsObjInitNewObject(&pThis->Stream.Base, &pFileOps->Stream.Obj, hVfs, hLock, 2104 (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT)); 2105 if (RT_FAILURE(rc)) 2106 { 2107 RTMemFree(pThis); 2108 return rc; 2109 } 2110 2111 pThis->uMagic = RTVFSFILE_MAGIC; 2112 pThis->fReserved = 0; 2113 pThis->pOps = pFileOps; 2114 pThis->Stream.uMagic = RTVFSIOSTREAM_MAGIC; 2115 pThis->Stream.fFlags = fOpen; 2116 pThis->Stream.pOps = &pFileOps->Stream; 1652 2117 1653 2118 *phVfsFile = pThis; -
trunk/src/VBox/Runtime/common/vfs/vfsstdfile.cpp
r34014 r34029 436 436 PRTVFSSTDFILE pThis; 437 437 RTVFSFILE hVfsFile; 438 rc = RTVfsNewFile(&g_rtVfsStdFileOps, sizeof(RTVFSSTDFILE), fOpen, NIL_RTVFS, &hVfsFile, (void **)&pThis);438 rc = RTVfsNewFile(&g_rtVfsStdFileOps, sizeof(RTVFSSTDFILE), fOpen, NIL_RTVFS, NIL_RTVFSLOCK, &hVfsFile, (void **)&pThis); 439 439 if (RT_FAILURE(rc)) 440 440 return rc; -
trunk/src/VBox/Runtime/common/zip/tar.h
r34002 r34029 93 93 char ab[512]; 94 94 /** The standard header. */ 95 RTZIPTARHDRPOSIX Hdr;95 RTZIPTARHDRPOSIX Posix; 96 96 } RTZIPTARHDR; 97 97 AssertCompileSize(RTZIPTARHDR, 512); -
trunk/src/VBox/Runtime/common/zip/tarvfs.cpp
r34002 r34029 35 35 #include <iprt/err.h> 36 36 #include <iprt/poll.h> 37 #include <iprt/file.h> 37 38 #include <iprt/string.h> 38 39 #include <iprt/vfs.h> … … 111 112 112 113 114 /** 115 * Checks if the TAR header includes a posix user name field. 116 * 117 * @returns true / false. 118 * @param pTar The TAR header. 119 */ 113 120 DECLINLINE(bool) rtZipTarHdrHasPosixUserName(PCRTZIPTARHDR pTar) 114 121 { … … 117 124 118 125 126 /** 127 * Checks if the TAR header includes a posix group name field. 128 * 129 * @returns true / false. 130 * @param pTar The TAR header. 131 */ 119 132 DECLINLINE(bool) rtZipTarHdrHasPosixGroupName(PCRTZIPTARHDR pTar) 120 133 { 121 134 return true; 135 } 136 137 138 /** 139 * Checks if the TAR header includes a posix compatible path prefix field. 140 * 141 * @returns true / false. 142 * @param pTar The TAR header. 143 */ 144 DECLINLINE(bool) rtZipTarHdrHasPrefix(PCRTZIPTARHDR pTar) 145 { 146 return true; 147 } 148 149 150 /** 151 * Validates the TAR header. 152 * 153 * @returns VINF_SUCCESS if valid, appropriate VERR_TAR_XXX if not. 154 * @param pTar The TAR header. 155 */ 156 static int rtZipTarHdrValidate(PCRTZIPTARHDR pTar) 157 { 158 return VINF_SUCCESS; 159 } 160 161 162 /** 163 * Translate a TAR header to an IPRT object info structure with additional UNIX 164 * attributes. 165 * 166 * @returns VINF_SUCCESS if valid, appropriate VERR_TAR_XXX if not. 167 * @param pTar The TAR header (input). 168 * @param pObjInfo The object info structure (output). 169 */ 170 static int rtZipTarHdrToFsObjInfo(PCRTZIPTARHDR pTar, PRTFSOBJINFO pObjInfo) 171 { 172 RT_ZERO(*pObjInfo); 173 174 return VINF_SUCCESS; 122 175 } 123 176 … … 168 221 pObjInfo->Attr.u.UnixOwner.szName[0] = '\0'; 169 222 if (rtZipTarHdrHasPosixUserName(&pThis->Hdr)) 170 RTStrCopy(pObjInfo->Attr.u.UnixOwner.szName, sizeof(pObjInfo->Attr.u.UnixOwner.szName), pThis->Hdr. Hdr.uname);223 RTStrCopy(pObjInfo->Attr.u.UnixOwner.szName, sizeof(pObjInfo->Attr.u.UnixOwner.szName), pThis->Hdr.Posix.uname); 171 224 break; 172 225 … … 177 230 pObjInfo->Attr.u.UnixGroup.szName[0] = '\0'; 178 231 if (rtZipTarHdrHasPosixGroupName(&pThis->Hdr)) 179 RTStrCopy(pObjInfo->Attr.u.UnixGroup.szName, sizeof(pObjInfo->Attr.u.UnixGroup.szName), pThis->Hdr. Hdr.gname);232 RTStrCopy(pObjInfo->Attr.u.UnixGroup.szName, sizeof(pObjInfo->Attr.u.UnixGroup.szName), pThis->Hdr.Posix.gname); 180 233 break; 181 234 … … 194 247 195 248 196 197 /** 198 * Tar filesystem stream operations. 199 */ 200 static const RTVFSOBJOPS g_rtZipTarFsStrmOps = 249 /** 250 * Tar filesystem base object operations. 251 */ 252 static const RTVFSOBJOPS g_rtZipTarFssBaseObjOps = 201 253 { 202 254 RTVFSOBJOPS_VERSION, … … 369 421 370 422 /** 371 * Standard fileoperations.423 * Tar I/O stream operations. 372 424 */ 373 425 static const RTVFSIOSTREAMOPS g_rtZipTarFssIosOps = … … 397 449 * @interface_method_impl{RTVFSOBJOPS,pfnClose} 398 450 */ 451 static DECLCALLBACK(int) rtZipTarFssSym_Close(void *pvThis) 452 { 453 PRTZIPTARBASEOBJ pThis = (PRTZIPTARBASEOBJ)pvThis; 454 return rtZipTarFssBaseObj_Close(pThis); 455 } 456 457 458 /** 459 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo} 460 */ 461 static DECLCALLBACK(int) rtZipTarFssSym_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr) 462 { 463 PRTZIPTARBASEOBJ pThis = (PRTZIPTARBASEOBJ)pvThis; 464 return rtZipTarFssBaseObj_QueryInfo(pThis, pObjInfo, enmAddAttr); 465 } 466 467 /** 468 * @interface_method_impl{RTVFSOBJSETOPS,pfnMode} 469 */ 470 static DECLCALLBACK(int) rtZipTarFssSym_SetMode(void *pvThis, RTFMODE fMode, RTFMODE fMask) 471 { 472 NOREF(pvThis); NOREF(fMode); NOREF(fMask); 473 return VERR_ACCESS_DENIED; 474 } 475 476 477 /** 478 * @interface_method_impl{RTVFSOBJSETOPS,pfnSetTimes} 479 */ 480 static DECLCALLBACK(int) rtZipTarFssSym_SetTimes(void *pvThis, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime, 481 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime) 482 { 483 NOREF(pvThis); NOREF(pAccessTime); NOREF(pModificationTime); NOREF(pChangeTime); NOREF(pBirthTime); 484 return VERR_ACCESS_DENIED; 485 } 486 487 488 /** 489 * @interface_method_impl{RTVFSOBJSETOPS,pfnSetOwner} 490 */ 491 static DECLCALLBACK(int) rtZipTarFssSym_SetOwner(void *pvThis, RTUID uid, RTGID gid) 492 { 493 NOREF(pvThis); NOREF(uid); NOREF(gid); 494 return VERR_ACCESS_DENIED; 495 } 496 497 498 /** 499 * @interface_method_impl{RTVFSSYMLINKOPS,pfnRead} 500 */ 501 static DECLCALLBACK(int) rtZipTarFssSym_Read(void *pvThis, char *pszTarget, size_t cbTarget) 502 { 503 PRTZIPTARBASEOBJ pThis = (PRTZIPTARBASEOBJ)pvThis; 504 return RTStrCopy(pszTarget, cbTarget, pThis->Hdr.Posix.linkname); 505 } 506 507 508 /** 509 * Tar symbolic (and hardlink) operations. 510 */ 511 static const RTVFSSYMLINKOPS g_rtZipTarFssSymOps = 512 { 513 { /* Obj */ 514 RTVFSOBJOPS_VERSION, 515 RTVFSOBJTYPE_IO_STREAM, 516 "TarFsStream::Symlink", 517 rtZipTarFssIos_Close, 518 rtZipTarFssIos_QueryInfo, 519 RTVFSOBJOPS_VERSION 520 }, 521 RTVFSSYMLINKOPS_VERSION, 522 0, 523 { /* ObjSet */ 524 RTVFSOBJSETOPS_VERSION, 525 RT_OFFSETOF(RTVFSFILEOPS, Stream.Obj) - RT_OFFSETOF(RTVFSFILEOPS, ObjSet), 526 rtZipTarFssSym_SetMode, 527 rtZipTarFssSym_SetTimes, 528 rtZipTarFssSym_SetOwner, 529 RTVFSOBJSETOPS_VERSION 530 }, 531 rtZipTarFssSym_Read, 532 RTVFSSYMLINKOPS_VERSION 533 }; 534 535 536 /** 537 * @interface_method_impl{RTVFSOBJOPS,pfnClose} 538 */ 399 539 static DECLCALLBACK(int) rtZipTarFss_Close(void *pvThis) 400 540 { … … 493 633 return pThis->rcFatal = VERR_TAR_UNEXPECTED_EOS; 494 634 495 /* 496 * Validate the header. 497 */ 498 /** @todo continue here... */ 635 pThis->offNextHdr = off + sizeof(Hdr); 636 637 /* 638 * Validate the header and convert to binary object info. 639 */ 640 /** @todo look for the two all zero headers terminating the stream... */ 641 rc = rtZipTarHdrValidate(&Hdr); 642 if (RT_FAILURE(rc)) 643 return pThis->rcFatal = rc; 644 645 RTFSOBJINFO Info; 646 rc = rtZipTarHdrToFsObjInfo(&Hdr, &Info); 647 if (RT_FAILURE(rc)) 648 return pThis->rcFatal = rc; 499 649 500 650 /* 501 651 * Create an object of the appropriate type. 502 652 */ 503 504 505 return VERR_NOT_IMPLEMENTED; 653 RTVFSOBJTYPE enmType; 654 RTVFSOBJ hVfsObj; 655 switch (Hdr.Posix.typeflag) 656 { 657 /* 658 * Files are represented by a VFS I/O stream. 659 */ 660 case RTZIPTAR_TF_NORMAL: 661 case RTZIPTAR_TF_OLDNORMAL: 662 case RTZIPTAR_TF_CONTIG: 663 { 664 RTVFSIOSTREAM hVfsIos; 665 PRTZIPTARIOSTREAM pIosData; 666 rc = RTVfsNewIoStream(&g_rtZipTarFssIosOps, 667 sizeof(*pIosData), 668 RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, 669 NIL_RTVFS, 670 NIL_RTVFSLOCK, 671 &hVfsIos, 672 (void **)&pIosData); 673 if (RT_FAILURE(rc)) 674 return pThis->rcFatal = rc; 675 676 pIosData->BaseObj.offHdr = off; 677 pIosData->BaseObj.Hdr = Hdr; 678 pIosData->BaseObj.ObjInfo = Info; 679 pIosData->cbFile = Info.cbObject; 680 pIosData->offFile = 0; 681 pIosData->cbPadding = 512 - (uint32_t)(Info.cbObject % 512); 682 pIosData->fEndOfStream = false; 683 pIosData->hVfsIos = pThis->hVfsIos; 684 RTVfsIoStrmRetain(pThis->hVfsIos); 685 686 pThis->pCurIosData = pIosData; 687 pThis->offNextHdr += pIosData->cbFile + pIosData->cbPadding; 688 689 enmType = RTVFSOBJTYPE_IO_STREAM; 690 hVfsObj = RTVfsObjFromIoStream(hVfsIos); 691 RTVfsIoStrmRelease(hVfsIos); 692 break; 693 } 694 695 /* 696 * We represent hard links using a symbolic link object. This fits 697 * best with the way TAR stores it and there is currently no better 698 * fitting VFS type alternative. 699 */ 700 case RTZIPTAR_TF_LINK: 701 case RTZIPTAR_TF_SYMLINK: 702 { 703 RTVFSSYMLINK hVfsSym; 704 PRTZIPTARBASEOBJ pBaseObjData; 705 rc = RTVfsNewSymlink(&g_rtZipTarFssSymOps, 706 sizeof(*pBaseObjData), 707 NIL_RTVFS, 708 NIL_RTVFSLOCK, 709 &hVfsSym, 710 (void **)&pBaseObjData); 711 if (RT_FAILURE(rc)) 712 return pThis->rcFatal = rc; 713 714 pBaseObjData->offHdr = off; 715 pBaseObjData->Hdr = Hdr; 716 pBaseObjData->ObjInfo = Info; 717 718 enmType = RTVFSOBJTYPE_SYMLINK; 719 hVfsObj = RTVfsObjFromSymlink(hVfsSym); 720 RTVfsSymlinkRelease(hVfsSym); 721 break; 722 } 723 724 /* 725 * All other objects are repesented using a VFS base object since they 726 * carry no data streams (unless some tar extension implements extended 727 * attributes / alternative streams). 728 */ 729 case RTZIPTAR_TF_CHR: 730 case RTZIPTAR_TF_BLK: 731 case RTZIPTAR_TF_DIR: 732 case RTZIPTAR_TF_FIFO: 733 { 734 PRTZIPTARBASEOBJ pBaseObjData; 735 rc = RTVfsNewBaseObj(&g_rtZipTarFssBaseObjOps, 736 sizeof(*pBaseObjData), 737 NIL_RTVFS, 738 NIL_RTVFSLOCK, 739 &hVfsObj, 740 (void **)&pBaseObjData); 741 if (RT_FAILURE(rc)) 742 return pThis->rcFatal = rc; 743 744 pBaseObjData->offHdr = off; 745 pBaseObjData->Hdr = Hdr; 746 pBaseObjData->ObjInfo = Info; 747 748 enmType = RTVFSOBJTYPE_BASE; 749 break; 750 } 751 752 default: 753 AssertFailed(); 754 return pThis->rcFatal = VERR_INTERNAL_ERROR_5; 755 } 756 pThis->hVfsCurObj = hVfsObj; 757 758 /* 759 * Set the return data and we're done. 760 */ 761 if (ppszName) 762 { 763 if (rtZipTarHdrHasPrefix(&Hdr)) 764 { 765 *ppszName = NULL; 766 rc = RTStrAAppendExN(ppszName, 2, Hdr.Posix.prefix, Hdr.Posix.name); 767 } 768 else 769 rc = RTStrDupEx(ppszName, Hdr.Posix.name); 770 if (RT_FAILURE(rc)) 771 return rc; 772 } 773 774 if (phVfsObj) 775 { 776 RTVfsObjRetain(hVfsObj); 777 *phVfsObj = hVfsObj; 778 } 779 780 if (penmType) 781 *penmType = enmType; 782 783 return VINF_SUCCESS; 506 784 } 507 785 … … 548 826 PRTZIPTARFSSTREAM pThis; 549 827 RTVFSFSSTREAM hVfsFss; 550 int rc = RTVfsNewFsStream(&rtZipTarFssOps, sizeof(*pThis), NIL_RTVFS, NIL_RT SEMRW, &hVfsFss, (void **)&pThis);828 int rc = RTVfsNewFsStream(&rtZipTarFssOps, sizeof(*pThis), NIL_RTVFS, NIL_RTVFSLOCK, &hVfsFss, (void **)&pThis); 551 829 if (RT_SUCCESS(rc)) 552 830 {
Note:
See TracChangeset
for help on using the changeset viewer.