libcsdbg  1.28
C++ exception (and generic) stack trace debug library
tcpsockbuf.cpp
Go to the documentation of this file.
1 #include "../include/tcpsockbuf.hpp"
2 #include "../include/util.hpp"
3 #if !defined CSDBG_WITH_PLUGIN && !defined CSDBG_WITH_HIGHLIGHT
4 #include "../include/exception.hpp"
5 #endif
6 
13 namespace csdbg {
14 
24 tcpsockbuf::tcpsockbuf(const i8 *addr, i32 port)
25 try:
26 streambuf(),
27 m_address(NULL),
28 m_port(port)
29 {
30  if ( unlikely(addr == NULL || strlen(addr) == 0) )
31  addr = "127.0.0.1";
32 
33  m_address = new i8[strlen(addr) + 1];
34  strcpy(m_address, addr);
35 }
36 
37 catch (...) {
38  delete[] m_data;
39  m_data = NULL;
40  m_address = NULL;
41 }
42 
43 
53 try:
54 streambuf(src),
55 m_address(NULL),
56 m_port(src.m_port)
57 {
58  m_address = new i8[strlen(src.m_address) + 1];
59  strcpy(m_address, src.m_address);
60 }
61 
62 catch (...) {
63  close();
64 
65  delete[] m_data;
66  m_data = NULL;
67  m_address = NULL;
68 }
69 
70 
75 {
76  delete[] m_address;
77  m_address = NULL;
78 }
79 
80 
90 {
91  return new tcpsockbuf(*this);
92 }
93 
94 
100 inline const i8* tcpsockbuf::address() const
101 {
102  return m_address;
103 }
104 
105 
111 inline i32 tcpsockbuf::port() const
112 {
113  return m_port;
114 }
115 
116 
122 inline bool tcpsockbuf::is_connected() const
123 {
124  return m_handle >= 0;
125 }
126 
127 
139 {
140  if ( unlikely(this == &rval) )
141  return *this;
142 
143  /* Copy the buffer and duplicate the stream descriptor */
144  streambuf::operator=(rval);
145 
146  u32 len = strlen(rval.m_address);
147  if (len > strlen(m_address)) {
148  delete[] m_address;
149  m_address = NULL;
150  m_address = new i8[len + 1];
151  }
152 
153  strcpy(m_address, rval.m_address);
154  m_port = rval.m_port;
155  return *this;
156 }
157 
158 
171 {
172  if ( unlikely(m_handle >= 0) )
173  close();
174 
175  /* Create the stream socket */
176  m_handle = socket(AF_INET, SOCK_STREAM, 0);
177  if ( unlikely(m_handle < 0) )
178  throw exception(
179  "failed to create stream socket (errno %d - %s)",
180  errno,
181  strerror(errno)
182  );
183 
184  tcp_addr_t addr;
185  util::memset(&addr, 0, sizeof(tcp_addr_t));
186  addr.sin_family = AF_INET;
187  addr.sin_port = htons(m_port);
188  addr.sin_addr.s_addr = inet_addr(m_address);
189 
190  /* Connect the socket to its peer */
191  ip_addr_t *ip = reinterpret_cast<ip_addr_t*> (&addr);
192  i32 retval;
193  do {
194  retval = connect(m_handle, ip, sizeof(tcp_addr_t));
195  }
196  while ( unlikely(retval < 0 && errno == EINTR) );
197 
198  if ( unlikely(retval < 0) ) {
199  close();
200  throw exception(
201  "failed to connect TCP/IP socket @ %s:%d (errno %d - %s)",
202  m_address,
203  m_port,
204  errno,
205  strerror(errno)
206  );
207  }
208 
209  return *this;
210 }
211 
212 
221 {
222  try {
224  return sync();
225  }
226 
227  catch (i32 err) {
228  throw exception(
229  "failed to send data @ %s:%d (errno %d - %s)",
230  m_address,
231  m_port,
232  err,
233  strerror(err)
234  );
235  }
236 }
237 
238 
245 {
246  return const_cast<tcpsockbuf&> (*this);
247 }
248 
249 
265 tcpsockbuf& tcpsockbuf::set_option(i32 nm, const void *val, u32 sz)
266 {
267  __D_ASSERT(val != NULL);
268  __D_ASSERT(sz > 0);
269  if ( unlikely(val == NULL || sz == 0) )
270  return *this;
271 
272  /* Flush the buffer to avoid data loss or data corruption */
273  flush();
274 
275  i32 retval = setsockopt(m_handle, SOL_SOCKET, nm, val, sz);
276  if ( unlikely(retval < 0) )
277  throw exception(
278  "failed to set socket option %d (errno %d - %s)",
279  nm,
280  errno,
281  strerror(errno)
282  );
283 
284  return *this;
285 }
286 
287 
300 {
301  if ( likely(m_handle >= 0) )
302  ::shutdown(m_handle, ch);
303 
304  return const_cast<tcpsockbuf&> (*this);
305 }
306 
307 }
308 
virtual streambuf & flush()=0
To be implemented.
Definition: streambuf.cpp:156
This abstract class is the base for all buffered output stream types (for files, sockets, serial interfaces e.t.c)
Definition: streambuf.hpp:37
static void * memset(void *, u8, u32)
Fill a memory block with a constant byte.
Definition: util.cpp:320
char i8
8-bit signed integer
Definition: config.hpp:72
i8 * m_address
Peer IP address (numerical, IPv4)
Definition: tcpsockbuf.hpp:40
i32 m_port
Peer TCP port.
Definition: tcpsockbuf.hpp:42
tcpsockbuf(const i8 *, i32=g_ldp_port)
Object constructor.
Definition: tcpsockbuf.cpp:24
i32 m_handle
Stream handle (descriptor)
Definition: streambuf.hpp:43
virtual ~tcpsockbuf()
Object destructor.
Definition: tcpsockbuf.cpp:74
#define likely(expr)
Offer a hint (positive) to the pipeline branch predictor.
Definition: config.hpp:344
virtual const i8 * address() const
Get the peer IP address.
Definition: tcpsockbuf.cpp:100
virtual tcpsockbuf & sync() const
Commit cached data to the network.
Definition: tcpsockbuf.cpp:244
virtual tcpsockbuf & open()
Connect the socket to its peer.
Definition: tcpsockbuf.cpp:170
struct sockaddr_in tcp_addr_t
TCP IPv4 address.
Definition: config.hpp:137
A buffered TCP/IP socket output stream.
Definition: tcpsockbuf.hpp:34
virtual streambuf & operator=(const streambuf &)
Assignment operator.
Definition: streambuf.cpp:96
virtual tcpsockbuf & shutdown(i32) const
Shutdown one or both socket channels.
Definition: tcpsockbuf.cpp:299
virtual bool is_connected() const
Check if the socket is connected to its peer.
Definition: tcpsockbuf.cpp:122
virtual tcpsockbuf & operator=(const tcpsockbuf &)
Assignment operator.
Definition: tcpsockbuf.cpp:138
virtual tcpsockbuf & set_option(i32, const void *, u32)
Set a socket option (applies only for the SOL_SOCKET ioctl level)
Definition: tcpsockbuf.cpp:265
unsigned int u32
32-bit unsigned integer
Definition: config.hpp:102
int i32
32-bit signed integer
Definition: config.hpp:82
virtual i32 port() const
Get the peer TCP port.
Definition: tcpsockbuf.cpp:111
This class is a throwable with a textual description of an error.
Definition: exception.hpp:26
virtual tcpsockbuf & flush()
Flush the buffered data to the socket.
Definition: tcpsockbuf.cpp:220
struct sockaddr ip_addr_t
IP address.
Definition: config.hpp:142
#define unlikely(expr)
Offer a hint (negative) to the pipeline branch predictor.
Definition: config.hpp:349
virtual streambuf & close()
Close the stream.
Definition: streambuf.cpp:130
#define __D_ASSERT(x)
Assertion macro.
Definition: config.hpp:268
virtual tcpsockbuf * clone() const
Object virtual copy constructor.
Definition: tcpsockbuf.cpp:89