Changeset 57643 in vbox for trunk/src/VBox/Runtime/common/vfs
- Timestamp:
- Sep 7, 2015 1:47:08 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 102533
- Location:
- trunk/src/VBox/Runtime/common/vfs
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/vfs/vfsmisc.cpp
r57358 r57643 71 71 72 72 case RTHANDLETYPE_PIPE: 73 /** @todo */ 74 rc = VERR_NOT_IMPLEMENTED; 73 rc = RTVfsIoStrmFromRTPipe(h.u.hPipe, fLeaveOpen, phVfsIos); 75 74 break; 76 75 -
trunk/src/VBox/Runtime/common/vfs/vfsstdpipe.cpp
r57635 r57643 1 1 /* $Id$ */ 2 2 /** @file 3 * IPRT - Virtual File System, Standard FileImplementation.3 * IPRT - Virtual File System, Standard Pipe I/O stream Implementation. 4 4 */ 5 5 … … 32 32 #include <iprt/vfslowlevel.h> 33 33 34 #include <iprt/assert.h> 34 35 #include <iprt/err.h> 35 36 #include <iprt/file.h> 37 #include <iprt/pipe.h> 36 38 #include <iprt/poll.h> 37 #include <iprt/thread.h>38 39 39 40 … … 42 43 *********************************************************************************************************************************/ 43 44 /** 44 * Private data of a standard file.45 */ 46 typedef struct RTVFSSTD FILE47 { 48 /** The file handle. */49 RT FILE hFile;45 * Private data of a standard pipe. 46 */ 47 typedef struct RTVFSSTDPIPE 48 { 49 /** The pipe handle. */ 50 RTPIPE hPipe; 50 51 /** Whether to leave the handle open when the VFS handle is closed. */ 51 52 bool fLeaveOpen; 52 } RTVFSSTDFILE; 53 /** Pointer to the private data of a standard file. */ 54 typedef RTVFSSTDFILE *PRTVFSSTDFILE; 53 /** Set if primarily read, clear if write. */ 54 bool fReadPipe; 55 /** Fake stream position. */ 56 uint64_t offFakePos; 57 } RTVFSSTDPIPE; 58 /** Pointer to the private data of a standard pipe. */ 59 typedef RTVFSSTDPIPE *PRTVFSSTDPIPE; 55 60 56 61 … … 58 63 * @interface_method_impl{RTVFSOBJOPS,pfnClose} 59 64 */ 60 static DECLCALLBACK(int) rtVfsStd File_Close(void *pvThis)61 { 62 PRTVFSSTD FILE pThis = (PRTVFSSTDFILE)pvThis;65 static DECLCALLBACK(int) rtVfsStdPipe_Close(void *pvThis) 66 { 67 PRTVFSSTDPIPE pThis = (PRTVFSSTDPIPE)pvThis; 63 68 64 69 int rc; 65 70 if (!pThis->fLeaveOpen) 66 rc = RT FileClose(pThis->hFile);71 rc = RTPipeClose(pThis->hPipe); 67 72 else 68 73 rc = VINF_SUCCESS; 69 pThis->h File = NIL_RTFILE;74 pThis->hPipe = NIL_RTPIPE; 70 75 71 76 return rc; … … 76 81 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo} 77 82 */ 78 static DECLCALLBACK(int) rtVfsStdFile_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr) 79 { 80 PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis; 81 return RTFileQueryInfo(pThis->hFile, pObjInfo, enmAddAttr); 82 } 83 84 85 /** 86 * RTFileRead and RTFileReadAt does not return VINF_EOF or VINF_TRY_AGAIN, this 87 * function tries to fix this as best as it can. 88 * 89 * This fixing can be subject to races if some other thread or process is 90 * modifying the file size between the read and our size query here. 91 * 92 * @returns VINF_SUCCESS, VINF_EOF or VINF_TRY_AGAIN. 93 * @param pThis The instance data. 94 * @param off The offset parameter. 95 * @param cbToRead The number of bytes attempted read . 96 * @param cbActuallyRead The number of bytes actually read. 97 */ 98 DECLINLINE(int) rtVfsStdFile_ReadFixRC(PRTVFSSTDFILE pThis, RTFOFF off, size_t cbToRead, size_t cbActuallyRead) 99 { 100 /* If the read returned less bytes than requested, it means the end of the 101 file has been reached. */ 102 if (cbToRead > cbActuallyRead) 103 return VINF_EOF; 104 105 /* The other case here is the very special zero byte read at the end of the 106 file, where we're supposed to indicate EOF. */ 107 if (cbToRead > 0) 108 return VINF_SUCCESS; 109 110 uint64_t cbFile; 111 int rc = RTFileGetSize(pThis->hFile, &cbFile); 112 if (RT_FAILURE(rc)) 113 return rc; 114 115 uint64_t off2; 116 if (off >= 0) 117 off2 = off; 118 else 119 { 120 rc = RTFileSeek(pThis->hFile, 0, RTFILE_SEEK_CURRENT, &off2); 121 if (RT_FAILURE(rc)) 122 return rc; 123 } 124 125 return off2 >= cbFile ? VINF_EOF : VINF_SUCCESS; 83 static DECLCALLBACK(int) rtVfsStdPipe_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr) 84 { 85 PRTVFSSTDPIPE pThis = (PRTVFSSTDPIPE)pvThis; 86 return RTPipeQueryInfo(pThis->hPipe, pObjInfo, enmAddAttr); 126 87 } 127 88 … … 130 91 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead} 131 92 */ 132 static DECLCALLBACK(int) rtVfsStd File_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)133 { 134 PRTVFSSTD FILE pThis = (PRTVFSSTDFILE)pvThis;93 static DECLCALLBACK(int) rtVfsStdPipe_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead) 94 { 95 PRTVFSSTDPIPE pThis = (PRTVFSSTDPIPE)pvThis; 135 96 int rc; 97 AssertReturn(off < 0 || pThis->offFakePos == off, VERR_SEEK_ON_DEVICE); 136 98 137 99 NOREF(fBlocking); 138 100 if (pSgBuf->cSegs == 1) 139 101 { 140 if ( off < 0)141 rc = RT FileRead( pThis->hFile,pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbRead);102 if (fBlocking) 103 rc = RTPipeReadBlocking(pThis->hPipe, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbRead); 142 104 else 143 rc = RT FileReadAt(pThis->hFile, off, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbRead);144 if ( rc == VINF_SUCCESS && pcbRead)145 rc = rtVfsStdFile_ReadFixRC(pThis, off, pSgBuf->paSegs[0].cbSeg, *pcbRead);105 rc = RTPipeRead( pThis->hPipe, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbRead); 106 if (RT_SUCCESS(rc)) 107 pThis->offFakePos += pcbRead ? *pcbRead : pSgBuf->paSegs[0].cbSeg; 146 108 } 147 109 else … … 150 112 size_t cbRead = 0; 151 113 size_t cbReadSeg = 0; 114 size_t *pcbReadSeg = pcbRead ? &cbReadSeg : NULL; 152 115 rc = VINF_SUCCESS; 153 116 … … 158 121 159 122 cbReadSeg = cbSeg; 160 if ( off < 0)161 rc = RT FileRead( pThis->hFile, pvSeg, cbSeg, pcbRead ? &cbReadSeg : NULL);123 if (fBlocking) 124 rc = RTPipeReadBlocking(pThis->hPipe, pvSeg, cbSeg, pcbReadSeg); 162 125 else 163 rc = RT FileReadAt(pThis->hFile, off, pvSeg, cbSeg, pcbRead ? &cbReadSeg : NULL);126 rc = RTPipeRead( pThis->hPipe, pvSeg, cbSeg, pcbReadSeg); 164 127 if (RT_FAILURE(rc)) 165 128 break; 166 if (off >= 0) 167 off += cbReadSeg; 168 cbRead += cbReadSeg; 169 if ((pcbRead && cbReadSeg != cbSeg) || rc != VINF_SUCCESS) 129 pThis->offFakePos += pcbRead ? cbReadSeg : cbSeg; 130 cbRead += cbReadSeg; 131 if (rc != VINF_SUCCESS) 170 132 break; 133 AssertBreakStmt(!pcbRead || cbReadSeg == cbSeg, rc = VINF_TRY_AGAIN); 171 134 } 172 135 173 136 if (pcbRead) 174 {175 137 *pcbRead = cbRead; 176 if (rc == VINF_SUCCESS)177 rc = rtVfsStdFile_ReadFixRC(pThis, off, cbSeg, cbReadSeg);178 }179 138 } 180 139 … … 186 145 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnWrite} 187 146 */ 188 static DECLCALLBACK(int) rtVfsStd File_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)189 { 190 PRTVFSSTD FILE pThis = (PRTVFSSTDFILE)pvThis;147 static DECLCALLBACK(int) rtVfsStdPipe_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten) 148 { 149 PRTVFSSTDPIPE pThis = (PRTVFSSTDPIPE)pvThis; 191 150 int rc; 192 193 NOREF(fBlocking); 151 AssertReturn(off < 0 || pThis->offFakePos == off, VERR_SEEK_ON_DEVICE); 152 194 153 if (pSgBuf->cSegs == 1) 195 154 { 196 if ( off < 0)197 rc = RT FileWrite(pThis->hFile, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbWritten);155 if (fBlocking) 156 rc = RTPipeWriteBlocking(pThis->hPipe, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbWritten); 198 157 else 199 rc = RTFileWriteAt(pThis->hFile, off, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbWritten); 158 rc = RTPipeWrite( pThis->hPipe, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbWritten); 159 if (RT_SUCCESS(rc)) 160 pThis->offFakePos += pcbWritten ? *pcbWritten : pSgBuf->paSegs[0].cbSeg; 200 161 } 201 162 else … … 212 173 213 174 cbWrittenSeg = 0; 214 if ( off < 0)215 rc = RT FileWrite(pThis->hFile, pvSeg, cbSeg, pcbWrittenSeg);175 if (fBlocking) 176 rc = RTPipeWriteBlocking(pThis->hPipe, pvSeg, cbSeg, pcbWrittenSeg); 216 177 else 217 { 218 rc = RTFileWriteAt(pThis->hFile, off, pvSeg, cbSeg, pcbWrittenSeg); 219 off += cbSeg; 220 } 178 rc = RTPipeWrite( pThis->hPipe, pvSeg, cbSeg, pcbWrittenSeg); 221 179 if (RT_FAILURE(rc)) 222 180 break; 181 pThis->offFakePos += pcbWritten ? cbWrittenSeg : cbSeg; 223 182 if (pcbWritten) 224 183 { 225 184 cbWritten += cbWrittenSeg; 226 if ( cbWrittenSeg != cbSeg)185 if (rc != VINF_SUCCESS) 227 186 break; 187 AssertStmt(cbWrittenSeg == cbSeg, rc = VINF_TRY_AGAIN); 228 188 } 189 else 190 AssertBreak(rc == VINF_SUCCESS); 229 191 } 230 192 … … 240 202 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnFlush} 241 203 */ 242 static DECLCALLBACK(int) rtVfsStd File_Flush(void *pvThis)243 { 244 PRTVFSSTD FILE pThis = (PRTVFSSTDFILE)pvThis;245 return RT FileFlush(pThis->hFile);204 static DECLCALLBACK(int) rtVfsStdPipe_Flush(void *pvThis) 205 { 206 PRTVFSSTDPIPE pThis = (PRTVFSSTDPIPE)pvThis; 207 return RTPipeFlush(pThis->hPipe); 246 208 } 247 209 … … 250 212 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnPollOne} 251 213 */ 252 static DECLCALLBACK(int) rtVfsStd File_PollOne(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,214 static DECLCALLBACK(int) rtVfsStdPipe_PollOne(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr, 253 215 uint32_t *pfRetEvents) 254 216 { 255 NOREF(pvThis); 256 int rc; 257 if (fEvents != RTPOLL_EVT_ERROR) 258 { 259 *pfRetEvents = fEvents & ~RTPOLL_EVT_ERROR; 217 PRTVFSSTDPIPE pThis = (PRTVFSSTDPIPE)pvThis; 218 uint32_t const fPossibleEvt = pThis->fReadPipe ? RTPOLL_EVT_READ : RTPOLL_EVT_WRITE; 219 220 int rc = RTPipeSelectOne(pThis->hPipe, cMillies); 221 if (RT_SUCCESS(rc)) 222 { 223 if (fEvents & fPossibleEvt) 224 *pfRetEvents = fPossibleEvt; 225 else 226 rc = RTVfsUtilDummyPollOne(fEvents, cMillies, fIntr, pfRetEvents); 227 } 228 else if ( rc != VERR_TIMEOUT 229 && rc != VERR_INTERRUPTED 230 && rc != VERR_TRY_AGAIN /* paranoia */) 231 { 232 *pfRetEvents = RTPOLL_EVT_ERROR; 260 233 rc = VINF_SUCCESS; 261 234 } 262 else if (fIntr) 263 rc = RTThreadSleep(cMillies); 264 else 265 { 266 uint64_t uMsStart = RTTimeMilliTS(); 267 do 268 rc = RTThreadSleep(cMillies); 269 while ( rc == VERR_INTERRUPTED 270 && !fIntr 271 && RTTimeMilliTS() - uMsStart < cMillies); 272 if (rc == VERR_INTERRUPTED) 273 rc = VERR_TIMEOUT; 274 } 235 275 236 return rc; 276 237 } … … 280 241 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnTell} 281 242 */ 282 static DECLCALLBACK(int) rtVfsStdFile_Tell(void *pvThis, PRTFOFF poffActual) 283 { 284 PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis; 285 uint64_t offActual; 286 int rc = RTFileSeek(pThis->hFile, 0, RTFILE_SEEK_CURRENT, &offActual); 287 if (RT_SUCCESS(rc)) 288 *poffActual = (RTFOFF)offActual; 289 return rc; 290 } 291 292 293 /** 294 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnSkip} 295 */ 296 static DECLCALLBACK(int) rtVfsStdFile_Skip(void *pvThis, RTFOFF cb) 297 { 298 PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis; 299 uint64_t offIgnore; 300 return RTFileSeek(pThis->hFile, cb, RTFILE_SEEK_CURRENT, &offIgnore); 301 } 302 303 304 /** 305 * @interface_method_impl{RTVFSOBJSETOPS,pfnMode} 306 */ 307 static DECLCALLBACK(int) rtVfsStdFile_SetMode(void *pvThis, RTFMODE fMode, RTFMODE fMask) 308 { 309 PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis; 310 if (fMask != ~RTFS_TYPE_MASK) 311 { 312 #if 0 313 RTFMODE fCurMode; 314 int rc = RTFileGetMode(pThis->hFile, &fCurMode); 315 if (RT_FAILURE(rc)) 316 return rc; 317 fMode |= ~fMask & fCurMode; 318 #else 319 RTFSOBJINFO ObjInfo; 320 int rc = RTFileQueryInfo(pThis->hFile, &ObjInfo, RTFSOBJATTRADD_NOTHING); 321 if (RT_FAILURE(rc)) 322 return rc; 323 fMode |= ~fMask & ObjInfo.Attr.fMode; 324 #endif 325 } 326 return RTFileSetMode(pThis->hFile, fMode); 327 } 328 329 330 /** 331 * @interface_method_impl{RTVFSOBJSETOPS,pfnSetTimes} 332 */ 333 static DECLCALLBACK(int) rtVfsStdFile_SetTimes(void *pvThis, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime, 334 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime) 335 { 336 PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis; 337 return RTFileSetTimes(pThis->hFile, pAccessTime, pModificationTime, pChangeTime, pBirthTime); 338 } 339 340 341 /** 342 * @interface_method_impl{RTVFSOBJSETOPS,pfnSetOwner} 343 */ 344 static DECLCALLBACK(int) rtVfsStdFile_SetOwner(void *pvThis, RTUID uid, RTGID gid) 345 { 346 #if 0 347 PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis; 348 return RTFileSetOwner(pThis->hFile, uid, gid); 349 #else 350 NOREF(pvThis); NOREF(uid); NOREF(gid); 351 return VERR_NOT_IMPLEMENTED; 352 #endif 353 } 354 355 356 /** 357 * @interface_method_impl{RTVFSFILEOPS,pfnSeek} 358 */ 359 static DECLCALLBACK(int) rtVfsStdFile_Seek(void *pvThis, RTFOFF offSeek, unsigned uMethod, PRTFOFF poffActual) 360 { 361 PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis; 362 uint64_t offActual = 0; 363 int rc = RTFileSeek(pThis->hFile, offSeek, uMethod, &offActual); 364 if (RT_SUCCESS(rc)) 365 *poffActual = offActual; 366 return rc; 367 } 368 369 370 /** 371 * @interface_method_impl{RTVFSFILEOPS,pfnQuerySize} 372 */ 373 static DECLCALLBACK(int) rtVfsStdFile_QuerySize(void *pvThis, uint64_t *pcbFile) 374 { 375 PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis; 376 return RTFileGetSize(pThis->hFile, pcbFile); 377 } 378 379 380 /** 381 * Standard file operations. 382 */ 383 DECL_HIDDEN_CONST(const RTVFSFILEOPS) g_rtVfsStdFileOps = 384 { 385 { /* Stream */ 386 { /* Obj */ 387 RTVFSOBJOPS_VERSION, 388 RTVFSOBJTYPE_FILE, 389 "StdFile", 390 rtVfsStdFile_Close, 391 rtVfsStdFile_QueryInfo, 392 RTVFSOBJOPS_VERSION 393 }, 394 RTVFSIOSTREAMOPS_VERSION, 395 0, 396 rtVfsStdFile_Read, 397 rtVfsStdFile_Write, 398 rtVfsStdFile_Flush, 399 rtVfsStdFile_PollOne, 400 rtVfsStdFile_Tell, 401 rtVfsStdFile_Skip, 402 NULL /*ZeroFill*/, 403 RTVFSIOSTREAMOPS_VERSION, 243 static DECLCALLBACK(int) rtVfsStdPipe_Tell(void *pvThis, PRTFOFF poffActual) 244 { 245 PRTVFSSTDPIPE pThis = (PRTVFSSTDPIPE)pvThis; 246 *poffActual = pThis->offFakePos; 247 return VINF_SUCCESS; 248 } 249 250 251 /** 252 * Standard pipe operations. 253 */ 254 DECL_HIDDEN_CONST(const RTVFSIOSTREAMOPS) g_rtVfsStdPipeOps = 255 { 256 { /* Obj */ 257 RTVFSOBJOPS_VERSION, 258 RTVFSOBJTYPE_IO_STREAM, 259 "StdFile", 260 rtVfsStdPipe_Close, 261 rtVfsStdPipe_QueryInfo, 262 RTVFSOBJOPS_VERSION 404 263 }, 405 RTVFS FILEOPS_VERSION,264 RTVFSIOSTREAMOPS_VERSION, 406 265 0, 407 { /* ObjSet */ 408 RTVFSOBJSETOPS_VERSION, 409 RT_OFFSETOF(RTVFSFILEOPS, Stream.Obj) - RT_OFFSETOF(RTVFSFILEOPS, ObjSet), 410 rtVfsStdFile_SetMode, 411 rtVfsStdFile_SetTimes, 412 rtVfsStdFile_SetOwner, 413 RTVFSOBJSETOPS_VERSION 414 }, 415 rtVfsStdFile_Seek, 416 rtVfsStdFile_QuerySize, 417 RTVFSFILEOPS_VERSION 266 rtVfsStdPipe_Read, 267 rtVfsStdPipe_Write, 268 rtVfsStdPipe_Flush, 269 rtVfsStdPipe_PollOne, 270 rtVfsStdPipe_Tell, 271 NULL /*rtVfsStdPipe_Skip*/, 272 NULL /*ZeroFill*/, 273 RTVFSIOSTREAMOPS_VERSION, 418 274 }; 419 275 420 276 421 277 /** 422 * Internal worker for RTVfs FileFromRTFile and RTVfsFileOpenNormal.278 * Internal worker for RTVfsIosFromRTPipe and later some create API. 423 279 * 424 280 * @returns IRPT status code. 425 * @param h File The IPRT file handle.281 * @param hPipe The IPRT file handle. 426 282 * @param fOpen The RTFILE_O_XXX flags. 427 283 * @param fLeaveOpen Whether to leave it open or close it. 428 284 * @param phVfsFile Where to return the handle. 429 285 */ 430 static int rtVfsFileFromRT File(RTFILE hFile, uint64_t fOpen, bool fLeaveOpen, PRTVFSFILE phVfsFile)431 { 432 PRTVFSSTD FILE pThis;433 RTVFS FILE hVfsFile;434 int rc = RTVfsNew File(&g_rtVfsStdFileOps, sizeof(RTVFSSTDFILE), fOpen, NIL_RTVFS, NIL_RTVFSLOCK,435 &hVfsFile, (void **)&pThis);286 static int rtVfsFileFromRTPipe(RTPIPE hPipe, uint64_t fOpen, bool fLeaveOpen, PRTVFSIOSTREAM phVfsIos) 287 { 288 PRTVFSSTDPIPE pThis; 289 RTVFSIOSTREAM hVfsIos; 290 int rc = RTVfsNewIoStream(&g_rtVfsStdPipeOps, sizeof(RTVFSSTDPIPE), fOpen, NIL_RTVFS, NIL_RTVFSLOCK, 291 &hVfsIos, (void **)&pThis); 436 292 if (RT_FAILURE(rc)) 437 293 return rc; 438 294 439 pThis->h File = hFile;295 pThis->hPipe = hPipe; 440 296 pThis->fLeaveOpen = fLeaveOpen; 441 *phVfs File = hVfsFile;297 *phVfsIos = hVfsIos; 442 298 return VINF_SUCCESS; 443 299 } 444 300 445 301 446 RTDECL(int) RTVfs FileFromRTFile(RTFILE hFile, uint64_t fOpen, bool fLeaveOpen, PRTVFSFILE phVfsFile)302 RTDECL(int) RTVfsIoStrmFromRTPipe(RTPIPE hPipe, bool fLeaveOpen, PRTVFSIOSTREAM phVfsIos) 447 303 { 448 304 /* 449 * Check the handle validity .305 * Check the handle validity and read/write mode, then create a stream for it. 450 306 */ 451 307 RTFSOBJINFO ObjInfo; 452 int rc = RTFileQueryInfo(hFile, &ObjInfo, RTFSOBJATTRADD_NOTHING); 453 if (RT_FAILURE(rc)) 454 return rc; 455 456 /* 457 * Set up some fake fOpen flags if necessary and create a VFS file handle. 458 */ 459 if (!fOpen) 460 fOpen = RTFILE_O_READWRITE | RTFILE_O_DENY_NONE | RTFILE_O_OPEN_CREATE; 461 462 return rtVfsFileFromRTFile(hFile, fOpen, fLeaveOpen, phVfsFile); 463 } 464 465 466 RTDECL(int) RTVfsFileOpenNormal(const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile) 467 { 468 /* 469 * Open the file the normal way and pass it to RTVfsFileFromRTFile. 470 */ 471 RTFILE hFile; 472 int rc = RTFileOpen(&hFile, pszFilename, fOpen); 308 int rc = RTPipeQueryInfo(hPipe, &ObjInfo, RTFSOBJATTRADD_NOTHING); 473 309 if (RT_SUCCESS(rc)) 474 { 475 /* 476 * Create a VFS file handle. 477 */ 478 rc = rtVfsFileFromRTFile(hFile, fOpen, false /*fLeaveOpen*/, phVfsFile); 479 if (RT_FAILURE(rc)) 480 RTFileClose(hFile); 481 } 482 return rc; 483 } 484 485 486 RTDECL(int) RTVfsIoStrmFromRTFile(RTFILE hFile, uint64_t fOpen, bool fLeaveOpen, PRTVFSIOSTREAM phVfsIos) 487 { 488 RTVFSFILE hVfsFile; 489 int rc = RTVfsFileFromRTFile(hFile, fOpen, fLeaveOpen, &hVfsFile); 490 if (RT_SUCCESS(rc)) 491 { 492 *phVfsIos = RTVfsFileToIoStream(hVfsFile); 493 RTVfsFileRelease(hVfsFile); 494 } 495 return rc; 496 } 497 498 499 RTDECL(int) RTVfsIoStrmOpenNormal(const char *pszFilename, uint64_t fOpen, PRTVFSIOSTREAM phVfsIos) 500 { 501 RTVFSFILE hVfsFile; 502 int rc = RTVfsFileOpenNormal(pszFilename, fOpen, &hVfsFile); 503 if (RT_SUCCESS(rc)) 504 *phVfsIos = RTVfsFileToIoStream(hVfsFile); 505 return rc; 506 } 507 310 rc = rtVfsFileFromRTPipe(hPipe, 311 ObjInfo.Attr.fMode & RTFS_DOS_READONLY ? RTFILE_O_READ : RTFILE_O_WRITE, 312 fLeaveOpen, phVfsIos); 313 return rc; 314 } 315 316 /** @todo Create pipe API? */ 317
Note:
See TracChangeset
for help on using the changeset viewer.