1 #pragma once
2
3 /* NOTE: IIRC, wak@ is working on exposing some of this in stdplus, so we can
4 * transition when that's ready.
5 *
6 * Copied some from gpioplus to enable unit-testing of lpc nuvoton and later
7 * other pieces.
8 */
9
10 #include <netdb.h>
11 #include <poll.h>
12 #include <sys/mman.h>
13 #include <sys/socket.h>
14 #include <sys/types.h>
15
16 #include <cinttypes>
17 #include <cstddef>
18 #include <cstdint>
19 #include <system_error>
20
21 namespace internal
22 {
23
24 /**
25 * @class Sys
26 * @brief Overridable direct syscall interface
27 */
28 class Sys
29 {
30 public:
31 virtual ~Sys() = default;
32
33 virtual int open(const char* pathname, int flags) const = 0;
34 virtual int read(int fd, void* buf, std::size_t count) const = 0;
35 virtual int pread(int fd, void* buf, std::size_t count,
36 off_t offset) const = 0;
37 virtual int pwrite(int fd, const void* buf, std::size_t count,
38 off_t offset) const = 0;
39 virtual int close(int fd) const = 0;
40 virtual void* mmap(void* addr, std::size_t length, int prot, int flags,
41 int fd, off_t offset) const = 0;
42 virtual int munmap(void* addr, std::size_t length) const = 0;
43 virtual int getpagesize() const = 0;
44 virtual int ioctl(int fd, unsigned long request, void* param) const = 0;
45 virtual int poll(struct pollfd* fds, nfds_t nfds, int timeout) const = 0;
46 virtual int socket(int domain, int type, int protocol) const = 0;
47 virtual int connect(int sockfd, const struct sockaddr* addr,
48 socklen_t addrlen) const = 0;
49 virtual ssize_t send(int sockfd, const void* buf, size_t len,
50 int flags) const = 0;
51 virtual ssize_t sendfile(int out_fd, int in_fd, off_t* offset,
52 size_t count) const = 0;
53 virtual int getaddrinfo(const char* node, const char* service,
54 const struct addrinfo* hints,
55 struct addrinfo** res) const = 0;
56 virtual void freeaddrinfo(struct addrinfo* res) const = 0;
57 virtual std::int64_t getSize(const char* pathname) const = 0;
58 };
59
60 /**
61 * @class SysImpl
62 * @brief syscall concrete implementation
63 * @details Passes through all calls to the normal linux syscalls
64 */
65 class SysImpl : public Sys
66 {
67 public:
68 int open(const char* pathname, int flags) const override;
69 int read(int fd, void* buf, std::size_t count) const override;
70 int pread(int fd, void* buf, std::size_t count,
71 off_t offset) const override;
72 int pwrite(int fd, const void* buf, std::size_t count,
73 off_t offset) const override;
74 int close(int fd) const override;
75 void* mmap(void* addr, std::size_t length, int prot, int flags, int fd,
76 off_t offset) const override;
77 int munmap(void* addr, std::size_t length) const override;
78 int getpagesize() const override;
79 int ioctl(int fd, unsigned long request, void* param) const override;
80 int poll(struct pollfd* fds, nfds_t nfds, int timeout) const override;
81 int socket(int domain, int type, int protocol) const override;
82 int connect(int sockfd, const struct sockaddr* addr,
83 socklen_t addrlen) const override;
84 ssize_t send(int sockfd, const void* buf, size_t len,
85 int flags) const override;
86 ssize_t sendfile(int out_fd, int in_fd, off_t* offset,
87 size_t count) const override;
88 int getaddrinfo(const char* node, const char* service,
89 const struct addrinfo* hints,
90 struct addrinfo** res) const override;
91 void freeaddrinfo(struct addrinfo* res) const override;
92 /* returns 0 on failure, or if the file is zero bytes. */
93 std::int64_t getSize(const char* pathname) const override;
94 };
95
errnoException(const std::string & message)96 inline std::system_error errnoException(const std::string& message)
97 {
98 return std::system_error(errno, std::generic_category(), message);
99 }
100
101 /** @brief Default instantiation of sys */
102 extern SysImpl sys_impl;
103
104 } // namespace internal
105