00001 #include <iostream>
00002 #include <stdio.h>
00003
00004
00005 #include "SysPlusPlus/syscall.h"
00006 #include "SysPlusPlus/syslib.h"
00007 #include "SysPlusPlus/Tools.h"
00008 #include "ComPlusPlus/Poll.h"
00009 #include "ComPlusPlus/SocketUnix.h"
00010 #include "SysPlusPlus/GenCfg.h"
00011 #include "SysPlusPlus/ComException.h"
00012
00013 #include <sys/types.h>
00014 #include <sys/socket.h>
00015 #include <netinet/in.h>
00016 #include <sys/un.h>
00017 #include <stdio.h>
00018 #include <signal.h>
00019 #include <netdb.h>
00020
00021
00025 void compp::SocketUnix::NewUnixSocket(enum UDSTYPE T) {
00026
00027 int ty;
00028 STYP = T;
00029 if ( T == STREAM ) {
00030 ty = SOCK_STREAM;
00031 } else {
00032 ty = SOCK_DGRAM;
00033 }
00034
00035 this->fd = syspp::Call::Socket ( AF_UNIX, ty, 0 );
00036 if ( this->fd == -1 ) {
00037 throw syspp::ComException("Panic: Cannot create socket!");
00038 }
00039 IsOpen=false;
00040 FdClosed=false;
00041
00042 }
00043
00048 compp::SocketUnix::~SocketUnix() {
00049
00050 if ( this->fd == -1 )
00051 return;
00052 if ( this->FD_IsAttached() ) {
00053 this->Close ();
00054 unlink (ownAddress.c_str());
00055 }
00056 }
00057
00058
00063 compp::SocketUnix::SocketUnix(enum UDSTYPE T, unsigned int buffsz) : Socket (buffsz) {
00064
00065 NewUnixSocket(T);
00066
00067 }
00068
00073 compp::SocketUnix::SocketUnix(int lfd, sockaddr_un *u, size_t l,unsigned int readaheadbufsize) : Socket (readaheadbufsize) {
00074
00075 this->fd = lfd;
00076 this->IsOpen = true;
00077 this->FdClosed = false;
00078
00079 ownAddress = lfd;
00080 }
00081
00082
00083
00088 void compp::SocketUnix::Close() {
00089
00090 if ( this->fd == -1 ) {
00091 return ;
00092 }
00093 syspp::Call::Close ( this->fd );
00094 this->fd = -1;
00095
00096 IsOpen=false;
00097 FdClosed=true;
00098 }
00099
00100
00108 compp::SocketUnix::SocketUnix(const std::string & fn, enum UDSTYPE T, unsigned int buffsz) : Socket (buffsz) {
00109
00110 NewUnixSocket(T);
00111 this->Bind ( fn );
00112
00113 }
00114
00115
00120 void compp::SocketUnix::Listen ( const int backlog ) {
00121
00122 if ( STYP != STREAM ) {
00123 throw syspp::ComException ( "Cannot listen on DGRAM socket" );
00124 }
00125
00126 if ( syspp::Call::Listen( this->fd, backlog) == -1) {
00127 throw syspp::ComException ( "Cannot listen on STREAM socket" );
00128 perror("listen");
00129 }
00130
00131 }
00132
00137 void compp::SocketUnix::Bind ( const std::string & fn ) {
00138
00139 struct sockaddr_un clntaddr;
00140
00141 clntaddr.sun_family = AF_UNIX;
00142 strcpy(clntaddr.sun_path, fn.c_str() );
00143
00144 if (bind(fd, (const sockaddr*)&clntaddr, sizeof(clntaddr)) < 0) {
00145 close(fd);
00146 perror("client: bind");
00147 }
00148
00149 ownAddress = fn;
00150 }
00151
00155 bool compp::SocketUnix::Connect( const std::string &fn ){
00156
00157 if ( STYP != STREAM ) {
00158 throw syspp::ComException ( "Cannot connect with DGRAM socket" );
00159 }
00160
00161 struct sockaddr_un un;
00162
00163 un.sun_family = AF_UNIX;
00164 strcpy(un.sun_path, fn.c_str() );
00165
00166 if ( -1 == syspp::Call::Connect ( this->fd, ( const sockaddr*) &un, sizeof ( un ) ) ) {
00167 return false;
00168 }
00169 this->IsOpen=true;
00170 this->FdClosed =false;
00171 return true;
00172 }
00173
00179 compp::SocketUnix* compp::SocketUnix::Accept ( void ) {
00180
00181 if ( STYP != STREAM ) {
00182 throw syspp::ComException ( "Cannot accept with DGRAM socket" );
00183 }
00184
00185 struct sockaddr_un un;
00186 int sz = sizeof ( un );
00187 int lfd = syspp::Call::Accept(fd, (struct sockaddr *) &un, &sz);
00188
00189 SocketUnix *retval = new compp::SocketUnix ( lfd, &un, sizeof ( un ), ReadAheadBufferTotalSize );
00190 retval->SetReadAhead ( this->ReadAhead );
00191 this->IsOpen=true;
00192
00193 return retval;
00194 }
00195
00200 int compp::SocketUnix::Sendto(const void *buf, size_t len, const std::string &fn){
00201
00202 if ( STYP != DATAGRAM ) {
00203 throw syspp::ComException ( "Cannot Sendto with STREAM socket" );
00204 }
00205 struct sockaddr_un ad;
00206 int ret;
00207
00208 _MkSockaddrUnix( fn, &ad);
00209
00210 ret = syspp::Call::Sendto( this->fd, buf, len, 0,(const struct sockaddr *) &ad, (int) sizeof ( ad));
00211 if ( ret == -1 ) {
00212 throw syspp::ComException( "Error in SendTo");
00213 }
00214 return ret;
00215 }
00216
00217
00223 int compp::SocketUnix::Recvfrom(void *buf, int len, int flags, std::string &path){
00224
00225 if ( STYP != DATAGRAM ) {
00226 throw syspp::ComException ( "Cannot Recvfrom STREAM socket" );
00227 }
00228
00229 struct sockaddr_un fromsa;
00230 int ret;
00231 int i = sizeof ( fromsa);
00232 memset ( (void *) &fromsa, 0, sizeof ( fromsa) );
00233 ret = syspp::Call::Recvfrom(this->fd, buf, len, flags, (struct sockaddr*) &fromsa, &i );
00234 path = fromsa.sun_path;
00235
00236 if ( ret == -1 && errno != EAGAIN ) {
00237 return -1;
00238 }
00239
00240 return ret;
00241 }
00242
00243
00247 void compp::SocketUnix::_MkSockaddrUnix( const std::string &fn, struct sockaddr_un *ad ) {
00248
00249 memset( ad, 0, sizeof(struct sockaddr_un));
00250 ad->sun_family = AF_UNIX;
00251 strcpy(ad->sun_path, fn.c_str());
00252
00253 }
00254
00255 void compp::SocketUnix::Shutdown (int method ) {
00256
00257 shutdown ( fd, method );
00258
00259 }