VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
glocalsocket.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // glocalsocket.cpp
19 //
20 
21 #include "gdef.h"
22 #include "glocalsocket.h"
23 #include "gprocess.h"
24 #include "gstr.h"
25 #include "gassert.h"
26 #include <stdexcept>
27 #include <unistd.h>
28 #include <fcntl.h>
29 
31 {
32  m_u.specific.sun_family = AF_LOCAL ; // ie. AF_UNIX
33  ::memset( m_u.specific.sun_path , 0 , sizeof(m_u.specific.sun_path) ) ;
34  std::strncpy( m_u.specific.sun_path , path , sizeof(m_u.specific.sun_path)-1U ) ;
35 }
36 
37 G::LocalSocketAddress::LocalSocketAddress( const std::string & path )
38 {
39  if( path.length() >= sizeof(m_u.specific.sun_path) )
40  throw std::runtime_error( "socket path too long" ) ;
41 
42  m_u.specific.sun_family = AF_LOCAL ; // ie. AF_UNIX
43  ::memset( m_u.specific.sun_path , 0 , sizeof(m_u.specific.sun_path) ) ;
44  std::strncpy( m_u.specific.sun_path , path.c_str() , sizeof(m_u.specific.sun_path)-1U ) ;
45 }
46 
47 struct sockaddr * G::LocalSocketAddress::p()
48 {
49  return &m_u.general ;
50 }
51 
52 const struct sockaddr * G::LocalSocketAddress::p() const
53 {
54  return &m_u.general ;
55 }
56 
58 {
59  return sizeof(m_u.specific) ;
60 }
61 
62 // ==
63 
64 G::LocalSocket::LocalSocket( bool datagram ) :
65  m_connected(false)
66 {
67  m_fd = ::socket( AF_LOCAL , datagram ? SOCK_DGRAM : SOCK_STREAM , 0 ) ;
68  int e = G::Process::errno_() ;
69  if( m_fd < 0 )
70  throw Error( "failed to create local socket" , G::Process::strerror(e) ) ;
71 }
72 
73 bool G::LocalSocket::connect( const std::string & path , bool no_throw )
74 {
75  Address address( path.c_str() ) ;
76  int rc = ::connect( m_fd , address.p() , address.size() ) ;
77  int e = G::Process::errno_() ;
78  if( rc != 0 && !no_throw )
79  throw Error( "failed to connect local socket" , path , G::Process::strerror(e) ) ;
80  m_connected = rc == 0 ;
81  return rc == 0 ;
82 }
83 
84 void G::LocalSocket::bind( const std::string & path )
85 {
86  G_ASSERT( !path.empty() ) ;
87  Address address( path.c_str() ) ;
88  int rc = ::bind( m_fd , address.p() , address.size() ) ;
89  if( rc != 0 )
90  {
91  int e = errno ;
92  throw Error( "failed to bind path to local socket" , G::Process::strerror(e) , path ) ;
93  }
94 }
95 
97 {
98  ::close( m_fd ) ;
99 }
100 
102 {
103  return m_connected ;
104 }
105 
107 {
108  return m_fd ;
109 }
110 
112 {
113  int flags = ::fcntl( m_fd , F_GETFL ) ;
114  if( flags != -1 )
115  ::fcntl( m_fd , F_SETFL , flags | O_NONBLOCK ) ;
116 }
117 
118 /// \file glocalsocket.cpp
LocalSocketAddress(const std::string &path)
Constructor.
An empty structure that is used to indicate a signal-safe, reentrant implementation.
Definition: gsignalsafe.h:36
int fd() const
Returns the socket's file descriptor.
void nonblock()
Makes the socket non-blocking.
LocalSocket(bool datagram)
Constructor for a datagram socket or a stream socket.
bool connect(const std::string &address_path, bool no_throw=false)
Connects to the given address.
~LocalSocket()
Destructor.
struct sockaddr * p()
Returns the sockaddr pointer.
bool connected() const
Returns true if the socket has been successfully connect()ed.
An address class for G::LocalSocket that works with file system paths.
Definition: glocalsocket.h:41
size_t size() const
Returns the sockaddr size.
void bind(const std::string &address_path)
Binds the given address to the socket. Throws Error on error.