LCOV - code coverage report
Current view: top level - sal/osl/unx - pipe.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 160 208 76.9 %
Date: 2015-06-13 12:38:46 Functions: 14 15 93.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "system.hxx"
      21             : 
      22             : #include <osl/pipe.h>
      23             : #include <osl/diagnose.h>
      24             : #include <osl/thread.h>
      25             : #include <osl/interlck.h>
      26             : #include <rtl/string.h>
      27             : #include <rtl/ustring.h>
      28             : #include <rtl/bootstrap.h>
      29             : #include <sal/log.hxx>
      30             : 
      31             : #include "sockimpl.hxx"
      32             : #include "secimpl.hxx"
      33             : 
      34             : #define PIPEDEFAULTPATH     "/tmp"
      35             : #define PIPEALTERNATEPATH   "/var/tmp"
      36             : 
      37             : #define PIPENAMEMASK    "OSL_PIPE_%s"
      38             : #define SECPIPENAMEMASK "OSL_PIPE_%s_%s"
      39             : 
      40             : oslPipe SAL_CALL osl_psz_createPipe(const sal_Char *pszPipeName, oslPipeOptions Options, oslSecurity Security);
      41             : 
      42             : static struct
      43             : {
      44             :     int            errcode;
      45             :     oslPipeError   error;
      46             : } PipeError[]= {
      47             :     { 0,               osl_Pipe_E_None              },  /* no error */
      48             :     { EPROTOTYPE,      osl_Pipe_E_NoProtocol        },  /* Protocol wrong type for socket */
      49             :     { ENOPROTOOPT,     osl_Pipe_E_NoProtocol        },  /* Protocol not available */
      50             :     { EPROTONOSUPPORT, osl_Pipe_E_NoProtocol        },  /* Protocol not supported */
      51             :     { ESOCKTNOSUPPORT, osl_Pipe_E_NoProtocol        },  /* Socket type not supported */
      52             :     { EPFNOSUPPORT,    osl_Pipe_E_NoProtocol        },  /* Protocol family not supported */
      53             :     { EAFNOSUPPORT,    osl_Pipe_E_NoProtocol        },  /* Address family not supported by */
      54             :                                                         /* protocol family */
      55             :     { ENETRESET,       osl_Pipe_E_NetworkReset      },  /* Network dropped connection because */
      56             :                                                          /* of reset */
      57             :     { ECONNABORTED,    osl_Pipe_E_ConnectionAbort   },  /* Software caused connection abort */
      58             :     { ECONNRESET,      osl_Pipe_E_ConnectionReset   },  /* Connection reset by peer */
      59             :     { ENOBUFS,         osl_Pipe_E_NoBufferSpace     },  /* No buffer space available */
      60             :     { ETIMEDOUT,       osl_Pipe_E_TimedOut          },  /* Connection timed out */
      61             :     { ECONNREFUSED,    osl_Pipe_E_ConnectionRefused },  /* Connection refused */
      62             :     { -1,              osl_Pipe_E_invalidError      }
      63             : };
      64             : 
      65             : /* reverse map */
      66         185 : static oslPipeError osl_PipeErrorFromNative(int nativeType)
      67             : {
      68         185 :     int i = 0;
      69             : 
      70        2305 :     while ((PipeError[i].error != osl_Pipe_E_invalidError) &&
      71        1935 :            (PipeError[i].errcode != nativeType)) i++;
      72             : 
      73         185 :     return PipeError[i].error;
      74             : }
      75             : 
      76         579 : oslPipe __osl_createPipeImpl()
      77             : {
      78             :     oslPipe pPipeImpl;
      79             : 
      80         579 :     pPipeImpl = static_cast<oslPipe>(calloc(1, sizeof(struct oslPipeImpl)));
      81         579 :     if (pPipeImpl == NULL)
      82           0 :         return NULL;
      83         579 :     pPipeImpl->m_nRefCount =1;
      84         579 :     pPipeImpl->m_bClosed = false;
      85             : #if defined(LINUX)
      86         579 :     pPipeImpl->m_bIsInShutdown = false;
      87         579 :     pPipeImpl->m_bIsAccepting = false;
      88             : #endif
      89         579 :     return pPipeImpl;
      90             : }
      91             : 
      92         569 : void __osl_destroyPipeImpl(oslPipe pImpl)
      93             : {
      94         569 :     if (pImpl != NULL)
      95         569 :         free(pImpl);
      96         569 : }
      97             : 
      98         515 : oslPipe SAL_CALL osl_createPipe(rtl_uString *ustrPipeName, oslPipeOptions Options, oslSecurity Security)
      99             : {
     100         515 :     oslPipe pPipe=0;
     101         515 :     rtl_String* strPipeName=0;
     102             : 
     103         515 :     if ( ustrPipeName != 0 )
     104             :     {
     105             :         rtl_uString2String( &strPipeName,
     106         515 :                             rtl_uString_getStr(ustrPipeName),
     107             :                             rtl_uString_getLength(ustrPipeName),
     108         515 :                             osl_getThreadTextEncoding(),
     109        1030 :                             OUSTRING_TO_OSTRING_CVTFLAGS );
     110         515 :         sal_Char* pszPipeName = rtl_string_getStr(strPipeName);
     111         515 :         pPipe = osl_psz_createPipe(pszPipeName, Options, Security);
     112             : 
     113         515 :         if ( strPipeName != 0 )
     114             :         {
     115         515 :             rtl_string_release(strPipeName);
     116             :         }
     117             :     }
     118             : 
     119         515 :     return pPipe;
     120             : 
     121             : }
     122             : 
     123             : static bool
     124           0 : cpyBootstrapSocketPath(sal_Char *name, size_t len)
     125             : {
     126           0 :     bool bRet = false;
     127           0 :     rtl_uString *pName = 0, *pValue = 0;
     128             : 
     129           0 :     rtl_uString_newFromAscii(&pName, "OSL_SOCKET_PATH");
     130             : 
     131           0 :     if (rtl_bootstrap_get(pName, &pValue, NULL))
     132             :     {
     133           0 :         if (pValue && pValue->length > 0)
     134             :         {
     135           0 :             rtl_String *pStrValue = 0;
     136             : 
     137             :             rtl_uString2String(&pStrValue, pValue->buffer,
     138             :                                pValue->length, RTL_TEXTENCODING_UTF8,
     139           0 :                                OUSTRING_TO_OSTRING_CVTFLAGS);
     140           0 :             if (pStrValue)
     141             :             {
     142           0 :                 if (pStrValue->length > 0)
     143             :                 {
     144           0 :                     size_t nCopy = (len-1 < (size_t)pStrValue->length) ? len-1 : (size_t)pStrValue->length;
     145           0 :                     strncpy (name, pStrValue->buffer, nCopy);
     146           0 :                     name[nCopy] = '\0';
     147           0 :                     bRet = (size_t)pStrValue->length < len;
     148             :                 }
     149           0 :                 rtl_string_release(pStrValue);
     150             :             }
     151             :         }
     152           0 :         rtl_uString_release(pName);
     153             :     }
     154           0 :     return bRet;
     155             : }
     156             : 
     157         515 : oslPipe SAL_CALL osl_psz_createPipe(const sal_Char *pszPipeName, oslPipeOptions Options,
     158             :                                     oslSecurity Security)
     159             : {
     160             :     int    Flags;
     161             :     size_t     len;
     162             :     struct sockaddr_un addr;
     163             : 
     164             :     sal_Char     name[PATH_MAX + 1];
     165         515 :     size_t nNameLength = 0;
     166         515 :     bool bNameTooLong = false;
     167             :     oslPipe  pPipe;
     168             : 
     169         515 :     if (access(PIPEDEFAULTPATH, R_OK|W_OK) == 0)
     170             :     {
     171         515 :         strncpy(name, PIPEDEFAULTPATH, sizeof(name));
     172             :     }
     173           0 :     else if (access(PIPEALTERNATEPATH, R_OK|W_OK) == 0)
     174             :     {
     175           0 :         strncpy(name, PIPEALTERNATEPATH, sizeof(name));
     176             :     }
     177           0 :     else if (!cpyBootstrapSocketPath (name, sizeof (name)))
     178             :     {
     179           0 :         return NULL;
     180             :     }
     181         515 :     name[sizeof(name) - 1] = '\0';  // ensure the string is NULL-terminated
     182         515 :     nNameLength = strlen(name);
     183         515 :     bNameTooLong = nNameLength > sizeof(name) - 2;
     184             : 
     185         515 :     if (!bNameTooLong)
     186             :     {
     187         515 :         size_t nRealLength = 0;
     188             : 
     189         515 :         strcat(name, "/");
     190         515 :         ++nNameLength;
     191             : 
     192         515 :         if (Security)
     193             :         {
     194             :             sal_Char Ident[256];
     195             : 
     196         515 :             Ident[0] = '\0';
     197             : 
     198         515 :             OSL_VERIFY(osl_psz_getUserIdent(Security, Ident, sizeof(Ident)));
     199             : 
     200         515 :             nRealLength = snprintf(&name[nNameLength], sizeof(name) - nNameLength, SECPIPENAMEMASK, Ident, pszPipeName);
     201             :         }
     202             :         else
     203             :         {
     204           0 :             nRealLength = snprintf(&name[nNameLength], sizeof(name) - nNameLength, PIPENAMEMASK, pszPipeName);
     205             :         }
     206             : 
     207         515 :         bNameTooLong = nRealLength > sizeof(name) - nNameLength - 1;
     208             :     }
     209             : 
     210         515 :     if (bNameTooLong)
     211             :     {
     212             :         SAL_WARN("sal.osl.pipe", "osl_createPipe: pipe name too long");
     213           0 :         return NULL;
     214             :     }
     215             : 
     216             :     /* alloc memory */
     217         515 :     pPipe = __osl_createPipeImpl();
     218             : 
     219         515 :     if (pPipe == NULL)
     220           0 :         return NULL;
     221             : 
     222             :     /* create socket */
     223         515 :     pPipe->m_Socket = socket(AF_UNIX, SOCK_STREAM, 0);
     224         515 :     if ( pPipe->m_Socket < 0 )
     225             :     {
     226             :         SAL_WARN("sal.osl.pipe", "socket() failed: " << strerror(errno));
     227           0 :         __osl_destroyPipeImpl(pPipe);
     228           0 :         return NULL;
     229             :     }
     230             : 
     231             :     /* set close-on-exec flag */
     232         515 :     if ((Flags = fcntl(pPipe->m_Socket, F_GETFD, 0)) != -1)
     233             :     {
     234         515 :         Flags |= FD_CLOEXEC;
     235         515 :         if (fcntl(pPipe->m_Socket, F_SETFD, Flags) == -1)
     236             :         {
     237             :             SAL_WARN("sal.osl.pipe", "fcntl() failed: " << strerror(errno));
     238             :         }
     239             :     }
     240             : 
     241         515 :     memset(&addr, 0, sizeof(addr));
     242             : 
     243             :     SAL_INFO("sal.osl.pipe", "new pipe on fd " << pPipe->m_Socket << " '" << name << "'");
     244             : 
     245         515 :     addr.sun_family = AF_UNIX;
     246         515 :     strncpy(addr.sun_path, name, sizeof(addr.sun_path) - 1);
     247             : #if defined(FREEBSD)
     248             :     len = SUN_LEN(&addr);
     249             : #else
     250         515 :     len = sizeof(addr);
     251             : #endif
     252             : 
     253         515 :     if ( Options & osl_Pipe_CREATE )
     254             :     {
     255             :         struct stat status;
     256             : 
     257             :         /* check if there exists an orphan filesystem entry */
     258         183 :         if ( ( stat(name, &status) == 0) &&
     259           2 :              ( S_ISSOCK(status.st_mode) || S_ISFIFO(status.st_mode) ) )
     260             :         {
     261           2 :             if ( connect(pPipe->m_Socket, reinterpret_cast<sockaddr *>(&addr), len) >= 0 )
     262             :             {
     263           0 :                 close (pPipe->m_Socket);
     264           0 :                 __osl_destroyPipeImpl(pPipe);
     265           0 :                 return NULL;
     266             :             }
     267             : 
     268           2 :             unlink(name);
     269             :         }
     270             : 
     271             :         /* ok, fs clean */
     272         179 :         if ( bind(pPipe->m_Socket, reinterpret_cast<sockaddr *>(&addr), len) < 0 )
     273             :         {
     274             :             SAL_WARN("sal.osl.pipe", "bind() failed: " << strerror(errno));
     275           0 :             close (pPipe->m_Socket);
     276           0 :             __osl_destroyPipeImpl(pPipe);
     277           0 :             return NULL;
     278             :         }
     279             : 
     280             :         /*  Only give access to all if no security handle was specified, otherwise security
     281             :             depends on umask */
     282             : 
     283         179 :         if ( !Security )
     284           0 :             chmod(name,S_IRWXU | S_IRWXG |S_IRWXO);
     285             : 
     286         179 :         strncpy(pPipe->m_Name, name, sizeof(pPipe->m_Name) - 1);
     287             : 
     288         179 :         if ( listen(pPipe->m_Socket, 5) < 0 )
     289             :         {
     290             :             SAL_WARN("sal.osl.pipe", "listen() failed: " << strerror(errno));
     291             :             // coverity[toctou] cid#1255391 warns about unlink(name) after
     292             :             // stat(name, &status) above, but the intervening call to bind makes
     293             :             // those two clearly unrelated, as it would fail if name existed at
     294             :             // that point in time:
     295           0 :             unlink(name);   /* remove filesystem entry */
     296           0 :             close (pPipe->m_Socket);
     297           0 :             __osl_destroyPipeImpl(pPipe);
     298           0 :             return NULL;
     299             :         }
     300             : 
     301         179 :         return pPipe;
     302             :     }
     303             :     else
     304             :     {   /* osl_pipe_OPEN */
     305         336 :         if ( access(name, F_OK) != -1 )
     306             :         {
     307          71 :             if ( connect( pPipe->m_Socket, reinterpret_cast<sockaddr *>(&addr), len) >= 0 )
     308             :             {
     309          71 :                 return pPipe;
     310             :             }
     311             : 
     312             :             SAL_WARN("sal.osl.pipe", "connect() failed: " << strerror(errno));
     313             :         }
     314             : 
     315         265 :         close (pPipe->m_Socket);
     316         265 :         __osl_destroyPipeImpl(pPipe);
     317         265 :         return NULL;
     318             :     }
     319             : }
     320             : 
     321     2056020 : void SAL_CALL osl_acquirePipe( oslPipe pPipe )
     322             : {
     323     2056020 :     osl_atomic_increment( &(pPipe->m_nRefCount) );
     324     2056020 : }
     325             : 
     326     2056317 : void SAL_CALL osl_releasePipe( oslPipe pPipe )
     327             : {
     328             : 
     329     2056317 :     if( 0 == pPipe )
     330     2056317 :         return;
     331             : 
     332     2056317 :     if( 0 == osl_atomic_decrement( &(pPipe->m_nRefCount) ) )
     333             :     {
     334         304 :         if( ! pPipe->m_bClosed )
     335           1 :             osl_closePipe( pPipe );
     336             : 
     337         304 :         __osl_destroyPipeImpl( pPipe );
     338             :     }
     339             : }
     340             : 
     341         424 : void SAL_CALL osl_closePipe( oslPipe pPipe )
     342             : {
     343             :     int nRet;
     344             :     int ConnFD;
     345             : 
     346         424 :     if( ! pPipe )
     347             :     {
     348         119 :         return;
     349             :     }
     350             : 
     351         422 :     if( pPipe->m_bClosed )
     352             :     {
     353         115 :         return;
     354             :     }
     355             : 
     356         307 :     ConnFD = pPipe->m_Socket;
     357             : 
     358             :     /*
     359             :       Thread does not return from accept on linux, so
     360             :       connect to the accepting pipe
     361             :      */
     362             : #if defined(LINUX)
     363             :     struct sockaddr_un addr;
     364             : 
     365         307 :     if ( pPipe->m_bIsAccepting )
     366             :     {
     367         178 :         pPipe->m_bIsInShutdown = true;
     368         178 :         pPipe->m_Socket = -1;
     369         178 :         int fd = socket(AF_UNIX, SOCK_STREAM, 0);
     370         178 :         if ( fd < 0 )
     371             :         {
     372             :             SAL_WARN("sal.osl.pipe", "socket() failed: " << strerror(errno));
     373           0 :             return;
     374             :         }
     375         178 :         memset(&addr, 0, sizeof(addr));
     376             : 
     377             :         SAL_INFO("sal.osl.pipe", "osl_destroyPipe : Pipe Name '" << pPipe->m_Name << "'");
     378             : 
     379         178 :         addr.sun_family = AF_UNIX;
     380         178 :         strncpy(addr.sun_path, pPipe->m_Name, sizeof(addr.sun_path) - 1);
     381         178 :         size_t len = sizeof(addr);
     382             : 
     383         178 :         nRet = connect( fd, reinterpret_cast<sockaddr *>(&addr), len);
     384         178 :         if ( nRet < 0 )
     385             :         {
     386             :             SAL_WARN("sal.osl.pipe", "connect() failed: " << strerror(errno));
     387             :         }
     388         178 :         close(fd);
     389             :     }
     390             : #endif /* LINUX */
     391             : 
     392         307 :     nRet = shutdown(ConnFD, 2);
     393         307 :     if ( nRet < 0 )
     394             :     {
     395             :         SAL_WARN("sal.osl.pipe", "shutdown() failed: " << strerror(errno));
     396             :     }
     397             : 
     398         307 :     nRet = close(ConnFD);
     399         307 :     if ( nRet < 0 )
     400             :     {
     401             :         SAL_WARN("sal.osl.pipe", "close() failed: " << strerror(errno));
     402             :     }
     403             :     /* remove filesystem entry */
     404         307 :     if ( strlen(pPipe->m_Name) > 0 )
     405             :     {
     406         179 :         unlink(pPipe->m_Name);
     407             :     }
     408         307 :     pPipe->m_bClosed = true;
     409             : }
     410             : 
     411         242 : oslPipe SAL_CALL osl_acceptPipe(oslPipe pPipe)
     412             : {
     413             :     int     s;
     414             :     oslPipe pAcceptedPipe;
     415             : 
     416             :     OSL_ASSERT(pPipe);
     417         242 :     if ( pPipe == 0 )
     418             :     {
     419           0 :         return NULL;
     420             :     }
     421             : 
     422             :     OSL_ASSERT(strlen(pPipe->m_Name) > 0);
     423             : 
     424             : #if defined(LINUX)
     425         242 :     pPipe->m_bIsAccepting = true;
     426             : #endif
     427             : 
     428         242 :     s = accept(pPipe->m_Socket, NULL, NULL);
     429             : 
     430             : #if defined(LINUX)
     431         242 :     pPipe->m_bIsAccepting = false;
     432             : #endif
     433             : 
     434         242 :     if (s < 0)
     435             :     {
     436             :         SAL_WARN("sal.osl.pipe", "accept() failed: " << strerror(errno));
     437           0 :         return NULL;
     438             :     }
     439             : 
     440             : #if defined(LINUX)
     441         242 :     if ( pPipe->m_bIsInShutdown  )
     442             :     {
     443         178 :         close(s);
     444         178 :         return NULL;
     445             :     }
     446             : #endif /* LINUX */
     447             :     else
     448             :     {
     449             :         /* alloc memory */
     450          64 :         pAcceptedPipe = __osl_createPipeImpl();
     451             : 
     452             :         OSL_ASSERT(pAcceptedPipe);
     453          64 :         if(pAcceptedPipe==NULL)
     454             :         {
     455           0 :             close(s);
     456           0 :             return NULL;
     457             :         }
     458             : 
     459             :         /* set close-on-exec flag */
     460             :         int flags;
     461          64 :         if (!((flags = fcntl(s, F_GETFD, 0)) < 0))
     462             :         {
     463          64 :             flags |= FD_CLOEXEC;
     464          64 :             if (fcntl(s, F_SETFD, flags) < 0)
     465             :             {
     466             :                 SAL_WARN("sal.osl.pipe", "fcntl() failed: " <<  strerror(errno));
     467             :             }
     468             :         }
     469             : 
     470          64 :         pAcceptedPipe->m_Socket = s;
     471             :     }
     472             : 
     473          64 :     return pAcceptedPipe;
     474             : }
     475             : 
     476     3334567 : sal_Int32 SAL_CALL osl_receivePipe(oslPipe pPipe,
     477             :                         void* pBuffer,
     478             :                         sal_Int32 BytesToRead)
     479             : {
     480     3334567 :     int nRet = 0;
     481             : 
     482             :     OSL_ASSERT(pPipe);
     483             : 
     484     3334567 :     if ( pPipe == 0 )
     485             :     {
     486             :         SAL_WARN("sal.osl.pipe", "osl_receivePipe: Invalid socket");
     487           0 :         errno=EINVAL;
     488           0 :         return -1;
     489             :     }
     490             : 
     491             :     nRet = recv(pPipe->m_Socket,
     492             :                   pBuffer,
     493     3334567 :                   BytesToRead, 0);
     494             : 
     495     3334565 :     if ( nRet < 0 )
     496             :     {
     497             :         SAL_WARN("sal.osl.pipe", "recv() failed: " << strerror(errno));
     498             :     }
     499             : 
     500     3334565 :       return nRet;
     501             : }
     502             : 
     503     2720766 : sal_Int32 SAL_CALL osl_sendPipe(oslPipe pPipe,
     504             :                        const void* pBuffer,
     505             :                        sal_Int32 BytesToSend)
     506             : {
     507     2720766 :     int nRet=0;
     508             : 
     509             :     OSL_ASSERT(pPipe);
     510             : 
     511     2720766 :     if ( pPipe == 0 )
     512             :     {
     513             :         SAL_WARN("sal.osl.pipe", "osl_sendPipe: Invalid socket");
     514           0 :         errno=EINVAL;
     515           0 :         return -1;
     516             :     }
     517             : 
     518             :     nRet = send(pPipe->m_Socket,
     519             :                   pBuffer,
     520     2720766 :                   BytesToSend, 0);
     521             : 
     522     2720766 :     if ( nRet <= 0 )
     523             :     {
     524             :         SAL_WARN("sal.osl.pipe", "send() failed: " << strerror(errno));
     525             :     }
     526             : 
     527     2720766 :      return nRet;
     528             : }
     529             : 
     530         185 : oslPipeError SAL_CALL osl_getLastPipeError(oslPipe pPipe)
     531             : {
     532             :     (void) pPipe; /* unused */
     533         185 :     return osl_PipeErrorFromNative(errno);
     534             : }
     535             : 
     536     2720766 : sal_Int32 SAL_CALL osl_writePipe( oslPipe pPipe, const void *pBuffer , sal_Int32 n )
     537             : {
     538             :     /* loop until all desired bytes were send or an error occurred */
     539     2720766 :     sal_Int32 BytesSend= 0;
     540     2720766 :     sal_Int32 BytesToSend= n;
     541             : 
     542             :     OSL_ASSERT(pPipe);
     543     8162298 :     while (BytesToSend > 0)
     544             :     {
     545             :         sal_Int32 RetVal;
     546             : 
     547     2720766 :         RetVal= osl_sendPipe(pPipe, pBuffer, BytesToSend);
     548             : 
     549             :         /* error occurred? */
     550     2720766 :         if(RetVal <= 0)
     551             :         {
     552           0 :             break;
     553             :         }
     554             : 
     555     2720766 :         BytesToSend -= RetVal;
     556     2720766 :         BytesSend += RetVal;
     557     2720766 :         pBuffer= static_cast<sal_Char const *>(pBuffer) + RetVal;
     558             :     }
     559             : 
     560     2720766 :     return BytesSend;
     561             : }
     562             : 
     563     2589541 : sal_Int32 SAL_CALL osl_readPipe( oslPipe pPipe, void *pBuffer , sal_Int32 n )
     564             : {
     565             :     /* loop until all desired bytes were read or an error occurred */
     566     2589541 :     sal_Int32 BytesRead= 0;
     567     2589541 :     sal_Int32 BytesToRead= n;
     568             : 
     569             :     OSL_ASSERT( pPipe );
     570     8513328 :     while (BytesToRead > 0)
     571             :     {
     572             :         sal_Int32 RetVal;
     573     3334567 :         RetVal= osl_receivePipe(pPipe, pBuffer, BytesToRead);
     574             : 
     575             :         /* error occurred? */
     576     3334565 :         if(RetVal <= 0)
     577             :         {
     578         319 :             break;
     579             :         }
     580             : 
     581     3334246 :         BytesToRead -= RetVal;
     582     3334246 :         BytesRead += RetVal;
     583     3334246 :         pBuffer= static_cast<sal_Char*>(pBuffer) + RetVal;
     584             :     }
     585     2589539 :     return BytesRead;
     586             : }
     587             : 
     588             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11