1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_io.hxx" 26 #include "osl/security.hxx" 27 #include "acceptor.hxx" 28 #include <com/sun/star/connection/ConnectionSetupException.hpp> 29 30 #include <cppuhelper/implbase1.hxx> 31 32 using namespace ::rtl; 33 using namespace ::osl; 34 using namespace ::cppu; 35 using namespace ::com::sun::star::uno; 36 using namespace ::com::sun::star::lang; 37 using namespace ::com::sun::star::connection; 38 using namespace ::com::sun::star::io; 39 40 41 namespace io_acceptor 42 { 43 44 typedef WeakImplHelper1< XConnection > MyPipeConnection; 45 46 class PipeConnection : 47 public MyPipeConnection 48 { 49 public: 50 PipeConnection( const OUString &sConnectionDescription); 51 ~PipeConnection(); 52 53 virtual sal_Int32 SAL_CALL read( Sequence< sal_Int8 >& aReadBytes, sal_Int32 nBytesToRead ) 54 throw(::com::sun::star::io::IOException, 55 ::com::sun::star::uno::RuntimeException); 56 virtual void SAL_CALL write( const Sequence< sal_Int8 >& aData ) 57 throw(::com::sun::star::io::IOException, 58 ::com::sun::star::uno::RuntimeException); 59 virtual void SAL_CALL flush( ) throw( 60 ::com::sun::star::io::IOException, 61 ::com::sun::star::uno::RuntimeException); 62 virtual void SAL_CALL close( ) 63 throw(::com::sun::star::io::IOException, 64 ::com::sun::star::uno::RuntimeException); 65 virtual ::rtl::OUString SAL_CALL getDescription( ) 66 throw(::com::sun::star::uno::RuntimeException); 67 public: 68 ::osl::StreamPipe m_pipe; 69 oslInterlockedCount m_nStatus; 70 OUString m_sDescription; 71 }; 72 73 74 PipeConnection(const OUString & sConnectionDescription)75 PipeConnection::PipeConnection( const OUString &sConnectionDescription) : 76 m_nStatus( 0 ), 77 m_sDescription( sConnectionDescription ) 78 { 79 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 80 81 // make it unique 82 m_sDescription += OUString::createFromAscii( ",uniqueValue=" ); 83 m_sDescription += OUString::valueOf( 84 sal::static_int_cast<sal_Int64 >( 85 reinterpret_cast< sal_IntPtr >(&m_pipe)), 86 10 ); 87 } 88 ~PipeConnection()89 PipeConnection::~PipeConnection() 90 { 91 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 92 } 93 read(Sequence<sal_Int8> & aReadBytes,sal_Int32 nBytesToRead)94 sal_Int32 PipeConnection::read( Sequence < sal_Int8 > & aReadBytes , sal_Int32 nBytesToRead ) 95 throw(::com::sun::star::io::IOException, 96 ::com::sun::star::uno::RuntimeException) 97 { 98 if( ! m_nStatus ) 99 { 100 if( aReadBytes.getLength() < nBytesToRead ) 101 { 102 aReadBytes.realloc( nBytesToRead ); 103 } 104 sal_Int32 n = m_pipe.read( aReadBytes.getArray(), nBytesToRead ); 105 OSL_ASSERT( n >= 0 && n <= aReadBytes.getLength() ); 106 if( n < aReadBytes.getLength() ) 107 { 108 aReadBytes.realloc( n ); 109 } 110 return n; 111 } 112 else { 113 throw IOException(); 114 } 115 } 116 write(const Sequence<sal_Int8> & seq)117 void PipeConnection::write( const Sequence < sal_Int8 > &seq ) 118 throw(::com::sun::star::io::IOException, 119 ::com::sun::star::uno::RuntimeException) 120 { 121 if( ! m_nStatus ) 122 { 123 if( m_pipe.write( seq.getConstArray() , seq.getLength() ) != seq.getLength() ) 124 { 125 throw IOException(); 126 } 127 } 128 else { 129 throw IOException(); 130 } 131 } 132 flush()133 void PipeConnection::flush( ) 134 throw( ::com::sun::star::io::IOException, 135 ::com::sun::star::uno::RuntimeException) 136 { 137 } 138 close()139 void PipeConnection::close() 140 throw( ::com::sun::star::io::IOException, 141 ::com::sun::star::uno::RuntimeException) 142 { 143 if( 1 == osl_incrementInterlockedCount( (&m_nStatus) ) ) 144 { 145 m_pipe.close(); 146 } 147 } 148 getDescription()149 OUString PipeConnection::getDescription() 150 throw(::com::sun::star::uno::RuntimeException) 151 { 152 return m_sDescription; 153 } 154 155 /*************** 156 * PipeAcceptor 157 **************/ PipeAcceptor(const OUString & sPipeName,const OUString & sConnectionDescription)158 PipeAcceptor::PipeAcceptor( const OUString &sPipeName , const OUString & sConnectionDescription) : 159 m_sPipeName( sPipeName ), 160 m_sConnectionDescription( sConnectionDescription ), 161 m_bClosed( sal_False ) 162 { 163 } 164 165 init()166 void PipeAcceptor::init() 167 { 168 m_pipe = Pipe( m_sPipeName.pData , osl_Pipe_CREATE , osl::Security() ); 169 if( ! m_pipe.is() ) 170 { 171 OUString error = OUString::createFromAscii( "io.acceptor: Couldn't setup pipe " ); 172 error += m_sPipeName; 173 throw ConnectionSetupException( error, Reference< XInterface > () ); 174 } 175 } 176 accept()177 Reference< XConnection > PipeAcceptor::accept( ) 178 { 179 Pipe pipe; 180 { 181 MutexGuard guard( m_mutex ); 182 pipe = m_pipe; 183 } 184 if( ! pipe.is() ) 185 { 186 OUString error = OUString::createFromAscii( "io.acceptor: pipe already closed" ); 187 error += m_sPipeName; 188 throw ConnectionSetupException( error, Reference< XInterface > () ); 189 } 190 PipeConnection *pConn = new PipeConnection( m_sConnectionDescription ); 191 192 oslPipeError status = pipe.accept( pConn->m_pipe ); 193 194 if( m_bClosed ) 195 { 196 // stopAccepting was called ! 197 delete pConn; 198 return Reference < XConnection >(); 199 } 200 else if( osl_Pipe_E_None == status ) 201 { 202 return Reference < XConnection > ( (XConnection * ) pConn ); 203 } 204 else 205 { 206 OUString error = OUString::createFromAscii( "io.acceptor: Couldn't setup pipe " ); 207 error += m_sPipeName; 208 throw ConnectionSetupException( error, Reference< XInterface > ()); 209 } 210 } 211 stopAccepting()212 void PipeAcceptor::stopAccepting() 213 { 214 m_bClosed = sal_True; 215 Pipe pipe; 216 { 217 MutexGuard guard( m_mutex ); 218 pipe = m_pipe; 219 m_pipe.clear(); 220 } 221 if( pipe.is() ) 222 { 223 pipe.close(); 224 } 225 } 226 } 227