From 6232d13f5321b87ddf12a1aa36b4545da45f173d Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Wed, 17 Nov 2021 22:34:57 +0100 Subject: Travel3: Simple image and video display site Reads the images and videos from filesystem and builds a site in memroy. --- src/inet.cc | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/inet.cc (limited to 'src/inet.cc') diff --git a/src/inet.cc b/src/inet.cc new file mode 100644 index 0000000..1700a14 --- /dev/null +++ b/src/inet.cc @@ -0,0 +1,112 @@ +#include "common.hh" + +#include "inet.hh" +#include "io.hh" +#include "logger.hh" + +#include +#include +#include +#include +#include +#include +#include + +namespace inet { + +unique_fd accept(Logger* logger, int fd, bool make_nonblock) { +#if HAVE_ACCEPT4 + unique_fd ret(accept4(fd, nullptr, nullptr, + make_nonblock ? SOCK_NONBLOCK : 0)); + if (!ret) + logger->warn("accept: %s", strerror(errno)); + return ret; +#else + unique_fd ret(::accept(fd, nullptr, nullptr)); + if (ret) { + if (make_nonblock && !io::make_nonblocking(ret.get())) { + logger->warn("make nonblock failed: %s", strerror(errno)); + ret.reset(); + } + } else { + logger->warn("accept: %s", strerror(errno)); + } + return ret; +#endif +} + +bool bind_and_listen(Logger* logger, + std::string const& addr, + std::string const& port, + std::vector* out) { + out->clear(); + struct addrinfo hints = {}; + struct addrinfo* ret; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_PASSIVE; + auto err = getaddrinfo(addr.empty() ? nullptr : addr.c_str(), + port.c_str(), &hints, &ret); + if (err) { + logger->warn("%s:%s: getaddrinfo: %s", + addr.c_str(), port.c_str(), gai_strerror(err)); + return false; + } + + for (auto* rp = ret; rp != nullptr; rp = rp->ai_next) { + unique_fd fd(socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)); + if (!fd) + continue; + + if (bind(fd.get(), rp->ai_addr, rp->ai_addrlen)) { + logger->warn("%s:%s: bind: %s", + addr.c_str(), port.c_str(), strerror(errno)); + continue; + } + + if (listen(fd.get(), 4096)) { + logger->warn("%s:%s: listen: %s", + addr.c_str(), port.c_str(), strerror(errno)); + continue; + } + + out->emplace_back(std::move(fd)); + } + freeaddrinfo(ret); + return !out->empty(); +} + +} // namespace inet + +namespace unix { + +unique_fd bind_and_listen(Logger* logger, + std::string_view path) { + unique_fd fd(socket(AF_UNIX, SOCK_STREAM, 0)); + if (fd) { + sockaddr_un addr; + if (path.size() >= sizeof(addr.sun_path)) { + logger->warn("%.*s: Too long path", + static_cast(path.size()), path.data()); + return unique_fd(); + } + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + std::copy_n(path.data(), path.size(), addr.sun_path); + addr.sun_path[path.size()] = '\0'; + if (bind(fd.get(), reinterpret_cast(&addr), + sizeof(addr))) { + logger->warn("%.*s: bind: %s", + static_cast(path.size()), path.data(), strerror(errno)); + return unique_fd(); + } + if (listen(fd.get(), 4096)) { + logger->warn("%.*s: listen: %s", + static_cast(path.size()), path.data(), strerror(errno)); + return unique_fd(); + } + } + return fd; +} + +} // namespace unix -- cgit v1.2.3-70-g09d2