VirtualBox

Ignore:
Timestamp:
Sep 7, 2015 1:47:08 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
102533
Message:

IPRT: Added RTVfsIoStrmFromRTPipe (and RTPipeQueryInfo) for the purpose of making RTVfsIoStrmFromStdHandle be able to work with pipes. Mostly untested.

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  
    7171
    7272            case RTHANDLETYPE_PIPE:
    73                 /** @todo  */
    74                 rc = VERR_NOT_IMPLEMENTED;
     73                rc = RTVfsIoStrmFromRTPipe(h.u.hPipe, fLeaveOpen, phVfsIos);
    7574                break;
    7675
  • trunk/src/VBox/Runtime/common/vfs/vfsstdpipe.cpp

    r57635 r57643  
    11/* $Id$ */
    22/** @file
    3  * IPRT - Virtual File System, Standard File Implementation.
     3 * IPRT - Virtual File System, Standard Pipe I/O stream Implementation.
    44 */
    55
     
    3232#include <iprt/vfslowlevel.h>
    3333
     34#include <iprt/assert.h>
    3435#include <iprt/err.h>
    3536#include <iprt/file.h>
     37#include <iprt/pipe.h>
    3638#include <iprt/poll.h>
    37 #include <iprt/thread.h>
    3839
    3940
     
    4243*********************************************************************************************************************************/
    4344/**
    44  * Private data of a standard file.
    45  */
    46 typedef struct RTVFSSTDFILE
    47 {
    48     /** The file handle. */
    49     RTFILE          hFile;
     45 * Private data of a standard pipe.
     46 */
     47typedef struct RTVFSSTDPIPE
     48{
     49    /** The pipe handle. */
     50    RTPIPE          hPipe;
    5051    /** Whether to leave the handle open when the VFS handle is closed. */
    5152    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. */
     59typedef RTVFSSTDPIPE *PRTVFSSTDPIPE;
    5560
    5661
     
    5863 * @interface_method_impl{RTVFSOBJOPS,pfnClose}
    5964 */
    60 static DECLCALLBACK(int) rtVfsStdFile_Close(void *pvThis)
    61 {
    62     PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis;
     65static DECLCALLBACK(int) rtVfsStdPipe_Close(void *pvThis)
     66{
     67    PRTVFSSTDPIPE pThis = (PRTVFSSTDPIPE)pvThis;
    6368
    6469    int rc;
    6570    if (!pThis->fLeaveOpen)
    66         rc = RTFileClose(pThis->hFile);
     71        rc = RTPipeClose(pThis->hPipe);
    6772    else
    6873        rc = VINF_SUCCESS;
    69     pThis->hFile = NIL_RTFILE;
     74    pThis->hPipe = NIL_RTPIPE;
    7075
    7176    return rc;
     
    7681 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo}
    7782 */
    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;
     83static DECLCALLBACK(int) rtVfsStdPipe_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
     84{
     85    PRTVFSSTDPIPE pThis = (PRTVFSSTDPIPE)pvThis;
     86    return RTPipeQueryInfo(pThis->hPipe, pObjInfo, enmAddAttr);
    12687}
    12788
     
    13091 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead}
    13192 */
    132 static DECLCALLBACK(int) rtVfsStdFile_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
    133 {
    134     PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis;
     93static DECLCALLBACK(int) rtVfsStdPipe_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
     94{
     95    PRTVFSSTDPIPE pThis = (PRTVFSSTDPIPE)pvThis;
    13596    int           rc;
     97    AssertReturn(off < 0 || pThis->offFakePos == off, VERR_SEEK_ON_DEVICE);
    13698
    13799    NOREF(fBlocking);
    138100    if (pSgBuf->cSegs == 1)
    139101    {
    140         if (off < 0)
    141             rc = RTFileRead(  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);
    142104        else
    143             rc = RTFileReadAt(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;
    146108    }
    147109    else
     
    150112        size_t  cbRead     = 0;
    151113        size_t  cbReadSeg  = 0;
     114        size_t *pcbReadSeg = pcbRead ? &cbReadSeg : NULL;
    152115        rc = VINF_SUCCESS;
    153116
     
    158121
    159122            cbReadSeg = cbSeg;
    160             if (off < 0)
    161                 rc = RTFileRead(  pThis->hFile,      pvSeg, cbSeg, pcbRead ? &cbReadSeg : NULL);
     123            if (fBlocking)
     124                rc = RTPipeReadBlocking(pThis->hPipe, pvSeg, cbSeg, pcbReadSeg);
    162125            else
    163                 rc = RTFileReadAt(pThis->hFile, off, pvSeg, cbSeg, pcbRead ? &cbReadSeg : NULL);
     126                rc = RTPipeRead(        pThis->hPipe, pvSeg, cbSeg, pcbReadSeg);
    164127            if (RT_FAILURE(rc))
    165128                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)
    170132                break;
     133            AssertBreakStmt(!pcbRead || cbReadSeg == cbSeg, rc = VINF_TRY_AGAIN);
    171134        }
    172135
    173136        if (pcbRead)
    174         {
    175137            *pcbRead = cbRead;
    176             if (rc == VINF_SUCCESS)
    177                 rc = rtVfsStdFile_ReadFixRC(pThis, off, cbSeg, cbReadSeg);
    178         }
    179138    }
    180139
     
    186145 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnWrite}
    187146 */
    188 static DECLCALLBACK(int) rtVfsStdFile_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
    189 {
    190     PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis;
     147static DECLCALLBACK(int) rtVfsStdPipe_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
     148{
     149    PRTVFSSTDPIPE pThis = (PRTVFSSTDPIPE)pvThis;
    191150    int           rc;
    192 
    193     NOREF(fBlocking);
     151    AssertReturn(off < 0 || pThis->offFakePos == off, VERR_SEEK_ON_DEVICE);
     152
    194153    if (pSgBuf->cSegs == 1)
    195154    {
    196         if (off < 0)
    197             rc = RTFileWrite(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);
    198157        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;
    200161    }
    201162    else
     
    212173
    213174            cbWrittenSeg = 0;
    214             if (off < 0)
    215                 rc = RTFileWrite(pThis->hFile, pvSeg, cbSeg, pcbWrittenSeg);
     175            if (fBlocking)
     176                rc = RTPipeWriteBlocking(pThis->hPipe, pvSeg, cbSeg, pcbWrittenSeg);
    216177            else
    217             {
    218                 rc = RTFileWriteAt(pThis->hFile, off, pvSeg, cbSeg, pcbWrittenSeg);
    219                 off += cbSeg;
    220             }
     178                rc = RTPipeWrite(        pThis->hPipe, pvSeg, cbSeg, pcbWrittenSeg);
    221179            if (RT_FAILURE(rc))
    222180                break;
     181            pThis->offFakePos += pcbWritten ? cbWrittenSeg : cbSeg;
    223182            if (pcbWritten)
    224183            {
    225184                cbWritten += cbWrittenSeg;
    226                 if (cbWrittenSeg != cbSeg)
     185                if (rc != VINF_SUCCESS)
    227186                    break;
     187                AssertStmt(cbWrittenSeg == cbSeg, rc = VINF_TRY_AGAIN);
    228188            }
     189            else
     190                AssertBreak(rc == VINF_SUCCESS);
    229191        }
    230192
     
    240202 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnFlush}
    241203 */
    242 static DECLCALLBACK(int) rtVfsStdFile_Flush(void *pvThis)
    243 {
    244     PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis;
    245     return RTFileFlush(pThis->hFile);
     204static DECLCALLBACK(int) rtVfsStdPipe_Flush(void *pvThis)
     205{
     206    PRTVFSSTDPIPE pThis = (PRTVFSSTDPIPE)pvThis;
     207    return RTPipeFlush(pThis->hPipe);
    246208}
    247209
     
    250212 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnPollOne}
    251213 */
    252 static DECLCALLBACK(int) rtVfsStdFile_PollOne(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
     214static DECLCALLBACK(int) rtVfsStdPipe_PollOne(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
    253215                                              uint32_t *pfRetEvents)
    254216{
    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;
    260233        rc = VINF_SUCCESS;
    261234    }
    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
    275236    return rc;
    276237}
     
    280241 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnTell}
    281242 */
    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,
     243static 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 */
     254DECL_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
    404263    },
    405     RTVFSFILEOPS_VERSION,
     264    RTVFSIOSTREAMOPS_VERSION,
    406265    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,
    418274};
    419275
    420276
    421277/**
    422  * Internal worker for RTVfsFileFromRTFile and RTVfsFileOpenNormal.
     278 * Internal worker for RTVfsIosFromRTPipe and later some create API.
    423279 *
    424280 * @returns IRPT status code.
    425  * @param   hFile               The IPRT file handle.
     281 * @param   hPipe               The IPRT file handle.
    426282 * @param   fOpen               The RTFILE_O_XXX flags.
    427283 * @param   fLeaveOpen          Whether to leave it open or close it.
    428284 * @param   phVfsFile           Where to return the handle.
    429285 */
    430 static int rtVfsFileFromRTFile(RTFILE hFile, uint64_t fOpen, bool fLeaveOpen, PRTVFSFILE phVfsFile)
    431 {
    432     PRTVFSSTDFILE   pThis;
    433     RTVFSFILE       hVfsFile;
    434     int rc = RTVfsNewFile(&g_rtVfsStdFileOps, sizeof(RTVFSSTDFILE), fOpen, NIL_RTVFS, NIL_RTVFSLOCK,
    435                           &hVfsFile, (void **)&pThis);
     286static 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);
    436292    if (RT_FAILURE(rc))
    437293        return rc;
    438294
    439     pThis->hFile        = hFile;
     295    pThis->hPipe        = hPipe;
    440296    pThis->fLeaveOpen   = fLeaveOpen;
    441     *phVfsFile = hVfsFile;
     297    *phVfsIos = hVfsIos;
    442298    return VINF_SUCCESS;
    443299}
    444300
    445301
    446 RTDECL(int) RTVfsFileFromRTFile(RTFILE hFile, uint64_t fOpen, bool fLeaveOpen, PRTVFSFILE phVfsFile)
     302RTDECL(int) RTVfsIoStrmFromRTPipe(RTPIPE hPipe, bool fLeaveOpen, PRTVFSIOSTREAM phVfsIos)
    447303{
    448304    /*
    449      * Check the handle validity.
     305     * Check the handle validity and read/write mode, then create a stream for it.
    450306     */
    451307    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);
    473309    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.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette