diff --git a/src/posix/platform/misc.cpp b/src/posix/platform/misc.cpp index a5cd1da65..dab40916f 100644 --- a/src/posix/platform/misc.cpp +++ b/src/posix/platform/misc.cpp @@ -83,7 +83,7 @@ otPlatMcuPowerState otPlatGetMcuPowerState(otInstance *aInstance) return gPlatMcuPowerState; } -int SocketWithCloseExec(int aDomain, int aType, int aProtocol) +int SocketWithCloseExec(int aDomain, int aType, int aProtocol, SocketBlockOption aBlockOption) { int rval = 0; int fd = -1; @@ -92,13 +92,15 @@ int SocketWithCloseExec(int aDomain, int aType, int aProtocol) VerifyOrExit((fd = socket(aDomain, aType, aProtocol)) != -1, perror("socket(SOCK_CLOEXEC)")); VerifyOrExit((rval = fcntl(fd, F_GETFD, 0)) != -1, perror("fcntl(F_GETFD)")); - VerifyOrExit((rval = fcntl(fd, F_SETFD, rval | FD_CLOEXEC)) != -1, perror("fcntl(F_SETFD)")); + rval |= aBlockOption == kSocketNonBlock ? O_NONBLOCK | FD_CLOEXEC : FD_CLOEXEC; + VerifyOrExit((rval = fcntl(fd, F_SETFD, rval)) != -1, perror("fcntl(F_SETFD)")); #else - VerifyOrExit((fd = socket(aDomain, aType | SOCK_CLOEXEC, aProtocol)) != -1, perror("socket(SOCK_CLOEXEC)")); + aType |= aBlockOption == kSocketNonBlock ? SOCK_CLOEXEC | SOCK_NONBLOCK : SOCK_CLOEXEC; + VerifyOrExit((fd = socket(aDomain, aType, aProtocol)) != -1, perror("socket(SOCK_CLOEXEC)")); #endif exit: - if (rval == -1 && fd != -1) + if (rval == -1) { VerifyOrDie(close(fd) == 0, OT_EXIT_ERROR_ERRNO); fd = -1; diff --git a/src/posix/platform/netif.cpp b/src/posix/platform/netif.cpp index 8a75fa0c2..8032ad3f9 100644 --- a/src/posix/platform/netif.cpp +++ b/src/posix/platform/netif.cpp @@ -447,7 +447,7 @@ static void mldListenerInit(void) { struct ipv6_mreq mreq6; - sMLDMonitorFd = SocketWithCloseExec(AF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_ICMPV6); + sMLDMonitorFd = SocketWithCloseExec(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6, kSocketNonBlock); mreq6.ipv6mr_interface = sTunIndex; memcpy(&mreq6.ipv6mr_multiaddr, kMLDv2MulticastAddress.mFields.m8, sizeof(kMLDv2MulticastAddress.mFields.m8)); @@ -559,7 +559,7 @@ void platformNetifInit(otInstance *aInstance, const char *aInterfaceName) { struct ifreq ifr; - sIpFd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_IP); + sIpFd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_IP, kSocketNonBlock); VerifyOrDie(sIpFd >= 0, OT_EXIT_ERROR_ERRNO); sNetlinkFd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); @@ -576,7 +576,7 @@ void platformNetifInit(otInstance *aInstance, const char *aInterfaceName) VerifyOrDie(bind(sNetlinkFd, reinterpret_cast(&sa), sizeof(sa)) == 0, OT_EXIT_ERROR_ERRNO); } - sTunFd = open(OPENTHREAD_POSIX_TUN_DEVICE, O_RDWR | O_CLOEXEC); + sTunFd = open(OPENTHREAD_POSIX_TUN_DEVICE, O_RDWR | O_CLOEXEC | O_NONBLOCK); VerifyOrDie(sTunFd > 0, OT_EXIT_ERROR_ERRNO); memset(&ifr, 0, sizeof(ifr)); diff --git a/src/posix/platform/platform-posix.h b/src/posix/platform/platform-posix.h index 652c34a8c..397e7a164 100644 --- a/src/posix/platform/platform-posix.h +++ b/src/posix/platform/platform-posix.h @@ -428,19 +428,26 @@ void platformUdpProcess(otInstance *aInstance, const fd_set *aReadSet); */ void platformUdpUpdateFdSet(otInstance *aInstance, fd_set *aReadFdSet, int *aMaxFd); +enum SocketBlockOption +{ + kSocketBlock, + kSocketNonBlock, +}; + /** * This function creates a socket with SOCK_CLOEXEC flag set. * - * @param[in] aDomain The communication domain. - * @param[in] aType The semantics of communication. - * @param[in] aProtocol The protocol to use. + * @param[in] aDomain The communication domain. + * @param[in] aType The semantics of communication. + * @param[in] aProtocol The protocol to use. + * @param[in] aBlockOption Whether to add nonblock flags. * * @returns The file descriptor of the created socket. * * @retval -1 Failed to create socket. * */ -int SocketWithCloseExec(int aDomain, int aType, int aProtocol); +int SocketWithCloseExec(int aDomain, int aType, int aProtocol, SocketBlockOption aBlockOption); #ifdef __cplusplus } diff --git a/src/posix/platform/uart.cpp b/src/posix/platform/uart.cpp index c6be4c92a..0abacd37c 100644 --- a/src/posix/platform/uart.cpp +++ b/src/posix/platform/uart.cpp @@ -69,7 +69,7 @@ otError otPlatUartEnable(void) // This allows implementing pseudo reset. VerifyOrExit(sUartSocket == -1, OT_NOOP); - sUartSocket = SocketWithCloseExec(AF_UNIX, SOCK_STREAM, 0); + sUartSocket = SocketWithCloseExec(AF_UNIX, SOCK_STREAM, 0, kSocketNonBlock); if (sUartSocket == -1) { diff --git a/src/posix/platform/udp.cpp b/src/posix/platform/udp.cpp index 8af21b38c..ae2ee8cd8 100644 --- a/src/posix/platform/udp.cpp +++ b/src/posix/platform/udp.cpp @@ -219,7 +219,7 @@ otError otPlatUdpSocket(otUdpSocket *aUdpSocket) assert(aUdpSocket->mHandle == NULL); - fd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); + fd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, kSocketNonBlock); VerifyOrExit(fd >= 0, error = OT_ERROR_FAILED); aUdpSocket->mHandle = FdToHandle(fd); diff --git a/src/posix/platform/virtual_time.cpp b/src/posix/platform/virtual_time.cpp index 1b0ef2b24..bc6b2ec46 100644 --- a/src/posix/platform/virtual_time.cpp +++ b/src/posix/platform/virtual_time.cpp @@ -87,7 +87,7 @@ void virtualTimeInit(void) sockaddr.sin_port = htons(kBasePort + sPortOffset + sNodeId); sockaddr.sin_addr.s_addr = INADDR_ANY; - sSockFd = SocketWithCloseExec(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + sSockFd = SocketWithCloseExec(AF_INET, SOCK_DGRAM, IPPROTO_UDP, kSocketBlock); if (sSockFd == -1) {