/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ //#define INCL_DOSERRORS #include "system.h" #include #include #include #include #include #include #include #include #include #define PIPENAMEMASK "OSL_PIPE_%s" #define SECPIPENAMEMASK "OSL_PIPE_%s_%s" typedef enum { MSG_SYN, MSG_FIN, MSG_DATA, MSG_UNKNOWN } MessageType; struct oslPipeImpl { oslInterlockedCount m_Reference; HPIPE hPipe; HMTX m_NamedObject; APIRET nLastError; //oslSecurity m_Security; sal_Bool m_bClosed; }; /* default size for input/output buffer */ static const ULONG ulBufSize = 4096; /* OS/2 path for pipes */ static const CHAR pszPipePath[] = "\\PIPE\\"; static const UCHAR nPipePathLen = sizeof (pszPipePath) - 1; /* global last error value to be returned from oslGetLastPipeError */ static APIRET ngLastError; using rtl::OString; using rtl::OUString; using rtl::OUStringToOString; /*****************************************************************************/ /* osl_create/destroy-PipeImpl */ /*****************************************************************************/ static oslInterlockedCount nPipes = 0; oslPipe __osl_createPipeImpl(void) { oslPipe pPipe; pPipe = (oslPipe) calloc(1,sizeof(struct oslPipeImpl)); pPipe->m_bClosed = sal_False; pPipe->m_Reference = 1; pPipe->hPipe = NULL; pPipe->m_NamedObject = NULL; return pPipe; } void __osl_destroyPipeImpl(oslPipe pPipe) { if (pPipe != NULL) { DosCloseMutexSem( pPipe->m_NamedObject); free(pPipe); } } /*****************************************************************************/ /* osl_createPipe */ /*****************************************************************************/ oslPipe SAL_CALL osl_createPipe(rtl_uString *ustrPipeName, oslPipeOptions Options, oslSecurity Security) { oslPipe pPipe; ULONG ulAction; CHAR strPipeNameBuffer [CCHMAXPATHCOMP]; rtl_String* strPipeName=0; sal_Char* pszPipeName=0; /* check parameters */ OSL_ASSERT( ustrPipeName ); //YD 17/04/06 OSL_ASSERT( Security == 0 ); /* allocate impl-structure */ pPipe = __osl_createPipeImpl(); if (!pPipe) { OSL_TRACE( "osl_createPipe failed allocating memory.\n" ); return NULL; } /* create pipe name */ OString sPipe = OUStringToOString(ustrPipeName, RTL_TEXTENCODING_ASCII_US); #if OSL_DEBUG_LEVEL>0 debug_printf("osl_createPipe options 0x%x\n", Options); #endif switch( Options ) { case osl_Pipe_OPEN: { APIRET fPipeAvailable; sprintf (strPipeNameBuffer, "\\PIPE\\OSL_PIPE_%s", sPipe.getStr()); #if OSL_DEBUG_LEVEL>0 debug_printf("osl_createPipe %s\n", strPipeNameBuffer); #endif ngLastError = DosOpen( (PCSZ)strPipeNameBuffer, &(pPipe->hPipe), &ulAction, 0, FILE_NORMAL, FILE_OPEN, OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE, (PEAOP2) NULL); // if pipe is busy, wait for it if (ngLastError == ERROR_PIPE_BUSY) do { /* free instance should be available first */ fPipeAvailable = DosWaitNPipe( (PCSZ)strPipeNameBuffer, -1); /* first try to open system pipe */ if ( fPipeAvailable == NO_ERROR ) { // We got it ! ngLastError = NO_ERROR; break; } // Pipe instance maybe catched by another client -> try again printf("osl_createPipe wait for Pipe available\n"); } while ( fPipeAvailable ); } break; case osl_Pipe_CREATE: { sprintf (strPipeNameBuffer, "\\SEM32\\OSL_SEM_%s", sPipe.getStr()); // check if semaphore exists (pipe create must fail for existig pipes) ngLastError = DosCreateMutexSem( (PCSZ)strPipeNameBuffer, &(pPipe->m_NamedObject), 0, TRUE ); if (ngLastError) break; sprintf (strPipeNameBuffer, "\\PIPE\\OSL_PIPE_%s", sPipe.getStr()); #if OSL_DEBUG_LEVEL>0 debug_printf("osl_createPipe %s\n", strPipeNameBuffer); #endif ngLastError = DosCreateNPipe( (PCSZ)strPipeNameBuffer, &(pPipe->hPipe), NP_ACCESS_DUPLEX, /* open pipe for read and write access */ 0xFF, /* allow unlimited number of instances */ ulBufSize, /* output buffer size */ ulBufSize, /* input buffer size */ 0L /* use default time-out time */ ); } break; default: ngLastError = ERROR_INVALID_PARAMETER; } /* if failed, release allocated memory */ if (ngLastError) { OSL_TRACE( "osl_createPipe failed %s the pipe %s, Error Code %d.\n", Options == osl_Pipe_OPEN ? "opening" : "creating", strPipeNameBuffer, ngLastError ); __osl_destroyPipeImpl(pPipe); return NULL; } pPipe->m_Reference= 1; pPipe->m_bClosed = sal_False; //pPipe->m_Security = Security; pPipe->nLastError = NO_ERROR; return (oslPipe)pPipe; } /*****************************************************************************/ /* osl_copyPipe */ /*****************************************************************************/ oslPipe SAL_CALL osl_copyPipe(oslPipe pPipe) { //oslPipe* pPipe = (oslPipe*) Pipe; oslPipe pNewPipe; /* check parameter */ OSL_ASSERT (pPipe); /* allocate impl-structure */ pNewPipe = __osl_createPipeImpl(); if (!pNewPipe) return NULL; /* create new handle */ pNewPipe->hPipe = (HPIPE) -1; ngLastError = DosDupHandle( pPipe->hPipe, &(pNewPipe->hPipe) ); /* if failed, release allocated memory */ if (ngLastError) { OSL_TRACE( "osl_copyPipe failed duplicating pipe handle, Error-Code: %d.\n", ngLastError ); free (pNewPipe); return NULL; } pNewPipe->nLastError = NO_ERROR; return (oslPipe)pNewPipe; } void SAL_CALL osl_acquirePipe( oslPipe pPipe ) { osl_incrementInterlockedCount( &(pPipe->m_Reference) ); } void SAL_CALL osl_releasePipe( oslPipe pPipe ) { // OSL_ASSERT( pPipe ); if( 0 == pPipe ) return; if( 0 == osl_decrementInterlockedCount( &(pPipe->m_Reference) ) ) { if( ! pPipe->m_bClosed ) osl_closePipe( pPipe ); __osl_destroyPipeImpl( pPipe ); } } /*****************************************************************************/ /* osl_destroyPipe */ /*************close****************************************************************/ void SAL_CALL osl_closePipe(oslPipe pPipe) { //oslPipe* pPipe = (oslPipe*) Pipe; /* check parameter */ OSL_ASSERT (pPipe); if( pPipe && ! pPipe->m_bClosed ) { pPipe->m_bClosed = sal_True; /* if we have a system pipe close it */ if (pPipe->hPipe != 0) { /* disconnect client */ DosDisConnectNPipe (pPipe->hPipe); /* close the pipe */ DosClose (pPipe->hPipe); } } } /*****************************************************************************/ /* osl_acceptPipe */ /*****************************************************************************/ oslPipe SAL_CALL osl_acceptPipe(oslPipe pPipe) { #define PINFO ((PIPEINFO *) &PipeInfoBuffer) ///oslPipe* pPipe = (oslPipe*) Pipe; oslPipe pNewPipe; BYTE PipeInfoBuffer[sizeof(PIPEINFO) + CCHMAXPATHCOMP]; /* check parameter */ OSL_ASSERT (pPipe); /* get pipe information */ pPipe->nLastError = DosQueryNPipeInfo(pPipe->hPipe, 1, (PVOID) &PipeInfoBuffer, sizeof(PipeInfoBuffer)); if (pPipe->nLastError) { OSL_TRACE( "osl_acceptPipe failed for requesting pipe information.\n", pPipe->nLastError ); return NULL; } /* create a new instance of the pipe if possible */ if (PINFO->cbMaxInst == -1 || /* unlimited instances */ PINFO->cbMaxInst > PINFO->cbCurInst) { HPIPE hPipe; pNewPipe = __osl_createPipeImpl(); if (!pNewPipe) { OSL_TRACE( "osl_acceptPipe failed creating new instance.\n", ngLastError ); free(pNewPipe); return NULL; } //pNewPipe->m_Security = pPipe->m_Security; pNewPipe->nLastError = DosCreateNPipe( (PCSZ)PINFO->szName, &(pNewPipe->hPipe), NP_ACCESS_DUPLEX, /* open pipe for read and write access */ 0xFF, /* allow unlimited number of instances */ ulBufSize, /* output buffer size */ ulBufSize, /* input buffer size */ 0L /* use default time-out time */ ); if (pNewPipe->nLastError) { OSL_TRACE( "osl_acceptPipe failed creating new named pipe, Error-Code: %d.\n", pNewPipe->nLastError ); free(pNewPipe); return NULL; } /* switch pipe handles */ hPipe = pPipe->hPipe; pPipe->hPipe = pNewPipe->hPipe; pNewPipe->hPipe = hPipe; /* connect new handle to client */ pNewPipe->nLastError = DosConnectNPipe( pNewPipe->hPipe ); /* if failed, release allocated memory */ if (pNewPipe->nLastError) { OSL_TRACE( "osl_acceptPipe failed connecting pipe to client, Error-Code: %d.\n", pNewPipe->nLastError ); osl_closePipe((oslPipe)pNewPipe); return NULL; } return (oslPipe)pNewPipe; } else { /* connect original handle to client */ pPipe->nLastError = DosConnectNPipe( pPipe->hPipe ); if (pPipe->nLastError) { OSL_TRACE( "osl_acceptPipe failed connecting pipe to client, Error-Code: %d.\n", pPipe->nLastError ); return NULL; } return (oslPipe)pPipe; } } /*****************************************************************************/ /* osl_receivePipe */ /*****************************************************************************/ sal_Int32 SAL_CALL osl_receivePipe(oslPipe pPipe, void* pBuffer, sal_Int32 BytesToRead) { //oslPipe* pPipe = (oslPipe*) Pipe; ULONG ulActual; /* check parameter */ OSL_ASSERT (pPipe); /* read data from pipe */ pPipe->nLastError = DosRead( pPipe->hPipe, pBuffer, BytesToRead, &ulActual ); /* return -1 if failed */ if( pPipe->nLastError ) { OSL_TRACE( "osl_receivePipe failed receiving from Pipe, Error-Code: %d.\n", pPipe->nLastError ); return -1; } return ulActual; } /*****************************************************************************/ /* osl_sendPipe */ /*****************************************************************************/ sal_Int32 SAL_CALL osl_sendPipe(oslPipe pPipe, const void* pBuffer, sal_Int32 BytesToSend) { //oslPipe* pPipe = (oslPipe*) Pipe; ULONG ulActual; /* check parameter */ OSL_ASSERT (pPipe); /* read data from pipe */ pPipe->nLastError = DosWrite( pPipe->hPipe, (PVOID) pBuffer, BytesToSend, &ulActual ); /* return -1 if failed */ if( pPipe->nLastError ) { OSL_TRACE( "osl_receivePipe failed writing to Pipe, Error-Code: %d.\n", pPipe->nLastError ); return -1; } return ulActual; } /*****************************************************************************/ /* osl_getLastPipeError */ /*****************************************************************************/ oslPipeError SAL_CALL osl_getLastPipeError(oslPipe pPipe) { //oslPipe* pPipe = (oslPipe*) Pipe; APIRET rc; /* return local error value if possible */ if (pPipe) { rc = pPipe->nLastError; pPipe->nLastError = NO_ERROR; } else rc = ngLastError; /* map OS/2 error values */ switch (rc) { case NO_ERROR: return osl_Pipe_E_None; case ERROR_PATH_NOT_FOUND: return osl_Pipe_E_NotFound; case ERROR_NOT_ENOUGH_MEMORY: return osl_Pipe_E_NoBufferSpace; default: return osl_Pipe_E_invalidError; } } /*****************************************************************************/ sal_Int32 SAL_CALL osl_writePipe( oslPipe pPipe, const void *pBuffer , sal_Int32 n ) { /* loop until all desired bytes were send or an error occurred */ sal_Int32 BytesSend= 0; sal_Int32 BytesToSend= n; OSL_ASSERT(pPipe); while (BytesToSend > 0) { sal_Int32 RetVal; RetVal= osl_sendPipe(pPipe, pBuffer, BytesToSend); /* error occurred? */ if(RetVal <= 0) { break; } BytesToSend -= RetVal; BytesSend += RetVal; pBuffer= (sal_Char*)pBuffer + RetVal; } return BytesSend; } sal_Int32 SAL_CALL osl_readPipe( oslPipe pPipe, void *pBuffer , sal_Int32 n ) { /* loop until all desired bytes were read or an error occurred */ sal_Int32 BytesRead= 0; sal_Int32 BytesToRead= n; OSL_ASSERT( pPipe ); while (BytesToRead > 0) { sal_Int32 RetVal; RetVal= osl_receivePipe(pPipe, pBuffer, BytesToRead); /* error occurred? */ if(RetVal <= 0) { break; } BytesToRead -= RetVal; BytesRead += RetVal; pBuffer= (sal_Char*)pBuffer + RetVal; } return BytesRead; } /****************************************************************************** * * New io resource transfer functions * *****************************************************************************/ /********************************************** osl_sendResourcePipe *********************************************/ sal_Bool osl_sendResourcePipe(oslPipe pPipe, oslSocket pSocket) { sal_Bool bRet = sal_False; return bRet; } /********************************************** osl_receiveResourcePipe *********************************************/ oslSocket osl_receiveResourcePipe(oslPipe pPipe) { oslSocket pSocket=0; return (oslSocket) pSocket; }