Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "system.h"
30 : :
31 : : #include <osl/pipe.h>
32 : : #include <osl/diagnose.h>
33 : : #include <osl/thread.h>
34 : : #include <osl/interlck.h>
35 : : #include <rtl/string.h>
36 : : #include <rtl/ustring.h>
37 : : #include <rtl/bootstrap.h>
38 : :
39 : : #include "sockimpl.h"
40 : :
41 : : #define PIPEDEFAULTPATH "/tmp"
42 : : #define PIPEALTERNATEPATH "/var/tmp"
43 : :
44 : : #define PIPENAMEMASK "OSL_PIPE_%s"
45 : : #define SECPIPENAMEMASK "OSL_PIPE_%s_%s"
46 : :
47 : : sal_Bool SAL_CALL osl_psz_getUserIdent(oslSecurity Security, sal_Char *pszIdent, sal_uInt32 nMax);
48 : : oslPipe SAL_CALL osl_psz_createPipe(const sal_Char *pszPipeName, oslPipeOptions Options, oslSecurity Security);
49 : :
50 : :
51 : : /*****************************************************************************/
52 : : /* enum oslPipeError */
53 : : /*****************************************************************************/
54 : :
55 : : static struct
56 : : {
57 : : int errcode;
58 : : oslPipeError error;
59 : : } PipeError[]= {
60 : : { 0, osl_Pipe_E_None }, /* no error */
61 : : { EPROTOTYPE, osl_Pipe_E_NoProtocol }, /* Protocol wrong type for socket */
62 : : { ENOPROTOOPT, osl_Pipe_E_NoProtocol }, /* Protocol not available */
63 : : { EPROTONOSUPPORT, osl_Pipe_E_NoProtocol }, /* Protocol not supported */
64 : : { ESOCKTNOSUPPORT, osl_Pipe_E_NoProtocol }, /* Socket type not supported */
65 : : { EPFNOSUPPORT, osl_Pipe_E_NoProtocol }, /* Protocol family not supported */
66 : : { EAFNOSUPPORT, osl_Pipe_E_NoProtocol }, /* Address family not supported by */
67 : : /* protocol family */
68 : : { ENETRESET, osl_Pipe_E_NetworkReset }, /* Network dropped connection because */
69 : : /* of reset */
70 : : { ECONNABORTED, osl_Pipe_E_ConnectionAbort }, /* Software caused connection abort */
71 : : { ECONNRESET, osl_Pipe_E_ConnectionReset }, /* Connection reset by peer */
72 : : { ENOBUFS, osl_Pipe_E_NoBufferSpace }, /* No buffer space available */
73 : : { ETIMEDOUT, osl_Pipe_E_TimedOut }, /* Connection timed out */
74 : : { ECONNREFUSED, osl_Pipe_E_ConnectionRefused }, /* Connection refused */
75 : : { -1, osl_Pipe_E_invalidError }
76 : : };
77 : :
78 : :
79 : : /* map */
80 : : /* mfe: NOT USED
81 : : static int osl_NativeFromPipeError(oslPipeError errorCode)
82 : : {
83 : : int i = 0;
84 : :
85 : : while ((PipeError[i].error != osl_Pipe_E_invalidError) &&
86 : : (PipeError[i].error != errorCode)) i++;
87 : :
88 : : return PipeError[i].errcode;
89 : :
90 : : }
91 : : */
92 : :
93 : : /* reverse map */
94 : 118 : static oslPipeError osl_PipeErrorFromNative(int nativeType)
95 : : {
96 : 118 : int i = 0;
97 : :
98 [ + + ][ + - ]: 1652 : while ((PipeError[i].error != osl_Pipe_E_invalidError) &&
99 : 1534 : (PipeError[i].errcode != nativeType)) i++;
100 : :
101 : 118 : return PipeError[i].error;
102 : : }
103 : :
104 : :
105 : : /* macros */
106 : : #define ERROR_TO_NATIVE(x) osl_NativeFromPipeError(x)
107 : : #define ERROR_FROM_NATIVE(y) osl_PipeErrorFromNative(y)
108 : :
109 : :
110 : : /*****************************************************************************/
111 : : /* osl_create/destroy-PipeImpl */
112 : : /*****************************************************************************/
113 : :
114 : 1452 : oslPipe __osl_createPipeImpl()
115 : : {
116 : : oslPipe pPipeImpl;
117 : :
118 : 1452 : pPipeImpl = (oslPipe)calloc(1, sizeof(struct oslPipeImpl));
119 : 1452 : pPipeImpl->m_nRefCount =1;
120 : 1452 : pPipeImpl->m_bClosed = sal_False;
121 : : #if defined(LINUX)
122 : 1452 : pPipeImpl->m_bIsInShutdown = sal_False;
123 : 1452 : pPipeImpl->m_bIsAccepting = sal_False;
124 : : #endif
125 : 1452 : return pPipeImpl;
126 : : }
127 : :
128 : 1446 : void __osl_destroyPipeImpl(oslPipe pImpl)
129 : : {
130 [ + - ]: 1446 : if (pImpl != NULL)
131 : 1446 : free(pImpl);
132 : 1446 : }
133 : :
134 : :
135 : : /*****************************************************************************/
136 : : /* osl_createPipe */
137 : : /*****************************************************************************/
138 : 1196 : oslPipe SAL_CALL osl_createPipe(rtl_uString *ustrPipeName, oslPipeOptions Options, oslSecurity Security)
139 : : {
140 : 1196 : oslPipe pPipe=0;
141 : 1196 : rtl_String* strPipeName=0;
142 : 1196 : sal_Char* pszPipeName=0;
143 : :
144 [ + - ]: 1196 : if ( ustrPipeName != 0 )
145 : : {
146 : 2392 : rtl_uString2String( &strPipeName,
147 : 1196 : rtl_uString_getStr(ustrPipeName),
148 : : rtl_uString_getLength(ustrPipeName),
149 : 1196 : osl_getThreadTextEncoding(),
150 : : OUSTRING_TO_OSTRING_CVTFLAGS );
151 : 1196 : pszPipeName = rtl_string_getStr(strPipeName);
152 : 1196 : pPipe = osl_psz_createPipe(pszPipeName, Options, Security);
153 : :
154 [ + - ]: 1196 : if ( strPipeName != 0 )
155 : : {
156 : 1196 : rtl_string_release(strPipeName);
157 : : }
158 : : }
159 : :
160 : 1196 : return pPipe;
161 : :
162 : : }
163 : :
164 : : static sal_Bool
165 : 0 : cpyBootstrapSocketPath(sal_Char *name, size_t len)
166 : : {
167 : 0 : sal_Bool bRet = sal_False;
168 : 0 : rtl_uString *pName = 0, *pValue = 0;
169 : :
170 : 0 : rtl_uString_newFromAscii(&pName, "OSL_SOCKET_PATH");
171 : :
172 [ # # ]: 0 : if (rtl_bootstrap_get(pName, &pValue, NULL))
173 : : {
174 : 0 : rtl_String *pStrValue = 0;
175 [ # # ][ # # ]: 0 : if (pValue && pValue->length > 0)
176 : : {
177 : 0 : rtl_uString2String(&pStrValue, pValue->buffer,
178 : 0 : pValue->length, RTL_TEXTENCODING_UTF8,
179 : : OUSTRING_TO_OSTRING_CVTFLAGS);
180 [ # # ][ # # ]: 0 : if (pStrValue && pStrValue->length > 0)
181 : : {
182 : 0 : size_t nCopy = SAL_MIN (len-1, (size_t)pStrValue->length);
183 : 0 : strncpy (name, pStrValue->buffer, nCopy);
184 : 0 : name[nCopy] = '\0';
185 : 0 : bRet = (size_t)pStrValue->length < len;
186 : : }
187 : 0 : rtl_string_release(pStrValue);
188 : : }
189 : 0 : rtl_uString_release(pName);
190 : : }
191 : 0 : return bRet;
192 : : }
193 : :
194 : 1196 : oslPipe SAL_CALL osl_psz_createPipe(const sal_Char *pszPipeName, oslPipeOptions Options,
195 : : oslSecurity Security)
196 : : {
197 : : int Flags;
198 : : size_t len;
199 : : struct sockaddr_un addr;
200 : :
201 : : sal_Char name[PATH_MAX + 1];
202 : 1196 : size_t nNameLength = 0;
203 : 1196 : int bNameTooLong = 0;
204 : : oslPipe pPipe;
205 : :
206 [ + - ]: 1196 : if (access(PIPEDEFAULTPATH, R_OK|W_OK) == 0)
207 : : {
208 : 1196 : strncpy(name, PIPEDEFAULTPATH, sizeof(name));
209 : : }
210 [ # # ]: 0 : else if (access(PIPEALTERNATEPATH, R_OK|W_OK) == 0)
211 : : {
212 : 0 : strncpy(name, PIPEALTERNATEPATH, sizeof(name));
213 : : }
214 [ # # ]: 0 : else if (!cpyBootstrapSocketPath (name, sizeof (name)))
215 : : {
216 : 0 : return NULL;
217 : : }
218 : 1196 : name[sizeof(name) - 1] = '\0'; // ensure the string is NULL-terminated
219 : 1196 : nNameLength = strlen(name);
220 : 1196 : bNameTooLong = nNameLength > sizeof(name) - 2;
221 : :
222 [ + - ]: 1196 : if (!bNameTooLong)
223 : : {
224 : 1196 : size_t nRealLength = 0;
225 : :
226 : 1196 : strcat(name, "/");
227 : 1196 : ++nNameLength;
228 : :
229 [ + - ]: 1196 : if (Security)
230 : : {
231 : : sal_Char Ident[256];
232 : :
233 : 1196 : Ident[0] = '\0';
234 : :
235 : 1196 : OSL_VERIFY(osl_psz_getUserIdent(Security, Ident, sizeof(Ident)));
236 : :
237 : 1196 : nRealLength = snprintf(&name[nNameLength], sizeof(name) - nNameLength, SECPIPENAMEMASK, Ident, pszPipeName);
238 : : }
239 : : else
240 : : {
241 : 0 : nRealLength = snprintf(&name[nNameLength], sizeof(name) - nNameLength, PIPENAMEMASK, pszPipeName);
242 : : }
243 : :
244 : 1196 : bNameTooLong = nRealLength > sizeof(name) - nNameLength - 1;
245 : : }
246 : :
247 [ - + ]: 1196 : if (bNameTooLong)
248 : : {
249 : : OSL_TRACE("osl_createPipe: pipe name too long");
250 : 0 : return NULL;
251 : : }
252 : :
253 : : /* alloc memory */
254 : 1196 : pPipe= __osl_createPipeImpl();
255 : :
256 : : /* create socket */
257 : 1196 : pPipe->m_Socket = socket(AF_UNIX, SOCK_STREAM, 0);
258 [ - + ]: 1196 : if ( pPipe->m_Socket < 0 )
259 : : {
260 : : OSL_TRACE("osl_createPipe socket failed. Errno: %d; %s",errno, strerror(errno));
261 : 0 : __osl_destroyPipeImpl(pPipe);
262 : 0 : return NULL;
263 : : }
264 : :
265 : : /* OSL_TRACE("osl_createPipe : new Pipe on fd %i\n",pPipe->m_Socket);*/
266 : :
267 : : /* set close-on-exec flag */
268 [ + - ]: 1196 : if ((Flags = fcntl(pPipe->m_Socket, F_GETFD, 0)) != -1)
269 : : {
270 : 1196 : Flags |= FD_CLOEXEC;
271 : 1196 : if (fcntl(pPipe->m_Socket, F_SETFD, Flags) == -1)
272 : : {
273 : : OSL_TRACE("osl_createPipe failed changing socket flags. Errno: %d; %s",errno,strerror(errno));
274 : : }
275 : : }
276 : :
277 : 1196 : memset(&addr, 0, sizeof(addr));
278 : :
279 : : OSL_TRACE("osl_createPipe : Pipe Name '%s'",name);
280 : :
281 : 1196 : addr.sun_family = AF_UNIX;
282 : 1196 : strncpy(addr.sun_path, name, sizeof(addr.sun_path) - 1);
283 : : #if defined(FREEBSD)
284 : : len = SUN_LEN(&addr);
285 : : #else
286 : 1196 : len = sizeof(addr);
287 : : #endif
288 : :
289 [ + + ]: 1196 : if ( Options & osl_Pipe_CREATE )
290 : : {
291 : : struct stat status;
292 : :
293 : : /* check if there exists an orphan filesystem entry */
294 [ - + ][ # # ]: 256 : if ( ( stat(name, &status) == 0) &&
295 [ # # ]: 0 : ( S_ISSOCK(status.st_mode) || S_ISFIFO(status.st_mode) ) )
296 : : {
297 [ # # ]: 0 : if ( connect(pPipe->m_Socket,(struct sockaddr *)&addr,len) >= 0 )
298 : : {
299 : : OSL_TRACE("osl_createPipe : Pipe already in use. Errno: %d; %s",errno,strerror(errno));
300 : 0 : close (pPipe->m_Socket);
301 : 0 : __osl_destroyPipeImpl(pPipe);
302 : 0 : return NULL;
303 : : }
304 : :
305 : 0 : unlink(name);
306 : : }
307 : :
308 : : /* ok, fs clean */
309 [ - + ]: 256 : if ( bind(pPipe->m_Socket, (struct sockaddr *)&addr, len) < 0 )
310 : : {
311 : : OSL_TRACE("osl_createPipe : failed to bind socket. Errno: %d; %s",errno,strerror(errno));
312 : 0 : close (pPipe->m_Socket);
313 : 0 : __osl_destroyPipeImpl(pPipe);
314 : 0 : return NULL;
315 : : }
316 : :
317 : : /* Only give access to all if no security handle was specified, otherwise security
318 : : depends on umask */
319 : :
320 [ - + ]: 256 : if ( !Security )
321 : 0 : chmod(name,S_IRWXU | S_IRWXG |S_IRWXO);
322 : :
323 : :
324 : 256 : strncpy(pPipe->m_Name, name, sizeof(pPipe->m_Name) - 1);
325 : :
326 [ - + ]: 256 : if ( listen(pPipe->m_Socket, 5) < 0 )
327 : : {
328 : : OSL_TRACE("osl_createPipe failed to listen. Errno: %d; %s",errno,strerror(errno));
329 : 0 : unlink(name); /* remove filesystem entry */
330 : 0 : close (pPipe->m_Socket);
331 : 0 : __osl_destroyPipeImpl(pPipe);
332 : 0 : return NULL;
333 : : }
334 : :
335 : 256 : return (pPipe);
336 : : }
337 : : else
338 : : { /* osl_pipe_OPEN */
339 [ + + ]: 940 : if ( access(name, F_OK) != -1 )
340 : : {
341 [ + - ]: 256 : if ( connect( pPipe->m_Socket, (struct sockaddr *)&addr, len) >= 0 )
342 : : {
343 : 256 : return (pPipe);
344 : : }
345 : :
346 : : OSL_TRACE("osl_createPipe failed to connect. Errno: %d; %s",errno,strerror(errno));
347 : : }
348 : :
349 : 684 : close (pPipe->m_Socket);
350 : 684 : __osl_destroyPipeImpl(pPipe);
351 : 1196 : return NULL;
352 : : }
353 : : }
354 : :
355 : 3502254 : void SAL_CALL osl_acquirePipe( oslPipe pPipe )
356 : : {
357 : 3502254 : osl_incrementInterlockedCount( &(pPipe->m_nRefCount) );
358 : 3502254 : }
359 : :
360 : 3503016 : void SAL_CALL osl_releasePipe( oslPipe pPipe )
361 : : {
362 : :
363 [ - + ]: 3503016 : if( 0 == pPipe )
364 : 3503016 : return;
365 : :
366 [ + + ]: 3503016 : if( 0 == osl_decrementInterlockedCount( &(pPipe->m_nRefCount) ) )
367 : : {
368 [ + + ]: 762 : if( ! pPipe->m_bClosed )
369 : 2 : osl_closePipe( pPipe );
370 : :
371 : 762 : __osl_destroyPipeImpl( pPipe );
372 : : }
373 : : }
374 : :
375 : 766 : void SAL_CALL osl_closePipe( oslPipe pPipe )
376 : : {
377 : : int nRet;
378 : : #if defined(LINUX)
379 : : size_t len;
380 : : struct sockaddr_un addr;
381 : : int fd;
382 : : #endif
383 : : int ConnFD;
384 : :
385 [ + - ]: 766 : if( ! pPipe )
386 : : {
387 : : return;
388 : : }
389 : :
390 [ + - ]: 766 : if( pPipe->m_bClosed )
391 : : {
392 : : return;
393 : : }
394 : :
395 : 766 : ConnFD = pPipe->m_Socket;
396 : :
397 : : /*
398 : : Thread does not return from accept on linux, so
399 : : connect to the accepting pipe
400 : : */
401 : : #if defined(LINUX)
402 [ + + ]: 766 : if ( pPipe->m_bIsAccepting )
403 : : {
404 : 96 : pPipe->m_bIsInShutdown = sal_True;
405 : 96 : pPipe->m_Socket = -1;
406 : 96 : fd = socket(AF_UNIX, SOCK_STREAM, 0);
407 : 96 : memset(&addr, 0, sizeof(addr));
408 : :
409 : : OSL_TRACE("osl_destroyPipe : Pipe Name '%s'",pPipe->m_Name);
410 : :
411 : 96 : addr.sun_family = AF_UNIX;
412 : 96 : strncpy(addr.sun_path, pPipe->m_Name, sizeof(addr.sun_path) - 1);
413 : 96 : len = sizeof(addr);
414 : :
415 : 96 : nRet = connect( fd, (struct sockaddr *)&addr, len);
416 : : if ( nRet < 0 )
417 : : {
418 : : OSL_TRACE("connect in osl_destroyPipe failed with error: %s", strerror(errno));
419 : : }
420 : 96 : close(fd);
421 : : }
422 : : #endif /* LINUX */
423 : :
424 : :
425 : 766 : nRet = shutdown(ConnFD, 2);
426 : : if ( nRet < 0 )
427 : : {
428 : : OSL_TRACE("shutdown in destroyPipe failed : '%s'",strerror(errno));
429 : : }
430 : :
431 : 766 : nRet = close(ConnFD);
432 : : if ( nRet < 0 )
433 : : {
434 : : OSL_TRACE("close in destroyPipe failed : '%s'",strerror(errno));
435 : : }
436 : : /* remove filesystem entry */
437 [ + + ]: 766 : if ( strlen(pPipe->m_Name) > 0 )
438 : : {
439 : 256 : unlink(pPipe->m_Name);
440 : : }
441 : 766 : pPipe->m_bClosed = sal_True;
442 : :
443 : : /* OSL_TRACE("Out osl_destroyPipe"); */
444 : : }
445 : :
446 : :
447 : : /*****************************************************************************/
448 : : /* osl_acceptPipe */
449 : : /*****************************************************************************/
450 : 352 : oslPipe SAL_CALL osl_acceptPipe(oslPipe pPipe)
451 : : {
452 : : int s, flags;
453 : : oslPipe pAcceptedPipe;
454 : :
455 : : OSL_ASSERT(pPipe);
456 [ - + ]: 352 : if ( pPipe == 0 )
457 : : {
458 : 0 : return NULL;
459 : : }
460 : :
461 : : OSL_ASSERT(strlen(pPipe->m_Name) > 0);
462 : :
463 : : #if defined(LINUX)
464 : 352 : pPipe->m_bIsAccepting = sal_True;
465 : : #endif
466 : :
467 : 352 : s = accept(pPipe->m_Socket, NULL, NULL);
468 : :
469 : : #if defined(LINUX)
470 : 352 : pPipe->m_bIsAccepting = sal_False;
471 : : #endif
472 : :
473 [ - + ]: 352 : if (s < 0)
474 : : {
475 : : OSL_TRACE("osl_acceptPipe : accept error '%s'", strerror(errno));
476 : 0 : return NULL;
477 : : }
478 : :
479 : : #if defined(LINUX)
480 [ + + ]: 352 : if ( pPipe->m_bIsInShutdown )
481 : : {
482 : 96 : close(s);
483 : 96 : return NULL;
484 : : }
485 : : #endif /* LINUX */
486 : : else
487 : : {
488 : : /* alloc memory */
489 : 256 : pAcceptedPipe= __osl_createPipeImpl();
490 : :
491 : : OSL_ASSERT(pAcceptedPipe);
492 [ - + ]: 256 : if(pAcceptedPipe==NULL)
493 : : {
494 : 0 : close(s);
495 : 0 : return NULL;
496 : : }
497 : :
498 : : /* set close-on-exec flag */
499 [ + - ]: 256 : if (!((flags = fcntl(s, F_GETFD, 0)) < 0))
500 : : {
501 : 256 : flags |= FD_CLOEXEC;
502 : 256 : if (fcntl(s, F_SETFD, flags) < 0)
503 : : {
504 : : OSL_TRACE("osl_acceptPipe: error changing socket flags. "
505 : : "Errno: %d; %s",errno,strerror(errno));
506 : : }
507 : : }
508 : :
509 : 256 : pAcceptedPipe->m_Socket = s;
510 : : }
511 : :
512 : 352 : return pAcceptedPipe;
513 : : }
514 : :
515 : : /*****************************************************************************/
516 : : /* osl_receivePipe */
517 : : /*****************************************************************************/
518 : 4791274 : sal_Int32 SAL_CALL osl_receivePipe(oslPipe pPipe,
519 : : void* pBuffer,
520 : : sal_Int32 BytesToRead)
521 : : {
522 : 4791274 : int nRet = 0;
523 : :
524 : : OSL_ASSERT(pPipe);
525 : :
526 [ - + ]: 4791274 : if ( pPipe == 0 )
527 : : {
528 : : OSL_TRACE("osl_receivePipe : Invalid socket");
529 : 0 : errno=EINVAL;
530 : 0 : return -1;
531 : : }
532 : :
533 : 4791274 : nRet = recv(pPipe->m_Socket,
534 : : (sal_Char*)pBuffer,
535 : : BytesToRead, 0);
536 : :
537 : : if ( nRet < 0 )
538 : : {
539 : : OSL_TRACE("osl_receivePipe failed : %i '%s'",nRet,strerror(errno));
540 : : }
541 : :
542 : 4791272 : return nRet;
543 : : }
544 : :
545 : :
546 : : /*****************************************************************************/
547 : : /* osl_sendPipe */
548 : : /*****************************************************************************/
549 : 4676451 : sal_Int32 SAL_CALL osl_sendPipe(oslPipe pPipe,
550 : : const void* pBuffer,
551 : : sal_Int32 BytesToSend)
552 : : {
553 : 4676451 : int nRet=0;
554 : :
555 : : OSL_ASSERT(pPipe);
556 : :
557 [ - + ]: 4676451 : if ( pPipe == 0 )
558 : : {
559 : : OSL_TRACE("osl_sendPipe : Invalid socket");
560 : 0 : errno=EINVAL;
561 : 0 : return -1;
562 : : }
563 : :
564 : 4676451 : nRet = send(pPipe->m_Socket,
565 : : (sal_Char*)pBuffer,
566 : : BytesToSend, 0);
567 : :
568 : :
569 : : if ( nRet <= 0 )
570 : : {
571 : : OSL_TRACE("osl_sendPipe failed : %i '%s'",nRet,strerror(errno));
572 : : }
573 : :
574 : 4676451 : return nRet;
575 : : }
576 : :
577 : :
578 : : /*****************************************************************************/
579 : : /* osl_getLastPipeError */
580 : : /*****************************************************************************/
581 : 118 : oslPipeError SAL_CALL osl_getLastPipeError(oslPipe pPipe)
582 : : {
583 : : (void) pPipe; /* unused */
584 : 118 : return ERROR_FROM_NATIVE(errno);
585 : : }
586 : :
587 : :
588 : 4676293 : sal_Int32 SAL_CALL osl_writePipe( oslPipe pPipe, const void *pBuffer , sal_Int32 n )
589 : : {
590 : : /* loop until all desired bytes were send or an error occurred */
591 : 4676293 : sal_Int32 BytesSend= 0;
592 : 4676293 : sal_Int32 BytesToSend= n;
593 : :
594 : : OSL_ASSERT(pPipe);
595 [ + + ]: 9352586 : while (BytesToSend > 0)
596 : : {
597 : : sal_Int32 RetVal;
598 : :
599 : 4676293 : RetVal= osl_sendPipe(pPipe, pBuffer, BytesToSend);
600 : :
601 : : /* error occurred? */
602 [ - + ]: 4676293 : if(RetVal <= 0)
603 : : {
604 : 0 : break;
605 : : }
606 : :
607 : 4676293 : BytesToSend -= RetVal;
608 : 4676293 : BytesSend += RetVal;
609 : 4676293 : pBuffer= (sal_Char*)pBuffer + RetVal;
610 : : }
611 : :
612 : 4676293 : return BytesSend;
613 : : }
614 : :
615 : 4455688 : sal_Int32 SAL_CALL osl_readPipe( oslPipe pPipe, void *pBuffer , sal_Int32 n )
616 : : {
617 : : /* loop until all desired bytes were read or an error occurred */
618 : 4455688 : sal_Int32 BytesRead= 0;
619 : 4455688 : sal_Int32 BytesToRead= n;
620 : :
621 : : OSL_ASSERT( pPipe );
622 [ + + ]: 9246484 : while (BytesToRead > 0)
623 : : {
624 : : sal_Int32 RetVal;
625 : 4791274 : RetVal= osl_receivePipe(pPipe, pBuffer, BytesToRead);
626 : :
627 : : /* error occurred? */
628 [ + + ]: 4791272 : if(RetVal <= 0)
629 : : {
630 : 476 : break;
631 : : }
632 : :
633 : 4790796 : BytesToRead -= RetVal;
634 : 4790796 : BytesRead += RetVal;
635 : 4790796 : pBuffer= (sal_Char*)pBuffer + RetVal;
636 : : }
637 : 4455686 : return BytesRead;
638 : : }
639 : :
640 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|