Claw  1.7.3
socket_traits_unix.hpp
Go to the documentation of this file.
00001 /*
00002   CLAW - a C++ Library Absolutely Wonderful
00003 
00004   CLAW is a free library without any particular aim but being useful to 
00005   anyone.
00006 
00007   Copyright (C) 2005-2011 Julien Jorge
00008 
00009   This library is free software; you can redistribute it and/or
00010   modify it under the terms of the GNU Lesser General Public
00011   License as published by the Free Software Foundation; either
00012   version 2.1 of the License, or (at your option) any later version.
00013 
00014   This library is distributed in the hope that it will be useful,
00015   but WITHOUT ANY WARRANTY; without even the implied warranty of
00016   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017   Lesser General Public License for more details.
00018 
00019   You should have received a copy of the GNU Lesser General Public
00020   License along with this library; if not, write to the Free Software
00021   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00022 
00023   contact: julien.jorge@gamned.org
00024 */
00030 #ifndef __CLAW_SOCKET_TRAITS_UNIX_HPP__
00031 #define __CLAW_SOCKET_TRAITS_UNIX_HPP__
00032 
00033 #include <sys/types.h>
00034 #include <sys/socket.h>
00035 #include <sys/stat.h>
00036 #include <netinet/in.h>
00037 #include <netinet/tcp.h>
00038 #include <netdb.h>
00039 #include <unistd.h>
00040 #include <cstring>
00041 
00042 #include <claw/assert.hpp>
00043 
00044 namespace claw
00045 {
00050   class socket_traits_unix
00051   {
00052   public:
00054     typedef int descriptor;
00055 
00056   public:
00058     static const descriptor invalid_socket = -1;
00059 
00060   public:
00061     /*------------------------------------------------------------------------*/
00066     static bool init()
00067     {
00068       return true;
00069     } // socket_traits_unix::init()
00070 
00071     /*------------------------------------------------------------------------*/
00076     static bool release()
00077     {
00078       return true;
00079     } // socket_traits_unix::release()
00080 
00081     /*------------------------------------------------------------------------*/
00086     static descriptor open()
00087     {
00088       descriptor fd = invalid_socket;
00089 
00090       fd = socket(AF_INET, SOCK_STREAM, 0);
00091 
00092       return fd;
00093     } // socket_traits_unix::open()
00094 
00095     /*------------------------------------------------------------------------*/
00101     static bool close( descriptor d )
00102     {
00103       return ::close(d) == 0; 
00104     } // socket_traits_unix::close()
00105 
00106     /*------------------------------------------------------------------------*/
00114     static bool connect( descriptor d, const std::string& address, int port )
00115     {
00116       CLAW_PRECOND( d != invalid_socket );
00117 
00118       bool result = false;
00119       struct hostent* hp = gethostbyname(address.c_str());
00120 
00121       if (hp)
00122   {
00123     struct sockaddr_in sa;
00124 
00125     memset (&sa, '\0', sizeof(sa));
00126     sa.sin_family = hp->h_addrtype;
00127     sa.sin_port = htons(port);
00128     memcpy( &sa.sin_addr, hp->h_addr, hp->h_length );
00129       
00130     if (::connect(d, (struct sockaddr*)&sa, (socklen_t)sizeof(sa)) != -1)
00131       result = true;
00132   }
00133 
00134       return result;
00135     } // socket_traits_unix::connect()
00136 
00137     /*------------------------------------------------------------------------*/
00145     static bool listen( descriptor d, int port, unsigned int queue_size )
00146     {
00147       CLAW_PRECOND( d != invalid_socket );
00148 
00149       struct sockaddr_in addr;
00150       
00151       memset (&addr, '\0', sizeof(addr));
00152       addr.sin_family = AF_INET;
00153       addr.sin_port = htons(port);
00154       addr.sin_addr.s_addr = htonl(INADDR_ANY);
00155       
00156       if ( bind(d, (struct sockaddr*)&addr, sizeof(addr)) != -1 )
00157   return ::listen(d, queue_size) != -1;
00158       else
00159   return false;
00160     } // socket_traits_unix::listen()
00161 
00162     /*------------------------------------------------------------------------*/
00171     static bool select_read( descriptor d, int time_limit = -1 )
00172     {
00173       CLAW_PRECOND( d != invalid_socket );
00174 
00175       struct timeval tv, *ptv;
00176       fd_set fds;
00177 
00178       if ( time_limit < 0 )
00179         ptv = NULL;
00180       else
00181         {
00182           tv.tv_sec  = time_limit;
00183           tv.tv_usec = 0;
00184           
00185           ptv = &tv;
00186         }
00187 
00188       FD_ZERO(&fds);
00189       FD_SET(d, &fds);
00190 
00191       select( d+1, &fds, NULL, NULL, ptv );
00192 
00193       return FD_ISSET( d, &fds );
00194     } // socket_traits_unix::select_read()
00195 
00196     /*------------------------------------------------------------------------*/
00202     static descriptor accept( descriptor d )
00203     {
00204       return ::accept( d, NULL, NULL );
00205     } // socket_traits_unix::accept()
00206 
00207     /*------------------------------------------------------------------------*/
00212     static bool valid_descriptor( descriptor d )
00213     {
00214       return d != invalid_socket;
00215     } // socket_traits_unix::valid_descriptor()
00216 
00217     /*------------------------------------------------------------------------*/
00222     static bool is_open( descriptor d )
00223     {
00224       struct stat buf;
00225 
00226       return fstat(d, &buf) == 0;
00227     } // socket_traits_unix::is_open()
00228 
00229   }; // class socket_traits_unix
00230 
00231   typedef socket_traits_unix socket_traits;
00232 } // namespace claw
00233 
00234 #endif // __CLAW_SOCKET_TRAITS_UNIX_HPP__