ns-3 Direct Code Execution
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
linux-socket-fd.cc
Go to the documentation of this file.
1 #include "linux-socket-fd.h"
3 #include "utils.h"
4 #include "process.h"
5 #include "ns3/log.h"
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <sys/mman.h> // for MMAP_FAILED
9 #include <poll.h>
10 
11 NS_LOG_COMPONENT_DEFINE ("LinuxSocketFd");
12 
13 namespace ns3 {
14 
15 LinuxSocketFd::LinuxSocketFd (Ptr<LinuxSocketFdFactory> factory, struct SimSocket *socket)
16  : m_factory (factory),
17  m_socket (socket),
18  m_statusFlags (0),
19  m_kernelPollCtx (0)
20 {
21 }
22 
24 {
25 }
26 
27 int
29 {
30  return m_factory->Close (m_socket);
31 }
32 ssize_t
33 LinuxSocketFd::Write (const void *buf, size_t count)
34 {
35  NS_LOG_FUNCTION (this << buf << count);
36  struct msghdr msg;
37  struct iovec iov;
38  msg.msg_control = 0;
39  msg.msg_controllen = 0;
40  msg.msg_iovlen = 1;
41  msg.msg_iov = &iov;
42  iov.iov_len = count;
43  iov.iov_base = (void*)buf;
44  msg.msg_name = 0;
45  msg.msg_namelen = 0;
46  ssize_t retval = Sendmsg (&msg, 0);
47  return retval;
48 }
49 ssize_t
50 LinuxSocketFd::Read (void *buf, size_t count)
51 {
52  NS_LOG_FUNCTION (this << buf << count);
53  struct msghdr msg;
54  struct iovec iov;
55  msg.msg_control = 0;
56  msg.msg_controllen = 0;
57  msg.msg_iovlen = 1;
58  msg.msg_iov = &iov;
59  iov.iov_len = count;
60  iov.iov_base = buf;
61  msg.msg_name = 0;
62  msg.msg_namelen = 0;
63  ssize_t retval = Recvmsg (&msg, 0);
64  return retval;
65 }
66 ssize_t
67 LinuxSocketFd::Recvmsg (struct msghdr *msg, int flags)
68 {
69  bool nonBlocking = (m_statusFlags & O_NONBLOCK) == O_NONBLOCK;
70  flags |= nonBlocking ? MSG_DONTWAIT : 0;
71  return m_factory->Recvmsg (m_socket, msg, flags);
72 }
73 ssize_t
74 LinuxSocketFd::Sendmsg (const struct msghdr *msg, int flags)
75 {
76  bool nonBlocking = (m_statusFlags & O_NONBLOCK) == O_NONBLOCK;
77  flags |= nonBlocking ? MSG_DONTWAIT : 0;
78  return m_factory->Sendmsg (m_socket, msg, flags);
79 }
80 bool
82 {
83  return false;
84 }
85 int
86 LinuxSocketFd::Setsockopt (int level, int optname,
87  const void *optval, socklen_t optlen)
88 {
89  return m_factory->Setsockopt (m_socket, level, optname, optval, optlen);
90 }
91 int
92 LinuxSocketFd::Getsockopt (int level, int optname,
93  void *optval, socklen_t *optlen)
94 {
95  return m_factory->Getsockopt (m_socket, level, optname, optval, optlen);
96 }
97 int
98 LinuxSocketFd::Getsockname (struct sockaddr *name, socklen_t *namelen)
99 {
100  return m_factory->Getsockname (m_socket, name, namelen);
101 }
102 int
103 LinuxSocketFd::Getpeername (struct sockaddr *name, socklen_t *namelen)
104 {
105  return m_factory->Getpeername (m_socket, name, namelen);
106 }
107 int
108 LinuxSocketFd::Ioctl (int request, char *argp)
109 {
110  return m_factory->Ioctl (m_socket, request, argp);
111 }
112 int
113 LinuxSocketFd::Bind (const struct sockaddr *my_addr, socklen_t addrlen)
114 {
115  return m_factory->Bind (m_socket, my_addr, addrlen);
116 }
117 int
118 LinuxSocketFd::Connect (const struct sockaddr *my_addr, socklen_t addrlen)
119 {
120  return m_factory->Connect (m_socket, my_addr, addrlen, m_statusFlags);
121 }
122 int
124 {
125  return m_factory->Listen (m_socket, backlog);
126 }
127 int
129 {
130  return m_factory->Shutdown (m_socket, how);
131 }
132 int
133 LinuxSocketFd::Accept (struct sockaddr *my_addr, socklen_t *addrlen)
134 {
135  return m_factory->Accept (m_socket, my_addr, addrlen);
136 }
137 void *
138 LinuxSocketFd::Mmap (void *start, size_t length, int prot, int flags, off64_t offset)
139 {
140  GET_CURRENT (start << length << prot << flags << offset);
141  current->err = ENODEV;
142  return MAP_FAILED;
143 }
144 off64_t
145 LinuxSocketFd::Lseek (off64_t offset, int whence)
146 {
147  GET_CURRENT (offset << whence);
148  current->err = ESPIPE;
149  return -1;
150 }
151 int
152 LinuxSocketFd::Fxstat (int ver, struct ::stat *buf)
153 {
154  GET_CURRENT (ver << buf);
155  buf->st_mode = S_IFSOCK;
156  buf->st_dev = -1;
157  buf->st_blksize = 0;
158  return 0;
159 }
160 int
161 LinuxSocketFd::Fxstat64 (int ver, struct ::stat64 *buf)
162 {
163  GET_CURRENT (ver << buf);
164  buf->st_mode = S_IFSOCK;
165  buf->st_dev = -1;
166  buf->st_blksize = 0;
167  return 0;
168 }
169 int
170 LinuxSocketFd::Fcntl (int cmd, unsigned long arg)
171 {
172  switch (cmd)
173  {
174  case F_GETFL: //XXX this command should also consider the flags O_APPEND and O_ASYNC
175  return m_statusFlags;
176  break;
177  case F_SETFL:
178  m_statusFlags = arg;
179  return 0;
180  break;
181  default:
182  //XXX commands missing
183  NS_FATAL_ERROR ("fcntl not implemented on socket");
184  return -1;
185  }
186 }
187 int
189  const struct itimerspec *new_value,
190  struct itimerspec *old_value)
191 {
192  NS_LOG_FUNCTION (this << Current () << flags << new_value << old_value);
193  NS_ASSERT (Current () != 0);
194  Thread *current = Current ();
195  current->err = EINVAL;
196  return -1;
197 }
198 int
199 LinuxSocketFd::Gettime (struct itimerspec *cur_value) const
200 {
201  NS_LOG_FUNCTION (this << Current () << cur_value);
202  NS_ASSERT (Current () != 0);
203  Thread *current = Current ();
204  current->err = EINVAL;
205  return -1;
206 }
207 bool
209 {
210  // XXX: TO BE IMPLEMENTED OR NOT :)
211  return false;
212 }
213 int
215 {
216  return m_factory->Poll (m_socket, ptable);
217 }
218 int
220 {
221  NS_LOG_FUNCTION (this << Current ());
222  NS_ASSERT (Current () != 0);
223  Thread *current = Current ();
224  current->err = EINVAL;
225  return -1;
226 }
227 } // namespace ns3