merged tag ooo/DEV300_m102
[LibreOffice.git] / sal / osl / os2 / pipe.cxx
blob20db94bda9eb250d746d68c4ecb319c7c2490fe6
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
29 #include "system.h"
31 #include <osl/pipe.h>
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"
44 typedef enum {
45 MSG_SYN,
46 MSG_FIN,
47 MSG_DATA,
48 MSG_UNKNOWN
49 } MessageType;
51 struct oslPipeImpl {
52 oslInterlockedCount m_Reference;
53 HPIPE hPipe;
54 HMTX m_NamedObject;
55 APIRET nLastError;
56 //oslSecurity m_Security;
57 sal_Bool m_bClosed;
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;
70 using rtl::OString;
71 using rtl::OUString;
72 using rtl::OUStringToOString;
74 /*****************************************************************************/
75 /* osl_create/destroy-PipeImpl */
76 /*****************************************************************************/
78 static oslInterlockedCount nPipes = 0;
80 oslPipe __osl_createPipeImpl(void)
82 oslPipe pPipe;
84 pPipe = (oslPipe) calloc(1,sizeof(struct oslPipeImpl));
86 pPipe->m_bClosed = sal_False;
87 pPipe->m_Reference = 1;
88 pPipe->hPipe = NULL;
89 pPipe->m_NamedObject = NULL;
91 return pPipe;
94 void __osl_destroyPipeImpl(oslPipe pPipe)
96 if (pPipe != NULL)
98 DosCloseMutexSem( pPipe->m_NamedObject);
99 free(pPipe);
104 /*****************************************************************************/
105 /* osl_createPipe */
106 /*****************************************************************************/
107 oslPipe SAL_CALL osl_createPipe(rtl_uString *ustrPipeName, oslPipeOptions Options,
108 oslSecurity Security)
110 oslPipe pPipe;
112 ULONG ulAction;
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();
123 if (!pPipe)
125 OSL_TRACE( "osl_createPipe failed allocating memory.\n" );
126 return NULL;
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);
133 #endif
135 switch( Options )
137 case osl_Pipe_OPEN:
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);
144 #endif
145 ngLastError = DosOpen( (PCSZ)strPipeNameBuffer,
146 &(pPipe->hPipe), &ulAction,
147 0, FILE_NORMAL, FILE_OPEN,
148 OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE,
149 (PEAOP2) NULL);
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 )
159 // We got it !
160 ngLastError = NO_ERROR;
161 break;
163 // Pipe instance maybe catched by another client -> try again
164 printf("osl_createPipe wait for Pipe available\n");
165 } while ( fPipeAvailable );
167 break;
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 );
173 if (ngLastError)
174 break;
176 sprintf (strPipeNameBuffer, "\\PIPE\\OSL_PIPE_%s", sPipe.getStr());
177 #if OSL_DEBUG_LEVEL>0
178 debug_printf("osl_createPipe %s\n", strPipeNameBuffer);
179 #endif
180 ngLastError = DosCreateNPipe( (PCSZ)strPipeNameBuffer,
181 &(pPipe->hPipe),
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 */
189 break;
190 default:
191 ngLastError = ERROR_INVALID_PARAMETER;
194 /* if failed, release allocated memory */
195 if (ngLastError)
197 OSL_TRACE( "osl_createPipe failed %s the pipe %s, Error Code %d.\n",
198 Options == osl_Pipe_OPEN ? "opening" : "creating",
199 strPipeNameBuffer,
200 ngLastError );
201 __osl_destroyPipeImpl(pPipe);
202 return NULL;
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 /*****************************************************************************/
213 /* osl_copyPipe */
214 /*****************************************************************************/
215 oslPipe SAL_CALL osl_copyPipe(oslPipe pPipe)
217 //oslPipe* pPipe = (oslPipe*) Pipe;
218 oslPipe pNewPipe;
221 /* check parameter */
222 OSL_ASSERT (pPipe);
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 */
233 if (ngLastError)
235 OSL_TRACE( "osl_copyPipe failed duplicating pipe handle, Error-Code: %d.\n",
236 ngLastError );
237 free (pNewPipe);
238 return NULL;
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 );
254 if( 0 == pPipe )
255 return;
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 */
273 OSL_ASSERT (pPipe);
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);
284 /* close the pipe */
285 DosClose (pPipe->hPipe);
290 /*****************************************************************************/
291 /* osl_acceptPipe */
292 /*****************************************************************************/
293 oslPipe SAL_CALL osl_acceptPipe(oslPipe pPipe)
296 #define PINFO ((PIPEINFO *) &PipeInfoBuffer)
298 ///oslPipe* pPipe = (oslPipe*) Pipe;
299 oslPipe pNewPipe;
300 BYTE PipeInfoBuffer[sizeof(PIPEINFO) + CCHMAXPATHCOMP];
302 /* check parameter */
303 OSL_ASSERT (pPipe);
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",
314 pPipe->nLastError );
315 return NULL;
318 /* create a new instance of the pipe if possible */
319 if (PINFO->cbMaxInst == -1 || /* unlimited instances */
320 PINFO->cbMaxInst > PINFO->cbCurInst)
322 HPIPE hPipe;
324 pNewPipe = __osl_createPipeImpl();
326 if (!pNewPipe)
328 OSL_TRACE( "osl_acceptPipe failed creating new instance.\n", ngLastError );
329 free(pNewPipe);
330 return NULL;
333 //pNewPipe->m_Security = pPipe->m_Security;
335 pNewPipe->nLastError =
336 DosCreateNPipe( (PCSZ)PINFO->szName,
337 &(pNewPipe->hPipe),
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 );
349 free(pNewPipe);
350 return NULL;
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);
368 return NULL;
370 return (oslPipe)pNewPipe;
372 else
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",
380 pPipe->nLastError );
381 return NULL;
384 return (oslPipe)pPipe;
388 /*****************************************************************************/
389 /* osl_receivePipe */
390 /*****************************************************************************/
391 sal_Int32 SAL_CALL osl_receivePipe(oslPipe pPipe,
392 void* pBuffer,
393 sal_Int32 BytesToRead)
395 //oslPipe* pPipe = (oslPipe*) Pipe;
396 ULONG ulActual;
398 /* check parameter */
399 OSL_ASSERT (pPipe);
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",
408 pPipe->nLastError );
409 return -1;
412 return ulActual;
416 /*****************************************************************************/
417 /* osl_sendPipe */
418 /*****************************************************************************/
419 sal_Int32 SAL_CALL osl_sendPipe(oslPipe pPipe,
420 const void* pBuffer,
421 sal_Int32 BytesToSend)
423 //oslPipe* pPipe = (oslPipe*) Pipe;
424 ULONG ulActual;
426 /* check parameter */
427 OSL_ASSERT (pPipe);
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",
436 pPipe->nLastError );
437 return -1;
440 return ulActual;
444 /*****************************************************************************/
445 /* osl_getLastPipeError */
446 /*****************************************************************************/
448 oslPipeError SAL_CALL osl_getLastPipeError(oslPipe pPipe)
450 //oslPipe* pPipe = (oslPipe*) Pipe;
451 APIRET rc;
453 /* return local error value if possible */
454 if (pPipe)
456 rc = pPipe->nLastError;
457 pPipe->nLastError = NO_ERROR;
458 } else
459 rc = ngLastError;
461 /* map OS/2 error values */
462 switch (rc)
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;
479 OSL_ASSERT(pPipe);
480 while (BytesToSend > 0)
482 sal_Int32 RetVal;
484 RetVal= osl_sendPipe(pPipe, pBuffer, BytesToSend);
486 /* error occured? */
487 if(RetVal <= 0)
489 break;
492 BytesToSend -= RetVal;
493 BytesSend += RetVal;
494 pBuffer= (sal_Char*)pBuffer + RetVal;
497 return BytesSend;
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;
506 OSL_ASSERT( pPipe );
507 while (BytesToRead > 0)
509 sal_Int32 RetVal;
510 RetVal= osl_receivePipe(pPipe, pBuffer, BytesToRead);
512 /* error occured? */
513 if(RetVal <= 0)
515 break;
518 BytesToRead -= RetVal;
519 BytesRead += RetVal;
520 pBuffer= (sal_Char*)pBuffer + RetVal;
522 return BytesRead;
526 /******************************************************************************
528 * New io resource transfer functions
530 *****************************************************************************/
533 /**********************************************
534 osl_sendResourcePipe
535 *********************************************/
537 sal_Bool osl_sendResourcePipe(oslPipe pPipe, oslSocket pSocket)
539 sal_Bool bRet = sal_False;
541 return bRet;
544 /**********************************************
545 osl_receiveResourcePipe
546 *********************************************/
548 oslSocket osl_receiveResourcePipe(oslPipe pPipe)
550 oslSocket pSocket=0;
552 return (oslSocket) pSocket;