Comm::TcpAcceptor::oldAccept(Comm::ConnectionPointer &details)
{
++statCounter.syscalls.sock.accepts;
- int sock;
struct addrinfo *gai = nullptr;
Ip::Address::InitAddr(gai);
errcode = 0; // reset local errno copy.
- if ((sock = accept(conn->fd, gai->ai_addr, &gai->ai_addrlen)) < 0) {
+ const auto rawSock = accept(conn->fd, gai->ai_addr, &gai->ai_addrlen);
+ if (rawSock < 0) {
errcode = errno; // store last accept errno locally.
Ip::Address::FreeAddr(gai);
}
}
- Must(sock >= 0);
++incoming_sockets_accepted;
// Sync with Comm ASAP so that abandoned details can properly close().
// XXX : these are not all HTTP requests. use a note about type and ip:port details->
// so we end up with a uniform "(HTTP|FTP-data|HTTPS|...) remote-ip:remote-port"
- fd_open(sock, FD_SOCKET, "HTTP Request");
- details->fd = sock;
- details->enterOrphanage();
+ Descriptor sock(rawSock, FD_SOCKET, "HTTP Request");
details->remote = *gai;
/* IFF the socket is (tproxy) transparent, pass the flag down to allow spoofing */
F->flags.transparent = fd_table[conn->fd].flags.transparent; // XXX: can we remove this line yet?
+ details->fd = sock.release();
+ details->enterOrphanage();
return Comm::OK;
}
#include "comm/Loops.h"
#include "debug/Messages.h"
#include "debug/Stream.h"
+#include "error/SysErrorDetail.h"
#include "fatal.h"
#include "fd.h"
#include "fde.h"
RESERVED_FD = newReserve;
}
+/* Comm::Descriptor */
+
+Comm::Descriptor::Descriptor(const int fd, const unsigned int type, const char * const description): fd_(fd)
+{
+ fd_open(fd_, type, description);
+}
+
+Comm::Descriptor::~Descriptor()
+{
+ if (fd_ >= 0) {
+ fd_close(fd_);
+ if (close(fd_) != 0) {
+ const auto savedErrno = errno;
+ debugs(51, 7, "failed to close FD " << fd_ << ReportSysError(savedErrno));
+ }
+ }
+}
+
#ifndef SQUID_FD_H_
#define SQUID_FD_H_
+namespace Comm {
+
+/// An open Comm-registered file descriptor guard that, upon creation, registers
+/// the descriptor with Comm and, upon destruction, unregisters and closes the
+/// descriptor (unless the descriptor has been release()d by then).
+class Descriptor
+{
+public:
+ /// Starts owning the given FD of a given type, with a given description.
+ /// Assumes the given descriptor is open and calls legacy fd_open().
+ Descriptor(int fd, unsigned int type, const char *description);
+ Descriptor(Descriptor &&) = delete; // no copying (and, for now, moving) of any kind
+
+ /// Closes and calls legacy fd_close() unless release() was called earlier.
+ ~Descriptor();
+
+ /// A copy of the descriptor for use in system calls and such.
+ operator int() const { return fd_; }
+
+ /// Forgets the descriptor and prevents its automatic closure (by us).
+ int release() { const auto result = fd_; fd_ = -1; return result; }
+
+private:
+ int fd_;
+};
+
+} // namespace Comm
+
void fd_close(int fd);
void fd_open(int fd, unsigned int type, const char *);
void fd_note(int fd, const char *);