Update ooo320-m1
[ooovba.git] / sal / osl / os2 / pipe.cxx
blob7b5be7d92f8c1f3928fcf0e4ac8f7743fc4c1d56
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pipe.cxx,v $
10 * $Revision: 1.5 $
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
32 #include "system.h"
34 #include <osl/pipe.h>
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"
47 typedef enum {
48 MSG_SYN,
49 MSG_FIN,
50 MSG_DATA,
51 MSG_UNKNOWN
52 } MessageType;
54 struct oslPipeImpl {
55 oslInterlockedCount m_Reference;
56 HPIPE hPipe;
57 HMTX m_NamedObject;
58 APIRET nLastError;
59 //oslSecurity m_Security;
60 sal_Bool m_bClosed;
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;
73 using rtl::OString;
74 using rtl::OUString;
75 using rtl::OUStringToOString;
77 /*****************************************************************************/
78 /* osl_create/destroy-PipeImpl */
79 /*****************************************************************************/
81 static oslInterlockedCount nPipes = 0;
83 oslPipe __osl_createPipeImpl(void)
85 oslPipe pPipe;
87 pPipe = (oslPipe) calloc(1,sizeof(struct oslPipeImpl));
89 pPipe->m_bClosed = sal_False;
90 pPipe->m_Reference = 1;
91 pPipe->hPipe = NULL;
92 pPipe->m_NamedObject = NULL;
94 return pPipe;
97 void __osl_destroyPipeImpl(oslPipe pPipe)
99 if (pPipe != NULL)
101 DosCloseMutexSem( pPipe->m_NamedObject);
102 free(pPipe);
107 /*****************************************************************************/
108 /* osl_createPipe */
109 /*****************************************************************************/
110 oslPipe SAL_CALL osl_createPipe(rtl_uString *ustrPipeName, oslPipeOptions Options,
111 oslSecurity Security)
113 oslPipe pPipe;
115 ULONG ulAction;
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();
126 if (!pPipe)
128 OSL_TRACE( "osl_createPipe failed allocating memory.\n" );
129 return NULL;
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);
136 #endif
138 switch( Options )
140 case osl_Pipe_OPEN:
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);
147 #endif
148 ngLastError = DosOpen( (PCSZ)strPipeNameBuffer,
149 &(pPipe->hPipe), &ulAction,
150 0, FILE_NORMAL, FILE_OPEN,
151 OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE,
152 (PEAOP2) NULL);
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 )
162 // We got it !
163 ngLastError = NO_ERROR;
164 break;
166 // Pipe instance maybe catched by another client -> try again
167 printf("osl_createPipe wait for Pipe available\n");
168 } while ( fPipeAvailable );
170 break;
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 );
176 if (ngLastError)
177 break;
179 sprintf (strPipeNameBuffer, "\\PIPE\\OSL_PIPE_%s", sPipe.getStr());
180 #if OSL_DEBUG_LEVEL>0
181 debug_printf("osl_createPipe %s\n", strPipeNameBuffer);
182 #endif
183 ngLastError = DosCreateNPipe( (PCSZ)strPipeNameBuffer,
184 &(pPipe->hPipe),
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 */
192 break;
193 default:
194 ngLastError = ERROR_INVALID_PARAMETER;
197 /* if failed, release allocated memory */
198 if (ngLastError)
200 OSL_TRACE( "osl_createPipe failed %s the pipe %s, Error Code %d.\n",
201 Options == osl_Pipe_OPEN ? "opening" : "creating",
202 strPipeNameBuffer,
203 ngLastError );
204 __osl_destroyPipeImpl(pPipe);
205 return NULL;
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 /*****************************************************************************/
216 /* osl_copyPipe */
217 /*****************************************************************************/
218 oslPipe SAL_CALL osl_copyPipe(oslPipe pPipe)
220 //oslPipe* pPipe = (oslPipe*) Pipe;
221 oslPipe pNewPipe;
224 /* check parameter */
225 OSL_ASSERT (pPipe);
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 */
236 if (ngLastError)
238 OSL_TRACE( "osl_copyPipe failed duplicating pipe handle, Error-Code: %d.\n",
239 ngLastError );
240 free (pNewPipe);
241 return NULL;
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 );
257 if( 0 == pPipe )
258 return;
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 */
276 OSL_ASSERT (pPipe);
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);
287 /* close the pipe */
288 DosClose (pPipe->hPipe);
293 /*****************************************************************************/
294 /* osl_acceptPipe */
295 /*****************************************************************************/
296 oslPipe SAL_CALL osl_acceptPipe(oslPipe pPipe)
299 #define PINFO ((PIPEINFO *) &PipeInfoBuffer)
301 ///oslPipe* pPipe = (oslPipe*) Pipe;
302 oslPipe pNewPipe;
303 BYTE PipeInfoBuffer[sizeof(PIPEINFO) + CCHMAXPATHCOMP];
305 /* check parameter */
306 OSL_ASSERT (pPipe);
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",
317 pPipe->nLastError );
318 return NULL;
321 /* create a new instance of the pipe if possible */
322 if (PINFO->cbMaxInst == -1 || /* unlimited instances */
323 PINFO->cbMaxInst > PINFO->cbCurInst)
325 HPIPE hPipe;
327 pNewPipe = __osl_createPipeImpl();
329 if (!pNewPipe)
331 OSL_TRACE( "osl_acceptPipe failed creating new instance.\n", ngLastError );
332 free(pNewPipe);
333 return NULL;
336 //pNewPipe->m_Security = pPipe->m_Security;
338 pNewPipe->nLastError =
339 DosCreateNPipe( (PCSZ)PINFO->szName,
340 &(pNewPipe->hPipe),
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 );
352 free(pNewPipe);
353 return NULL;
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);
371 return NULL;
373 return (oslPipe)pNewPipe;
375 else
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",
383 pPipe->nLastError );
384 return NULL;
387 return (oslPipe)pPipe;
391 /*****************************************************************************/
392 /* osl_receivePipe */
393 /*****************************************************************************/
394 sal_Int32 SAL_CALL osl_receivePipe(oslPipe pPipe,
395 void* pBuffer,
396 sal_Int32 BytesToRead)
398 //oslPipe* pPipe = (oslPipe*) Pipe;
399 ULONG ulActual;
401 /* check parameter */
402 OSL_ASSERT (pPipe);
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",
411 pPipe->nLastError );
412 return -1;
415 return ulActual;
419 /*****************************************************************************/
420 /* osl_sendPipe */
421 /*****************************************************************************/
422 sal_Int32 SAL_CALL osl_sendPipe(oslPipe pPipe,
423 const void* pBuffer,
424 sal_Int32 BytesToSend)
426 //oslPipe* pPipe = (oslPipe*) Pipe;
427 ULONG ulActual;
429 /* check parameter */
430 OSL_ASSERT (pPipe);
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",
439 pPipe->nLastError );
440 return -1;
443 return ulActual;
447 /*****************************************************************************/
448 /* osl_getLastPipeError */
449 /*****************************************************************************/
451 oslPipeError SAL_CALL osl_getLastPipeError(oslPipe pPipe)
453 //oslPipe* pPipe = (oslPipe*) Pipe;
454 APIRET rc;
456 /* return local error value if possible */
457 if (pPipe)
459 rc = pPipe->nLastError;
460 pPipe->nLastError = NO_ERROR;
461 } else
462 rc = ngLastError;
464 /* map OS/2 error values */
465 switch (rc)
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;
482 OSL_ASSERT(pPipe);
483 while (BytesToSend > 0)
485 sal_Int32 RetVal;
487 RetVal= osl_sendPipe(pPipe, pBuffer, BytesToSend);
489 /* error occured? */
490 if(RetVal <= 0)
492 break;
495 BytesToSend -= RetVal;
496 BytesSend += RetVal;
497 pBuffer= (sal_Char*)pBuffer + RetVal;
500 return BytesSend;
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;
509 OSL_ASSERT( pPipe );
510 while (BytesToRead > 0)
512 sal_Int32 RetVal;
513 RetVal= osl_receivePipe(pPipe, pBuffer, BytesToRead);
515 /* error occured? */
516 if(RetVal <= 0)
518 break;
521 BytesToRead -= RetVal;
522 BytesRead += RetVal;
523 pBuffer= (sal_Char*)pBuffer + RetVal;
525 return BytesRead;
529 /******************************************************************************
531 * New io resource transfer functions
533 *****************************************************************************/
536 /**********************************************
537 osl_sendResourcePipe
538 *********************************************/
540 sal_Bool osl_sendResourcePipe(oslPipe pPipe, oslSocket pSocket)
542 sal_Bool bRet = sal_False;
544 return bRet;
547 /**********************************************
548 osl_receiveResourcePipe
549 *********************************************/
551 oslSocket osl_receiveResourcePipe(oslPipe pPipe)
553 oslSocket pSocket=0;
555 return (oslSocket) pSocket;