00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifdef __MSC_VER
00015 #pragma warning ( disable : 4786 )
00016 #endif
00017
00018 #include <cabal_socket.h>
00019 #include <cabal_channel.h>
00020 #include <fcntl.h>
00021 #include <string>
00022 #include <cassert>
00023
00024 namespace Cabal {
00025
00026 Socket::Socket( const Socket &orig )
00027 throw( InitError )
00028 {
00029 m_skCom = Net::dup( orig.m_skCom );
00030 if ( ! Net::validSocket( m_skCom ) )
00031 throw InitError( "Can't create a new file descriptor", Net::errorCode() );
00032
00033 m_timeout = orig.m_timeout;
00034 m_bTout = orig.m_bTout;
00035 m_type = orig.m_type;
00036
00037 m_remote = orig.m_remote;
00038 m_local = orig.m_local;
00039
00040 m_channel = 0;
00041 m_recpt = 0;
00042 }
00043
00044
00045 bool Socket::bind( const Address &local )
00046 {
00047 if ( ! Net::bind( m_skCom, local.address() ) )
00048 {
00049 m_osError = Net::errorCode();
00050 return false;
00051 }
00052
00053 m_osError = 0;
00054 m_local = local;
00055 return true;
00056 }
00057
00058 int Socket::selectFor( bool rw )
00059 {
00060
00061 if ( managed() ) return 1;
00062
00063 fd_set set;
00064 struct timeval tv;
00065
00066 FD_ZERO( &set );
00067 FD_SET(m_skCom, &set);
00068 Net::resetError();
00069
00070 if ( m_timeout == -1 )
00071 {
00072 if ( rw )
00073 select(m_skCom+1, NULL, &set, NULL, NULL);
00074 else
00075 select(m_skCom+1, &set, NULL, NULL, NULL);
00076 }
00077 else
00078 {
00079 tv.tv_sec = m_timeout/ 1000;
00080 tv.tv_usec = (m_timeout % 1000) * 1000;
00081 if ( rw )
00082 select(m_skCom + 1, NULL, &set, NULL, &tv);
00083 else
00084 select(m_skCom + 1, &set, NULL, NULL, &tv);
00085 }
00086
00087 return FD_ISSET( m_skCom, &set );
00088 }
00089
00090
00091 int Socket::recv( void *buffer, const int len )
00092 {
00093 int retlen;
00094
00095 if( selectFor( false ) )
00096 {
00097 retlen = rawRecv( buffer, len );
00098
00099 if ( retlen < 0 )
00100 m_osError = Net::errorCode();
00101 else {
00102 m_osError = 0;
00103
00104 if ( retlen == 0 ) {
00105 Net::closeSocket( m_skCom );
00106 Net::invalidate( m_skCom );
00107 }
00108 }
00109
00110 m_bTout = false;
00111 return retlen;
00112 }
00113 else
00114 {
00115 m_osError = 0;
00116 m_bTout = true;
00117 return 0;
00118 }
00119 }
00120
00121 int Socket::send( const void *buffer, const int len )
00122 {
00123 if ( ! Net::validSocket( m_skCom ) ) return -1;
00124
00125 int readin;
00126 if( selectFor( true ) )
00127 {
00128 readin = rawSend( buffer, len );
00129
00130 if ( readin < 0 ) {
00131 if ( Net::errorPipe() ) {
00132
00133 Net::closeSocket( m_skCom );
00134 Net::invalidate( m_skCom );
00135 readin = 0;
00136 m_osError = 0;
00137 }
00138 else
00139 m_osError = Net::errorCode();
00140 }
00141 else
00142 m_osError = 0;
00143 m_bTout = false;
00144 return readin;
00145 }
00146 else
00147 {
00148 m_osError = 0;
00149 m_bTout = true;
00150 return 0;
00151 }
00152 }
00153
00154 bool Socket::close()
00155 {
00156 m_osError = 0;
00157 if ( m_recpt != 0 )
00158 {
00159 m_recpt->terminate( this );
00160 delete m_recpt;
00161 m_recpt = 0;
00162 }
00163
00164 if ( ! Net::validSocket( m_skCom ) )
00165 return false;
00166
00167 if ( Net::closeSocket( m_skCom ) == 0 ) {
00168 Net::invalidate( m_skCom );
00169 return true;
00170 }
00171 else {
00172 m_osError = Net::errorCode();
00173 return false;
00174 }
00175 }
00176
00177
00178 void Socket::channel( Channel *chn, Reception* rcpt )
00179 {
00180 if ( m_recpt != 0 )
00181 {
00182 m_recpt->terminate( this );
00183 delete m_recpt;
00184 }
00185
00186 m_recpt = rcpt;
00187 m_recpt->init( this );
00188
00189 if ( m_channel )
00190 m_channel->removeSocket( this );
00191
00192 m_channel = chn;
00193
00194 if ( m_channel )
00195 m_channel->addSocket( this );
00196 }
00197
00198 }