libsocket
unixdgram.cpp
Go to the documentation of this file.
1 #include <string.h>
2 #include <unistd.h>
3 #include <string>
4 
5 #include <memory>
6 
7 /*
8  The committers of the libsocket project, all rights reserved
9  (c) 2012, dermesser <lbo@spheniscida.de>
10 
11  Redistribution and use in source and binary forms, with or without
12  modification, are permitted provided that the following conditions are met:
13 
14  1. Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  2. Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19 
20  THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS “AS IS” AND ANY
21  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
24  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 */
32 
43 #include <libunixsocket.h>
44 #include <exception.hpp>
45 #include <unixdgram.hpp>
46 
47 namespace libsocket {
59 ssize_t unix_dgram::sndto(const void* buf, size_t length, const char* path,
60  int sendto_flags) {
61  if (buf == NULL)
62  throw socket_exception(__FILE__, __LINE__,
63  "unix_dgram::sndto: Buffer is NULL!", false);
64 
65  ssize_t bytes;
66 
67  if (0 > (bytes = sendto_unix_dgram_socket(sfd, buf, length, path,
68  sendto_flags))) {
69  if (is_nonblocking && errno == EWOULDBLOCK)
70  return -1;
71  else
72  throw socket_exception(
73  __FILE__, __LINE__,
74  "unix_dgram::sndto: Could not send data to peer!");
75  }
76 
77  return bytes;
78 }
79 
91 ssize_t unix_dgram::sndto(const void* buf, size_t length, const string& path,
92  int sendto_flags) {
93  return sndto(buf, length, path.c_str(), sendto_flags);
94 }
95 
106 ssize_t unix_dgram::sndto(const string& buf, const string& path,
107  int sendto_flags) {
108  return sndto(static_cast<const void*>(buf.c_str()), buf.size(),
109  path.c_str(), sendto_flags);
110 }
111 
124 ssize_t unix_dgram::rcvfrom(void* buf, size_t length, char* source,
125  size_t source_len, int recvfrom_flags) {
126  if (buf == NULL)
127  throw socket_exception(__FILE__, __LINE__,
128  "unix_dgram::rcvfrom: Buffer is NULL!", false);
129 
130  ssize_t bytes;
131 
132  bytes = recvfrom_unix_dgram_socket(sfd, buf, length, source, source_len,
133  recvfrom_flags);
134 
135  if (bytes < 0) {
136  if (is_nonblocking && errno == EWOULDBLOCK)
137  return -1;
138  else
139  throw socket_exception(
140  __FILE__, __LINE__,
141  "unix_dgram::rcvfrom: Could not receive data from peer!");
142  }
143 
144  return bytes;
145 }
146 
159 ssize_t unix_dgram::rcvfrom(void* buf, size_t length, string& source,
160  int recvfrom_flags) {
161  if (buf == NULL)
162  throw socket_exception(__FILE__, __LINE__,
163  "unix_dgram::rcvfrom: Buffer is NULL!", false);
164 
165  ssize_t bytes;
166 
167  using std::unique_ptr;
168 
169  unique_ptr<char[]> source_cstr(
170  new char[108]); // AFAIK, the address field in struct sockaddr_un is
171  // only 108 bytes long...
172  size_t source_cstr_len;
173 
174  memset(source_cstr.get(), 0, 108);
175 
176  bytes = recvfrom_unix_dgram_socket(sfd, buf, length, source_cstr.get(), 107,
177  recvfrom_flags);
178 
179  if (bytes < 0) {
180  if (is_nonblocking && errno == EWOULDBLOCK)
181  return -1;
182  else
183  throw socket_exception(
184  __FILE__, __LINE__,
185  "unix_dgram::rcvfrom: Could not receive data from peer!");
186  }
187 
188  source_cstr_len = strlen(source_cstr.get());
189 
190  source.resize(source_cstr_len);
191 
192  source = source_cstr.get();
193 
194  return bytes;
195 }
196 
208 ssize_t unix_dgram::rcvfrom(string& buf, string& source, int recvfrom_flags) {
209  if (buf.empty())
210  throw socket_exception(__FILE__, __LINE__,
211  "unix_dgram::rcvfrom: Buffer is empty!", false);
212 
213  ssize_t bytes;
214 
215  using std::unique_ptr;
216 
217  unique_ptr<char[]> source_cstr(
218  new char[108]); // AFAIK, the address field in struct sockaddr_un is
219  // only 108 bytes...
220  unique_ptr<char[]> cbuf(new char[buf.size()]);
221 
222  size_t source_cstr_len;
223 
224  memset(source_cstr.get(), 0, 108);
225 
226  bytes = recvfrom_unix_dgram_socket(sfd, cbuf.get(), buf.size(),
227  source_cstr.get(), 107, recvfrom_flags);
228 
229  if (bytes < 0) {
230  if (is_nonblocking && errno == EWOULDBLOCK)
231  return -1;
232  else
233  throw socket_exception(
234  __FILE__, __LINE__,
235  "unix_dgram::rcvfrom: Could not receive data from peer!");
236  }
237 
238  source_cstr_len = strlen(source_cstr.get());
239 
240  source.resize(source_cstr_len);
241  buf.resize(bytes);
242 
243  buf.assign(cbuf.get(), bytes);
244  source.assign(source_cstr.get(), source_cstr_len);
245 
246  return bytes;
247 }
248 } // namespace libsocket
Contains libsocket elements.
Definition: dgramclient.hpp:41
ssize_t sndto(const void *buf, size_t length, const char *path, int sendto_flags=0)
Send data to datagram socket.
Definition: unixdgram.cpp:59
This class is instantiated and thrown when an error occurs. If there's an error somewhere in libsocke...
Definition: exception.hpp:52
ssize_t recvfrom_unix_dgram_socket(int sfd, void *buf, size_t size, char *from, size_t from_size, int recvfrom_flags)
Receive datagram from another UNIX socket.
int sfd
sfd is the sockets API file descriptor
Definition: socket.hpp:74
ssize_t sendto_unix_dgram_socket(int sfd, const void *buf, size_t size, const char *path, int sendto_flags)
Send datagram to socket.
ssize_t rcvfrom(void *buf, size_t length, char *source, size_t source_len, int recvfrom_flags=0)
Receive data and store the sender's address.
Definition: unixdgram.cpp:124