/src/libzmq/src/ipc_address.cpp
Line | Count | Source |
1 | | /* SPDX-License-Identifier: MPL-2.0 */ |
2 | | |
3 | | #include "precompiled.hpp" |
4 | | #include "compat.hpp" |
5 | | #include "ipc_address.hpp" |
6 | | |
7 | | #if defined ZMQ_HAVE_IPC |
8 | | |
9 | | #include "err.hpp" |
10 | | |
11 | | #include <string> |
12 | | |
13 | | zmq::ipc_address_t::ipc_address_t () |
14 | 66 | { |
15 | 66 | memset (&_address, 0, sizeof _address); |
16 | 66 | } |
17 | | |
18 | | zmq::ipc_address_t::ipc_address_t (const sockaddr *sa_, socklen_t sa_len_) : |
19 | 0 | _addrlen (sa_len_) |
20 | 0 | { |
21 | 0 | zmq_assert (sa_ && sa_len_ > 0); |
22 | |
|
23 | 0 | memset (&_address, 0, sizeof _address); |
24 | 0 | if (sa_->sa_family == AF_UNIX) |
25 | 0 | memcpy (&_address, sa_, sa_len_); |
26 | 0 | } |
27 | | |
28 | | zmq::ipc_address_t::~ipc_address_t () |
29 | 66 | { |
30 | 66 | } |
31 | | |
32 | | int zmq::ipc_address_t::resolve (const char *path_) |
33 | 66 | { |
34 | 66 | const size_t path_len = strlen (path_); |
35 | 66 | if (path_len >= sizeof _address.sun_path) { |
36 | 10 | errno = ENAMETOOLONG; |
37 | 10 | return -1; |
38 | 10 | } |
39 | 56 | if (path_[0] == '@' && !path_[1]) { |
40 | 1 | errno = EINVAL; |
41 | 1 | return -1; |
42 | 1 | } |
43 | | |
44 | 55 | _address.sun_family = AF_UNIX; |
45 | 55 | memcpy (_address.sun_path, path_, path_len + 1); |
46 | | /* Abstract sockets start with '\0' */ |
47 | 55 | if (path_[0] == '@') |
48 | 12 | *_address.sun_path = '\0'; |
49 | | |
50 | 55 | _addrlen = |
51 | 55 | static_cast<socklen_t> (offsetof (sockaddr_un, sun_path) + path_len); |
52 | 55 | return 0; |
53 | 56 | } |
54 | | |
55 | | int zmq::ipc_address_t::to_string (std::string &addr_) const |
56 | 110 | { |
57 | 110 | if (_address.sun_family != AF_UNIX) { |
58 | 0 | addr_.clear (); |
59 | 0 | return -1; |
60 | 0 | } |
61 | | |
62 | 110 | const char prefix[] = "ipc://"; |
63 | 110 | char buf[sizeof prefix + sizeof _address.sun_path]; |
64 | 110 | char *pos = buf; |
65 | 110 | memcpy (pos, prefix, sizeof prefix - 1); |
66 | 110 | pos += sizeof prefix - 1; |
67 | 110 | const char *src_pos = _address.sun_path; |
68 | 110 | if (!_address.sun_path[0] && _address.sun_path[1]) { |
69 | 24 | *pos++ = '@'; |
70 | 24 | src_pos++; |
71 | 24 | } |
72 | | // according to http://man7.org/linux/man-pages/man7/unix.7.html, NOTES |
73 | | // section, address.sun_path might not always be null-terminated; therefore, |
74 | | // we calculate the length based of addrlen |
75 | 110 | const size_t src_len = |
76 | 110 | strnlen (src_pos, _addrlen - offsetof (sockaddr_un, sun_path) |
77 | 110 | - (src_pos - _address.sun_path)); |
78 | 110 | memcpy (pos, src_pos, src_len); |
79 | 110 | addr_.assign (buf, pos - buf + src_len); |
80 | 110 | return 0; |
81 | 110 | } |
82 | | |
83 | | const sockaddr *zmq::ipc_address_t::addr () const |
84 | 55 | { |
85 | 55 | return reinterpret_cast<const sockaddr *> (&_address); |
86 | 55 | } |
87 | | |
88 | | socklen_t zmq::ipc_address_t::addrlen () const |
89 | 55 | { |
90 | 55 | return _addrlen; |
91 | 55 | } |
92 | | |
93 | | #endif |