Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

pipe_connection.cpp

Go to the documentation of this file.
00001 /*
00002 **  ClanLib SDK
00003 **  Copyright (c) 1997-2005 The ClanLib Team
00004 **
00005 **  This software is provided 'as-is', without any express or implied
00006 **  warranty.  In no event will the authors be held liable for any damages
00007 **  arising from the use of this software.
00008 **
00009 **  Permission is granted to anyone to use this software for any purpose,
00010 **  including commercial applications, and to alter it and redistribute it
00011 **  freely, subject to the following restrictions:
00012 **
00013 **  1. The origin of this software must not be misrepresented; you must not
00014 **     claim that you wrote the original software. If you use this software
00015 **     in a product, an acknowledgment in the product documentation would be
00016 **     appreciated but is not required.
00017 **  2. Altered source versions must be plainly marked as such, and must not be
00018 **     misrepresented as being the original software.
00019 **  3. This notice may not be removed or altered from any source distribution.
00020 **
00021 **  Note: Some of the libraries ClanLib link to may have additional
00022 **  requirements or restrictions.
00023 **
00024 **  File Author(s):
00025 **
00026 **    Magnus Norddahl
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 // CL_PipeConnection Construction:
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 // CL_PipeConnection Attributes:
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 // CL_PipeConnection Operations:
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 // CL_PipeConnection Implementation:

Generated on Sat Feb 19 22:51:16 2005 for npcore by  doxygen 1.4.1