00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "precomp.h"
00030 #include "pipe_connection.h"
00031 #include "exception.h"
00032 #include "string_help.h"
00033 #include "event.h"
00034 #include "socket_event_handler.h"
00035 #ifndef WIN32
00036 #include <sys/socket.h>
00037 #include <sys/un.h>
00038 #endif
00039
00040 #ifndef UNIX_PATH_MAX
00041 #define UNIX_PATH_MAX 108
00042 #endif
00043
00045
00046
00047 CL_PipeConnection::CL_PipeConnection(const CL_String &pipe_name, bool pass_credentials)
00048 : handle(-1), socket_event_handler(0), read_event(0), write_event(0), exception_event(0)
00049 {
00050 #ifdef WIN32
00051 #else
00052 CL_StringA pipe_name_local8 = CL_StringHelp::text_to_local8(pipe_name);
00053 if (pipe_name_local8.length() >= UNIX_PATH_MAX)
00054 throw CL_Exception(TEXT("Pipe name too long"));
00055
00056 handle = socket(PF_UNIX, SOCK_STREAM, 0);
00057 if (handle == -1)
00058 throw CL_Exception(TEXT("Socket create failed"));
00059
00060 sockaddr_un name;
00061 memset(&name, 0, sizeof(sockaddr_un));
00062 name.sun_family = AF_UNIX;
00063 memcpy(name.sun_path+1, pipe_name_local8.data(), pipe_name_local8.length());
00064
00065 int res = ::connect(handle, (sockaddr *) &name, sizeof(sockaddr_un));
00066 if (res == -1)
00067 {
00068 ::close(handle);
00069 throw CL_Exception(TEXT("Could not connect to server"));
00070 }
00071
00072 socket_event_handler = new CL_SocketEventHandler(handle);
00073 read_event = new CL_Event(socket_event_handler, CL_Event::type_socket_read);
00074 write_event = new CL_Event(socket_event_handler, CL_Event::type_socket_write);
00075 exception_event = new CL_Event(socket_event_handler, CL_Event::type_socket_exception);
00076
00077 if (pass_credentials)
00078 {
00079 int flag = 1;
00080 setsockopt(handle, SOL_SOCKET, SO_PASSCRED, &flag, sizeof(int));
00081 }
00082 #endif
00083 }
00084
00085 CL_PipeConnection::CL_PipeConnection(int pipe_handle, bool pass_credentials)
00086 : handle(pipe_handle), socket_event_handler(0), read_event(0), write_event(0), exception_event(0)
00087 {
00088 #ifdef WIN32
00089 #else
00090 if (handle == -1)
00091 throw CL_Exception(TEXT("Invalid socket value"));
00092
00093 socket_event_handler = new CL_SocketEventHandler(handle);
00094 read_event = new CL_Event(socket_event_handler, CL_Event::type_socket_read);
00095 write_event = new CL_Event(socket_event_handler, CL_Event::type_socket_write);
00096 exception_event = new CL_Event(socket_event_handler, CL_Event::type_socket_exception);
00097
00098 if (pass_credentials)
00099 {
00100 int flag = 1;
00101 setsockopt(handle, SOL_SOCKET, SO_PASSCRED, &flag, sizeof(int));
00102 }
00103 #endif
00104 }
00105
00106 CL_PipeConnection::~CL_PipeConnection()
00107 {
00108 #ifdef WIN32
00109 #else
00110 delete read_event;
00111 delete write_event;
00112 delete exception_event;
00113 delete socket_event_handler;
00114 ::close(handle);
00115 #endif
00116 }
00117
00119
00120
00121 CL_Event *CL_PipeConnection::get_read_event()
00122 {
00123 return read_event;
00124 }
00125
00126 CL_Event *CL_PipeConnection::get_write_event()
00127 {
00128 return write_event;
00129 }
00130
00131 CL_Event *CL_PipeConnection::get_exception_event()
00132 {
00133 return exception_event;
00134 }
00135
00137
00138
00139 int CL_PipeConnection::send(const void *_data, int length, int timeout)
00140 {
00141 #ifdef WIN32
00142 return 0;
00143 #else
00144 const char *data = (const char *) _data;
00145 int pos = 0;
00146 while (pos < length)
00147 {
00148 int res = ::send(handle, data+pos, length-pos, 0);
00149 if (res == -1)
00150 throw CL_Exception(TEXT("Write failed to socket!"));
00151
00152 pos += res;
00153 }
00154 return pos;
00155 #endif
00156 }
00157
00158 int CL_PipeConnection::receive(void *_data, int len, int timeout)
00159 {
00160 #ifdef WIN32
00161 return 0;
00162 #else
00163 char *data = (char *) _data;
00164 int received = 0;
00165 while (received < len)
00166 {
00167 int res = ::recv(handle, data+received, len-received, 0);
00168 if (res == -1)
00169 throw CL_Exception(TEXT("Read failed on socket!"));
00170
00171 received += res;
00172 }
00173 return received;
00174 #endif
00175 }
00176
00177 int CL_PipeConnection::peek(void *_data, int len, int timeout)
00178 {
00179 #ifdef WIN32
00180 return 0;
00181 #else
00182 char *data = (char *) _data;
00183 int received = 0;
00184 int res = ::recv(handle, data+received, len-received, MSG_PEEK);
00185 if (res == -1)
00186 throw CL_Exception(TEXT("Read peek failed on socket!"));
00187 received += res;
00188 return received;
00189 #endif
00190 }
00191
00192 CL_String CL_PipeConnection::receive_user_credentials()
00193 {
00194 return CL_String(TEXT("mbn"));
00195 }
00196
00197 void CL_PipeConnection::send_user_credentials()
00198 {
00199 }
00200
00202