1 #include <l4/l4re_vfs/vfs.h>
2 #include <l4/l4re_vfs/backend>
3 #include <l4/util/util.h>
4 #include <l4/sys/kdebug.h>
5 #include <l4/cxx/ref_ptr>
10 #include "lwip/sockets.h"
14 * lwIP file backend for integrating lwIP sockets into L4Re VFS
16 * lwip maintains its own internal socket numbers and clients expect these to
17 * be normal file descriptors from which to read/write. L4Re's VFS however has
18 * a different view on fds and so we need an indirection that translates
19 * between VFS fds and lwIP socket IDs. This translation is used by the BSD
20 * socket API wrappers in this library to convert between these two
23 * Every time a client application creates a socket using the socket() wrapper
24 * in this library, we register a new Socket_file with VFS. This allows us to
25 * intercept readv/writev calls to this fd and map them to lwip_read(),
28 class Socket_file : public L4Re::Vfs::Be_file
31 int _lwip_fd; // underlying lwIP file descriptor
32 bool _connected; // socket connected?
35 /* _connected is initially false, as we cannot read/write
36 * from a socket until it has been connected/bound
38 explicit Socket_file(int lwip_fd = -1) throw()
39 : L4Re::Vfs::Be_file(),
45 ~Socket_file() throw()
51 bool connected() { return _connected; }
52 void connected(bool t) { _connected = t; }
54 int lwip_fd() { return _lwip_fd; }
56 ssize_t readv(const struct iovec*, int) throw();
57 ssize_t writev(const struct iovec*, int) throw();
59 // should be in L4Re::Vfs::Be_file ?
60 int fstat64(struct stat64 *) const throw()
65 ssize_t Socket_file::readv(const struct iovec* iov,
75 for (int i = 0; i < iov_cnt; ++i)
76 read_cnt += lwip_read(_lwip_fd, iov[i].iov_base,
83 ssize_t Socket_file::writev(const struct iovec* iov,
86 ssize_t write_cnt = 0;
93 for (int i = 0; i < iov_cnt; ++i)
94 write_cnt += lwip_write(_lwip_fd, iov[i].iov_base,
101 EXTERN_C int assign_fd_to_socket(int sockfd)
105 Ref_ptr<Socket_file> f(new Socket_file(sockfd));
106 int vfs_fd = L4Re::Vfs::vfs_ops->alloc_fd(f);
112 EXTERN_C int socket_for_fd(int sock)
116 // XXX: why doesn't ref_ptr_static_cast() work?
117 Ref_ptr<L4Re::Vfs::File> vf = L4Re::Vfs::vfs_ops->get_file(sock);
118 Ref_ptr<Socket_file> f = ref_ptr(static_cast<Socket_file*>(vf.ptr()));
123 EXTERN_C void mark_connected(int sock, int val)
126 Ref_ptr<L4Re::Vfs::File> vf = L4Re::Vfs::vfs_ops->get_file(sock);
127 Ref_ptr<Socket_file> f = ref_ptr(static_cast<Socket_file*>(vf.ptr()));
128 f->connected(val == 1);