1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 //#define INCL_DOSERRORS
32 #include <osl/diagnose.h>
33 #include <osl/thread.h>
34 #include <osl/mutex.h>
35 #include <osl/semaphor.h>
36 #include <osl/conditn.h>
37 #include <osl/interlck.h>
38 #include <osl/process.h>
39 #include <rtl/ustring.hxx>
41 #define PIPENAMEMASK "OSL_PIPE_%s"
42 #define SECPIPENAMEMASK "OSL_PIPE_%s_%s"
52 oslInterlockedCount m_Reference
;
56 //oslSecurity m_Security;
60 /* default size for input/output buffer */
61 static const ULONG ulBufSize
= 4096;
63 /* OS/2 path for pipes */
64 static const CHAR pszPipePath
[] = "\\PIPE\\";
65 static const UCHAR nPipePathLen
= sizeof (pszPipePath
) - 1;
67 /* global last error value to be returned from oslGetLastPipeError */
68 static APIRET ngLastError
;
72 using rtl::OUStringToOString
;
74 /*****************************************************************************/
75 /* osl_create/destroy-PipeImpl */
76 /*****************************************************************************/
78 static oslInterlockedCount nPipes
= 0;
80 oslPipe
__osl_createPipeImpl(void)
84 pPipe
= (oslPipe
) calloc(1,sizeof(struct oslPipeImpl
));
86 pPipe
->m_bClosed
= sal_False
;
87 pPipe
->m_Reference
= 1;
89 pPipe
->m_NamedObject
= NULL
;
94 void __osl_destroyPipeImpl(oslPipe pPipe
)
98 DosCloseMutexSem( pPipe
->m_NamedObject
);
104 /*****************************************************************************/
106 /*****************************************************************************/
107 oslPipe SAL_CALL
osl_createPipe(rtl_uString
*ustrPipeName
, oslPipeOptions Options
,
108 oslSecurity Security
)
113 CHAR strPipeNameBuffer
[CCHMAXPATHCOMP
];
114 rtl_String
* strPipeName
=0;
115 sal_Char
* pszPipeName
=0;
117 /* check parameters */
118 OSL_ASSERT( ustrPipeName
);
119 //YD 17/04/06 OSL_ASSERT( Security == 0 );
121 /* allocate impl-structure */
122 pPipe
= __osl_createPipeImpl();
125 OSL_TRACE( "osl_createPipe failed allocating memory.\n" );
129 /* create pipe name */
130 OString sPipe
= OUStringToOString(ustrPipeName
, RTL_TEXTENCODING_ASCII_US
);
131 #if OSL_DEBUG_LEVEL>0
132 debug_printf("osl_createPipe options 0x%x\n", Options
);
139 APIRET fPipeAvailable
;
141 sprintf (strPipeNameBuffer
, "\\PIPE\\OSL_PIPE_%s", sPipe
.getStr());
142 #if OSL_DEBUG_LEVEL>0
143 debug_printf("osl_createPipe %s\n", strPipeNameBuffer
);
145 ngLastError
= DosOpen( (PCSZ
)strPipeNameBuffer
,
146 &(pPipe
->hPipe
), &ulAction
,
147 0, FILE_NORMAL
, FILE_OPEN
,
148 OPEN_ACCESS_READWRITE
| OPEN_SHARE_DENYREADWRITE
,
150 // if pipe is busy, wait for it
151 if (ngLastError
== ERROR_PIPE_BUSY
)
154 /* free instance should be available first */
155 fPipeAvailable
= DosWaitNPipe( (PCSZ
)strPipeNameBuffer
, -1);
156 /* first try to open system pipe */
157 if ( fPipeAvailable
== NO_ERROR
)
160 ngLastError
= NO_ERROR
;
163 // Pipe instance maybe catched by another client -> try again
164 printf("osl_createPipe wait for Pipe available\n");
165 } while ( fPipeAvailable
);
168 case osl_Pipe_CREATE
:
170 sprintf (strPipeNameBuffer
, "\\SEM32\\OSL_SEM_%s", sPipe
.getStr());
171 // check if semaphore exists (pipe create must fail for existig pipes)
172 ngLastError
= DosCreateMutexSem( (PCSZ
)strPipeNameBuffer
, &(pPipe
->m_NamedObject
), 0, TRUE
);
176 sprintf (strPipeNameBuffer
, "\\PIPE\\OSL_PIPE_%s", sPipe
.getStr());
177 #if OSL_DEBUG_LEVEL>0
178 debug_printf("osl_createPipe %s\n", strPipeNameBuffer
);
180 ngLastError
= DosCreateNPipe( (PCSZ
)strPipeNameBuffer
,
182 NP_ACCESS_DUPLEX
, /* open pipe for read and write access */
183 0xFF, /* allow unlimited number of instances */
184 ulBufSize
, /* output buffer size */
185 ulBufSize
, /* input buffer size */
186 0L /* use default time-out time */
191 ngLastError
= ERROR_INVALID_PARAMETER
;
194 /* if failed, release allocated memory */
197 OSL_TRACE( "osl_createPipe failed %s the pipe %s, Error Code %d.\n",
198 Options
== osl_Pipe_OPEN
? "opening" : "creating",
201 __osl_destroyPipeImpl(pPipe
);
205 pPipe
->m_Reference
= 1;
206 pPipe
->m_bClosed
= sal_False
;
207 //pPipe->m_Security = Security;
208 pPipe
->nLastError
= NO_ERROR
;
209 return (oslPipe
)pPipe
;
212 /*****************************************************************************/
214 /*****************************************************************************/
215 oslPipe SAL_CALL
osl_copyPipe(oslPipe pPipe
)
217 //oslPipe* pPipe = (oslPipe*) Pipe;
221 /* check parameter */
224 /* allocate impl-structure */
225 pNewPipe
= __osl_createPipeImpl();
226 if (!pNewPipe
) return NULL
;
228 /* create new handle */
229 pNewPipe
->hPipe
= (HPIPE
) -1;
230 ngLastError
= DosDupHandle( pPipe
->hPipe
, &(pNewPipe
->hPipe
) );
232 /* if failed, release allocated memory */
235 OSL_TRACE( "osl_copyPipe failed duplicating pipe handle, Error-Code: %d.\n",
241 pNewPipe
->nLastError
= NO_ERROR
;
242 return (oslPipe
)pNewPipe
;
245 void SAL_CALL
osl_acquirePipe( oslPipe pPipe
)
247 osl_incrementInterlockedCount( &(pPipe
->m_Reference
) );
250 void SAL_CALL
osl_releasePipe( oslPipe pPipe
)
252 // OSL_ASSERT( pPipe );
257 if( 0 == osl_decrementInterlockedCount( &(pPipe
->m_Reference
) ) )
259 if( ! pPipe
->m_bClosed
)
260 osl_closePipe( pPipe
);
262 __osl_destroyPipeImpl( pPipe
);
266 /*****************************************************************************/
267 /* osl_destroyPipe */
268 /*************close****************************************************************/
269 void SAL_CALL
osl_closePipe(oslPipe pPipe
)
271 //oslPipe* pPipe = (oslPipe*) Pipe;
272 /* check parameter */
275 if( pPipe
&& ! pPipe
->m_bClosed
)
277 pPipe
->m_bClosed
= sal_True
;
278 /* if we have a system pipe close it */
279 if (pPipe
->hPipe
!= 0)
281 /* disconnect client */
282 DosDisConnectNPipe (pPipe
->hPipe
);
285 DosClose (pPipe
->hPipe
);
290 /*****************************************************************************/
292 /*****************************************************************************/
293 oslPipe SAL_CALL
osl_acceptPipe(oslPipe pPipe
)
296 #define PINFO ((PIPEINFO *) &PipeInfoBuffer)
298 ///oslPipe* pPipe = (oslPipe*) Pipe;
300 BYTE PipeInfoBuffer
[sizeof(PIPEINFO
) + CCHMAXPATHCOMP
];
302 /* check parameter */
305 /* get pipe information */
306 pPipe
->nLastError
= DosQueryNPipeInfo(pPipe
->hPipe
,
308 (PVOID
) &PipeInfoBuffer
,
309 sizeof(PipeInfoBuffer
));
311 if (pPipe
->nLastError
)
313 OSL_TRACE( "osl_acceptPipe failed for requesting pipe information.\n",
318 /* create a new instance of the pipe if possible */
319 if (PINFO
->cbMaxInst
== -1 || /* unlimited instances */
320 PINFO
->cbMaxInst
> PINFO
->cbCurInst
)
324 pNewPipe
= __osl_createPipeImpl();
328 OSL_TRACE( "osl_acceptPipe failed creating new instance.\n", ngLastError
);
333 //pNewPipe->m_Security = pPipe->m_Security;
335 pNewPipe
->nLastError
=
336 DosCreateNPipe( (PCSZ
)PINFO
->szName
,
338 NP_ACCESS_DUPLEX
, /* open pipe for read and write access */
339 0xFF, /* allow unlimited number of instances */
340 ulBufSize
, /* output buffer size */
341 ulBufSize
, /* input buffer size */
342 0L /* use default time-out time */
345 if (pNewPipe
->nLastError
)
347 OSL_TRACE( "osl_acceptPipe failed creating new named pipe, Error-Code: %d.\n",
348 pNewPipe
->nLastError
);
353 /* switch pipe handles */
354 hPipe
= pPipe
->hPipe
;
355 pPipe
->hPipe
= pNewPipe
->hPipe
;
356 pNewPipe
->hPipe
= hPipe
;
358 /* connect new handle to client */
359 pNewPipe
->nLastError
= DosConnectNPipe( pNewPipe
->hPipe
);
361 /* if failed, release allocated memory */
362 if (pNewPipe
->nLastError
)
364 OSL_TRACE( "osl_acceptPipe failed connecting pipe to client, Error-Code: %d.\n",
365 pNewPipe
->nLastError
);
367 osl_closePipe((oslPipe
)pNewPipe
);
370 return (oslPipe
)pNewPipe
;
374 /* connect original handle to client */
375 pPipe
->nLastError
= DosConnectNPipe( pPipe
->hPipe
);
377 if (pPipe
->nLastError
)
379 OSL_TRACE( "osl_acceptPipe failed connecting pipe to client, Error-Code: %d.\n",
384 return (oslPipe
)pPipe
;
388 /*****************************************************************************/
389 /* osl_receivePipe */
390 /*****************************************************************************/
391 sal_Int32 SAL_CALL
osl_receivePipe(oslPipe pPipe
,
393 sal_Int32 BytesToRead
)
395 //oslPipe* pPipe = (oslPipe*) Pipe;
398 /* check parameter */
401 /* read data from pipe */
402 pPipe
->nLastError
= DosRead( pPipe
->hPipe
, pBuffer
, BytesToRead
, &ulActual
);
404 /* return -1 if failed */
405 if( pPipe
->nLastError
)
407 OSL_TRACE( "osl_receivePipe failed receiving from Pipe, Error-Code: %d.\n",
416 /*****************************************************************************/
418 /*****************************************************************************/
419 sal_Int32 SAL_CALL
osl_sendPipe(oslPipe pPipe
,
421 sal_Int32 BytesToSend
)
423 //oslPipe* pPipe = (oslPipe*) Pipe;
426 /* check parameter */
429 /* read data from pipe */
430 pPipe
->nLastError
= DosWrite( pPipe
->hPipe
, (PVOID
) pBuffer
, BytesToSend
, &ulActual
);
432 /* return -1 if failed */
433 if( pPipe
->nLastError
)
435 OSL_TRACE( "osl_receivePipe failed writing to Pipe, Error-Code: %d.\n",
444 /*****************************************************************************/
445 /* osl_getLastPipeError */
446 /*****************************************************************************/
448 oslPipeError SAL_CALL
osl_getLastPipeError(oslPipe pPipe
)
450 //oslPipe* pPipe = (oslPipe*) Pipe;
453 /* return local error value if possible */
456 rc
= pPipe
->nLastError
;
457 pPipe
->nLastError
= NO_ERROR
;
461 /* map OS/2 error values */
464 case NO_ERROR
: return osl_Pipe_E_None
;
465 case ERROR_PATH_NOT_FOUND
: return osl_Pipe_E_NotFound
;
466 case ERROR_NOT_ENOUGH_MEMORY
: return osl_Pipe_E_NoBufferSpace
;
467 default: return osl_Pipe_E_invalidError
;
471 /*****************************************************************************/
473 sal_Int32 SAL_CALL
osl_writePipe( oslPipe pPipe
, const void *pBuffer
, sal_Int32 n
)
475 /* loop until all desired bytes were send or an error occured */
476 sal_Int32 BytesSend
= 0;
477 sal_Int32 BytesToSend
= n
;
480 while (BytesToSend
> 0)
484 RetVal
= osl_sendPipe(pPipe
, pBuffer
, BytesToSend
);
492 BytesToSend
-= RetVal
;
494 pBuffer
= (sal_Char
*)pBuffer
+ RetVal
;
500 sal_Int32 SAL_CALL
osl_readPipe( oslPipe pPipe
, void *pBuffer
, sal_Int32 n
)
502 /* loop until all desired bytes were read or an error occured */
503 sal_Int32 BytesRead
= 0;
504 sal_Int32 BytesToRead
= n
;
507 while (BytesToRead
> 0)
510 RetVal
= osl_receivePipe(pPipe
, pBuffer
, BytesToRead
);
518 BytesToRead
-= RetVal
;
520 pBuffer
= (sal_Char
*)pBuffer
+ RetVal
;
526 /******************************************************************************
528 * New io resource transfer functions
530 *****************************************************************************/
533 /**********************************************
535 *********************************************/
537 sal_Bool
osl_sendResourcePipe(oslPipe pPipe
, oslSocket pSocket
)
539 sal_Bool bRet
= sal_False
;
544 /**********************************************
545 osl_receiveResourcePipe
546 *********************************************/
548 oslSocket
osl_receiveResourcePipe(oslPipe pPipe
)
552 return (oslSocket
) pSocket
;