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_listen.h"
00031 #include "pipe_connection.h"
00032 #include "exception.h"
00033 #include "event.h"
00034 #include "string_help.h"
00035 #include "socket_event_handler.h"
00036 #ifndef WIN32
00037 #include <sys/socket.h>
00038 #include <sys/un.h>
00039 #endif
00040
00041 #ifndef UNIX_PATH_MAX
00042 #define UNIX_PATH_MAX 108
00043 #endif
00044
00046
00047
00048 CL_PipeListen::CL_PipeListen(const CL_String &name)
00049 : accept_event(0), socket_event_handler(0), handle(-1)
00050 {
00051 #ifdef WIN32
00052 #else
00053 CL_StringA name_local8 = CL_StringHelp::text_to_local8(name);
00054 if (name_local8.length() >= UNIX_PATH_MAX)
00055 throw CL_Exception(TEXT("Pipe name too long!"));
00056
00057 handle = socket(PF_UNIX, SOCK_STREAM, 0);
00058 if (handle == -1)
00059 throw CL_Exception(TEXT("Unable to create unix socket"));
00060
00061
00062
00063
00064 sockaddr_un addr;
00065 memset(&addr, 0, sizeof(sockaddr_un));
00066 addr.sun_family = AF_UNIX;
00067 memcpy(addr.sun_path+1, name_local8.data(), name_local8.length());
00068
00069 int result = bind(handle, (sockaddr *) &addr, sizeof(sockaddr_un));
00070 if (result != -1)
00071 result = listen(handle, 5);
00072 if (result == -1)
00073 {
00074 ::close(handle);
00075 throw CL_Exception(TEXT("Unable to bind pipe to ") + name);
00076 }
00077
00078 socket_event_handler = new CL_SocketEventHandler(handle);
00079 accept_event = new CL_Event(socket_event_handler, CL_Event::type_socket_read);
00080 #endif
00081 }
00082
00083 CL_PipeListen::~CL_PipeListen()
00084 {
00085 delete accept_event;
00086 delete socket_event_handler;
00087 #ifdef WIN32
00088 #else
00089 if (handle != -1)
00090 ::close(handle);
00091 #endif
00092 }
00093
00095
00096
00097 CL_Event *CL_PipeListen::get_accept_event()
00098 {
00099 return accept_event;
00100 }
00101
00103
00104
00105 CL_PipeConnection *CL_PipeListen::accept(bool send_credentials, int timeout)
00106 {
00107 #ifdef WIN32
00108 return 0;
00109 #else
00110
00111
00112
00113 sockaddr_un name;
00114 memset(&name, 0, sizeof(sockaddr_un));
00115 name.sun_family = AF_UNIX;
00116
00117 socklen_t size = sizeof(sockaddr_un);
00118 int sock = ::accept(handle, (sockaddr *) &name, &size);
00119 if (sock == -1)
00120 return 0;
00121
00122 return new CL_PipeConnection(sock, send_credentials);
00123 #endif
00124 }
00125
00127