From e89ae88f3a975ebcc5af8b1d0621f80ba13cca46 Mon Sep 17 00:00:00 2001 From: "andrey.bychkov" Date: Wed, 5 Aug 2026 17:37:57 +0300 Subject: [PATCH] fix(PICAN): align socket handling with PIEthernet patterns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Sentinel: sock = 0 → sock = -1 (0 is stdin, valid fd) - openDevice(): close socket on ioctl/bind failure (resource leak) - openDevice(): set O_NONBLOCK via fcntl after socket() - openDevice(): check setsockopt() return value - closeDevice(): call shutdown() before close(), reset sock to -1 - readDevice() / writeDevice(): guard against sock == -1 - Add missing #include --- libs/main/io_devices/pican.cpp | 21 ++++++++++++++++++--- libs/main/io_devices/pican.h | 2 +- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/libs/main/io_devices/pican.cpp b/libs/main/io_devices/pican.cpp index 2d6fe04e..6d1e2295 100644 --- a/libs/main/io_devices/pican.cpp +++ b/libs/main/io_devices/pican.cpp @@ -24,6 +24,7 @@ # define PIP_CAN #endif #ifdef PIP_CAN +# include # include # include # include @@ -49,7 +50,7 @@ PICAN::PICAN(const PIString & path, PIIODevice::DeviceMode mode): PIIODevice(pat setThreadedReadBufferSize(256); setPath(path); can_id = 0; - sock = 0; + sock = -1; PRIVATE->event.create(); } @@ -67,19 +68,25 @@ bool PICAN::openDevice() { sock = socket(PF_CAN, SOCK_RAW, CAN_RAW); if (sock < 0) { piCoutObj << "Error! while opening socket"; + sock = -1; return false; } + fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK); ifreq ifr; strcpy(ifr.ifr_name, path().dataAscii()); piCout << "PICAN try to get interface index..."; if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) { piCoutObj << "Error! while determin the interface ioctl"; + ::close(sock); + sock = -1; return false; } struct timeval tv; tv.tv_sec = 1; tv.tv_usec = 0; - setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof tv); + if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof tv) < 0) { + piCoutObj << "Error! while setting socket receive timeout"; + } // bind socket to all CAN interface sockaddr_can addr; addr.can_family = AF_CAN; @@ -87,6 +94,8 @@ bool PICAN::openDevice() { piCout << "PICAN try to bind socket to interface" << ifr.ifr_ifindex; if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { piCoutObj << "Error! while binding socket"; + ::close(sock); + sock = -1; return false; } piCout << "PICAN Open OK!"; @@ -101,7 +110,11 @@ bool PICAN::openDevice() { bool PICAN::closeDevice() { #ifdef PIP_CAN interrupt(); - if (sock > 0) ::close(sock); + if (sock != -1) { + ::shutdown(sock, SHUT_RDWR); + ::close(sock); + sock = -1; + } #endif return true; } @@ -109,6 +122,7 @@ bool PICAN::closeDevice() { ssize_t PICAN::readDevice(void * read_to, ssize_t max_size) { #ifdef PIP_CAN + if (sock == -1) return -1; // piCout << "PICAN read"; can_frame frame; ssize_t ret = 0; @@ -127,6 +141,7 @@ ssize_t PICAN::readDevice(void * read_to, ssize_t max_size) { ssize_t PICAN::writeDevice(const void * data, ssize_t max_size) { #ifdef PIP_CAN + if (sock == -1) return -1; // piCout << "PICAN write" << can_id << max_size; if (max_size > 8) { piCoutObj << "Can't send CAN frame bigger than 8 bytes (requested " << max_size << ")!"; diff --git a/libs/main/io_devices/pican.h b/libs/main/io_devices/pican.h index 93bef921..37938818 100644 --- a/libs/main/io_devices/pican.h +++ b/libs/main/io_devices/pican.h @@ -73,7 +73,7 @@ protected: private: PRIVATE_DECLARATION(PIP_EXPORT) - int sock; + int sock = -1; int can_id, readed_id; };