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

pipe_listen.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_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 // CL_PipeListen Construction:
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         // Create pipe name in the abstract namespace:
00062         // (abstract namespace starts with first character in sun_path 
00063         // being the null character)
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 // CL_PipeListen Attributes:
00096 
00097 CL_Event *CL_PipeListen::get_accept_event()
00098 {
00099         return accept_event;
00100 }
00101 
00103 // CL_PipeListen Operations:
00104 
00105 CL_PipeConnection *CL_PipeListen::accept(bool send_credentials, int timeout)
00106 {
00107 #ifdef WIN32
00108         return 0;
00109 #else
00110         // EAGAIN
00111         // O_NONBLOCK
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 // CL_PipeListen Implementation:

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