1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pipe.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 //#define INCL_DOSERRORS
35 #include <osl/diagnose.h>
36 #include <osl/thread.h>
37 #include <osl/mutex.h>
38 #include <osl/semaphor.h>
39 #include <osl/conditn.h>
40 #include <osl/interlck.h>
41 #include <osl/process.h>
42 #include <rtl/ustring.hxx>
44 #define PIPENAMEMASK "OSL_PIPE_%s"
45 #define SECPIPENAMEMASK "OSL_PIPE_%s_%s"
55 oslInterlockedCount m_Reference
;
59 //oslSecurity m_Security;
63 /* default size for input/output buffer */
64 static const ULONG ulBufSize
= 4096;
66 /* OS/2 path for pipes */
67 static const CHAR pszPipePath
[] = "\\PIPE\\";
68 static const UCHAR nPipePathLen
= sizeof (pszPipePath
) - 1;
70 /* global last error value to be returned from oslGetLastPipeError */
71 static APIRET ngLastError
;
75 using rtl::OUStringToOString
;
77 /*****************************************************************************/
78 /* osl_create/destroy-PipeImpl */
79 /*****************************************************************************/
81 static oslInterlockedCount nPipes
= 0;
83 oslPipe
__osl_createPipeImpl(void)
87 pPipe
= (oslPipe
) calloc(1,sizeof(struct oslPipeImpl
));
89 pPipe
->m_bClosed
= sal_False
;
90 pPipe
->m_Reference
= 1;
92 pPipe
->m_NamedObject
= NULL
;
97 void __osl_destroyPipeImpl(oslPipe pPipe
)
101 DosCloseMutexSem( pPipe
->m_NamedObject
);
107 /*****************************************************************************/
109 /*****************************************************************************/
110 oslPipe SAL_CALL
osl_createPipe(rtl_uString
*ustrPipeName
, oslPipeOptions Options
,
111 oslSecurity Security
)
116 CHAR strPipeNameBuffer
[CCHMAXPATHCOMP
];
117 rtl_String
* strPipeName
=0;
118 sal_Char
* pszPipeName
=0;
120 /* check parameters */
121 OSL_ASSERT( ustrPipeName
);
122 //YD 17/04/06 OSL_ASSERT( Security == 0 );
124 /* allocate impl-structure */
125 pPipe
= __osl_createPipeImpl();
128 OSL_TRACE( "osl_createPipe failed allocating memory.\n" );
132 /* create pipe name */
133 OString sPipe
= OUStringToOString(ustrPipeName
, RTL_TEXTENCODING_ASCII_US
);
134 #if OSL_DEBUG_LEVEL>0
135 debug_printf("osl_createPipe options 0x%x\n", Options
);
142 APIRET fPipeAvailable
;
144 sprintf (strPipeNameBuffer
, "\\PIPE\\OSL_PIPE_%s", sPipe
.getStr());
145 #if OSL_DEBUG_LEVEL>0
146 debug_printf("osl_createPipe %s\n", strPipeNameBuffer
);
148 ngLastError
= DosOpen( (PCSZ
)strPipeNameBuffer
,
149 &(pPipe
->hPipe
), &ulAction
,
150 0, FILE_NORMAL
, FILE_OPEN
,
151 OPEN_ACCESS_READWRITE
| OPEN_SHARE_DENYREADWRITE
,
153 // if pipe is busy, wait for it
154 if (ngLastError
== ERROR_PIPE_BUSY
)
157 /* free instance should be available first */
158 fPipeAvailable
= DosWaitNPipe( (PCSZ
)strPipeNameBuffer
, -1);
159 /* first try to open system pipe */
160 if ( fPipeAvailable
== NO_ERROR
)
163 ngLastError
= NO_ERROR
;
166 // Pipe instance maybe catched by another client -> try again
167 printf("osl_createPipe wait for Pipe available\n");
168 } while ( fPipeAvailable
);
171 case osl_Pipe_CREATE
:
173 sprintf (strPipeNameBuffer
, "\\SEM32\\OSL_SEM_%s", sPipe
.getStr());
174 // check if semaphore exists (pipe create must fail for existig pipes)
175 ngLastError
= DosCreateMutexSem( (PCSZ
)strPipeNameBuffer
, &(pPipe
->m_NamedObject
), 0, TRUE
);
179 sprintf (strPipeNameBuffer
, "\\PIPE\\OSL_PIPE_%s", sPipe
.getStr());
180 #if OSL_DEBUG_LEVEL>0
181 debug_printf("osl_createPipe %s\n", strPipeNameBuffer
);
183 ngLastError
= DosCreateNPipe( (PCSZ
)strPipeNameBuffer
,
185 NP_ACCESS_DUPLEX
, /* open pipe for read and write access */
186 0xFF, /* allow unlimited number of instances */
187 ulBufSize
, /* output buffer size */
188 ulBufSize
, /* input buffer size */
189 0L /* use default time-out time */
194 ngLastError
= ERROR_INVALID_PARAMETER
;
197 /* if failed, release allocated memory */
200 OSL_TRACE( "osl_createPipe failed %s the pipe %s, Error Code %d.\n",
201 Options
== osl_Pipe_OPEN
? "opening" : "creating",
204 __osl_destroyPipeImpl(pPipe
);
208 pPipe
->m_Reference
= 1;
209 pPipe
->m_bClosed
= sal_False
;
210 //pPipe->m_Security = Security;
211 pPipe
->nLastError
= NO_ERROR
;
212 return (oslPipe
)pPipe
;
215 /*****************************************************************************/
217 /*****************************************************************************/
218 oslPipe SAL_CALL
osl_copyPipe(oslPipe pPipe
)
220 //oslPipe* pPipe = (oslPipe*) Pipe;
224 /* check parameter */
227 /* allocate impl-structure */
228 pNewPipe
= __osl_createPipeImpl();
229 if (!pNewPipe
) return NULL
;
231 /* create new handle */
232 pNewPipe
->hPipe
= (HPIPE
) -1;
233 ngLastError
= DosDupHandle( pPipe
->hPipe
, &(pNewPipe
->hPipe
) );
235 /* if failed, release allocated memory */
238 OSL_TRACE( "osl_copyPipe failed duplicating pipe handle, Error-Code: %d.\n",
244 pNewPipe
->nLastError
= NO_ERROR
;
245 return (oslPipe
)pNewPipe
;
248 void SAL_CALL
osl_acquirePipe( oslPipe pPipe
)
250 osl_incrementInterlockedCount( &(pPipe
->m_Reference
) );
253 void SAL_CALL
osl_releasePipe( oslPipe pPipe
)
255 // OSL_ASSERT( pPipe );
260 if( 0 == osl_decrementInterlockedCount( &(pPipe
->m_Reference
) ) )
262 if( ! pPipe
->m_bClosed
)
263 osl_closePipe( pPipe
);
265 __osl_destroyPipeImpl( pPipe
);
269 /*****************************************************************************/
270 /* osl_destroyPipe */
271 /*************close****************************************************************/
272 void SAL_CALL
osl_closePipe(oslPipe pPipe
)
274 //oslPipe* pPipe = (oslPipe*) Pipe;
275 /* check parameter */
278 if( pPipe
&& ! pPipe
->m_bClosed
)
280 pPipe
->m_bClosed
= sal_True
;
281 /* if we have a system pipe close it */
282 if (pPipe
->hPipe
!= 0)
284 /* disconnect client */
285 DosDisConnectNPipe (pPipe
->hPipe
);
288 DosClose (pPipe
->hPipe
);
293 /*****************************************************************************/
295 /*****************************************************************************/
296 oslPipe SAL_CALL
osl_acceptPipe(oslPipe pPipe
)
299 #define PINFO ((PIPEINFO *) &PipeInfoBuffer)
301 ///oslPipe* pPipe = (oslPipe*) Pipe;
303 BYTE PipeInfoBuffer
[sizeof(PIPEINFO
) + CCHMAXPATHCOMP
];
305 /* check parameter */
308 /* get pipe information */
309 pPipe
->nLastError
= DosQueryNPipeInfo(pPipe
->hPipe
,
311 (PVOID
) &PipeInfoBuffer
,
312 sizeof(PipeInfoBuffer
));
314 if (pPipe
->nLastError
)
316 OSL_TRACE( "osl_acceptPipe failed for requesting pipe information.\n",
321 /* create a new instance of the pipe if possible */
322 if (PINFO
->cbMaxInst
== -1 || /* unlimited instances */
323 PINFO
->cbMaxInst
> PINFO
->cbCurInst
)
327 pNewPipe
= __osl_createPipeImpl();
331 OSL_TRACE( "osl_acceptPipe failed creating new instance.\n", ngLastError
);
336 //pNewPipe->m_Security = pPipe->m_Security;
338 pNewPipe
->nLastError
=
339 DosCreateNPipe( (PCSZ
)PINFO
->szName
,
341 NP_ACCESS_DUPLEX
, /* open pipe for read and write access */
342 0xFF, /* allow unlimited number of instances */
343 ulBufSize
, /* output buffer size */
344 ulBufSize
, /* input buffer size */
345 0L /* use default time-out time */
348 if (pNewPipe
->nLastError
)
350 OSL_TRACE( "osl_acceptPipe failed creating new named pipe, Error-Code: %d.\n",
351 pNewPipe
->nLastError
);
356 /* switch pipe handles */
357 hPipe
= pPipe
->hPipe
;
358 pPipe
->hPipe
= pNewPipe
->hPipe
;
359 pNewPipe
->hPipe
= hPipe
;
361 /* connect new handle to client */
362 pNewPipe
->nLastError
= DosConnectNPipe( pNewPipe
->hPipe
);
364 /* if failed, release allocated memory */
365 if (pNewPipe
->nLastError
)
367 OSL_TRACE( "osl_acceptPipe failed connecting pipe to client, Error-Code: %d.\n",
368 pNewPipe
->nLastError
);
370 osl_closePipe((oslPipe
)pNewPipe
);
373 return (oslPipe
)pNewPipe
;
377 /* connect original handle to client */
378 pPipe
->nLastError
= DosConnectNPipe( pPipe
->hPipe
);
380 if (pPipe
->nLastError
)
382 OSL_TRACE( "osl_acceptPipe failed connecting pipe to client, Error-Code: %d.\n",
387 return (oslPipe
)pPipe
;
391 /*****************************************************************************/
392 /* osl_receivePipe */
393 /*****************************************************************************/
394 sal_Int32 SAL_CALL
osl_receivePipe(oslPipe pPipe
,
396 sal_Int32 BytesToRead
)
398 //oslPipe* pPipe = (oslPipe*) Pipe;
401 /* check parameter */
404 /* read data from pipe */
405 pPipe
->nLastError
= DosRead( pPipe
->hPipe
, pBuffer
, BytesToRead
, &ulActual
);
407 /* return -1 if failed */
408 if( pPipe
->nLastError
)
410 OSL_TRACE( "osl_receivePipe failed receiving from Pipe, Error-Code: %d.\n",
419 /*****************************************************************************/
421 /*****************************************************************************/
422 sal_Int32 SAL_CALL
osl_sendPipe(oslPipe pPipe
,
424 sal_Int32 BytesToSend
)
426 //oslPipe* pPipe = (oslPipe*) Pipe;
429 /* check parameter */
432 /* read data from pipe */
433 pPipe
->nLastError
= DosWrite( pPipe
->hPipe
, (PVOID
) pBuffer
, BytesToSend
, &ulActual
);
435 /* return -1 if failed */
436 if( pPipe
->nLastError
)
438 OSL_TRACE( "osl_receivePipe failed writing to Pipe, Error-Code: %d.\n",
447 /*****************************************************************************/
448 /* osl_getLastPipeError */
449 /*****************************************************************************/
451 oslPipeError SAL_CALL
osl_getLastPipeError(oslPipe pPipe
)
453 //oslPipe* pPipe = (oslPipe*) Pipe;
456 /* return local error value if possible */
459 rc
= pPipe
->nLastError
;
460 pPipe
->nLastError
= NO_ERROR
;
464 /* map OS/2 error values */
467 case NO_ERROR
: return osl_Pipe_E_None
;
468 case ERROR_PATH_NOT_FOUND
: return osl_Pipe_E_NotFound
;
469 case ERROR_NOT_ENOUGH_MEMORY
: return osl_Pipe_E_NoBufferSpace
;
470 default: return osl_Pipe_E_invalidError
;
474 /*****************************************************************************/
476 sal_Int32 SAL_CALL
osl_writePipe( oslPipe pPipe
, const void *pBuffer
, sal_Int32 n
)
478 /* loop until all desired bytes were send or an error occured */
479 sal_Int32 BytesSend
= 0;
480 sal_Int32 BytesToSend
= n
;
483 while (BytesToSend
> 0)
487 RetVal
= osl_sendPipe(pPipe
, pBuffer
, BytesToSend
);
495 BytesToSend
-= RetVal
;
497 pBuffer
= (sal_Char
*)pBuffer
+ RetVal
;
503 sal_Int32 SAL_CALL
osl_readPipe( oslPipe pPipe
, void *pBuffer
, sal_Int32 n
)
505 /* loop until all desired bytes were read or an error occured */
506 sal_Int32 BytesRead
= 0;
507 sal_Int32 BytesToRead
= n
;
510 while (BytesToRead
> 0)
513 RetVal
= osl_receivePipe(pPipe
, pBuffer
, BytesToRead
);
521 BytesToRead
-= RetVal
;
523 pBuffer
= (sal_Char
*)pBuffer
+ RetVal
;
529 /******************************************************************************
531 * New io resource transfer functions
533 *****************************************************************************/
536 /**********************************************
538 *********************************************/
540 sal_Bool
osl_sendResourcePipe(oslPipe pPipe
, oslSocket pSocket
)
542 sal_Bool bRet
= sal_False
;
547 /**********************************************
548 osl_receiveResourcePipe
549 *********************************************/
551 oslSocket
osl_receiveResourcePipe(oslPipe pPipe
)
555 return (oslSocket
) pSocket
;