/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtNetwork module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or (at your option) the GNU General ** Public license version 3 or any later version approved by the KDE Free ** Qt Foundation. The licenses are as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QNET_UNIX_P_H #define QNET_UNIX_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience // of Qt code on Unix. This header file may change from version to // version to version without notice, or even be removed. // // We mean it. // #include #include "private/qcore_unix_p.h" #include #include #include #if defined(Q_OS_VXWORKS) # include #endif // for inet_addr #include #include #if defined(Q_OS_VXWORKS) # include #else # include #endif QT_BEGIN_NAMESPACE // Almost always the same. If not, specify in qplatformdefs.h. #if !defined(QT_SOCKOPTLEN_T) # define QT_SOCKOPTLEN_T QT_SOCKLEN_T #endif static inline int qt_safe_socket(int domain, int type, int protocol, int flags = 0) { Q_ASSERT((flags & ~O_NONBLOCK) == 0); int fd; #ifdef QT_THREADSAFE_CLOEXEC int newtype = type | SOCK_CLOEXEC; if (flags & O_NONBLOCK) newtype |= SOCK_NONBLOCK; fd = ::socket(domain, newtype, protocol); return fd; #else fd = ::socket(domain, type, protocol); if (fd == -1) return -1; ::fcntl(fd, F_SETFD, FD_CLOEXEC); // set non-block too? if (flags & O_NONBLOCK) ::fcntl(fd, F_SETFL, ::fcntl(fd, F_GETFL) | O_NONBLOCK); return fd; #endif } static inline int qt_safe_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *addrlen, int flags = 0) { Q_ASSERT((flags & ~O_NONBLOCK) == 0); int fd; #ifdef QT_THREADSAFE_CLOEXEC // use accept4 int sockflags = SOCK_CLOEXEC; if (flags & O_NONBLOCK) sockflags |= SOCK_NONBLOCK; # if defined(Q_OS_NETBSD) fd = ::paccept(s, addr, static_cast(addrlen), NULL, sockflags); # else fd = ::accept4(s, addr, static_cast(addrlen), sockflags); # endif return fd; #else fd = ::accept(s, addr, static_cast(addrlen)); if (fd == -1) return -1; ::fcntl(fd, F_SETFD, FD_CLOEXEC); // set non-block too? if (flags & O_NONBLOCK) ::fcntl(fd, F_SETFL, ::fcntl(fd, F_GETFL) | O_NONBLOCK); return fd; #endif } static inline int qt_safe_listen(int s, int backlog) { return ::listen(s, backlog); } static inline int qt_safe_connect(int sockfd, const struct sockaddr *addr, QT_SOCKLEN_T addrlen) { int ret; // Solaris e.g. expects a non-const 2nd parameter EINTR_LOOP(ret, QT_SOCKET_CONNECT(sockfd, const_cast(addr), addrlen)); return ret; } #undef QT_SOCKET_CONNECT #define QT_SOCKET_CONNECT qt_safe_connect #if defined(socket) # undef socket #endif #if defined(accept) # undef accept #endif #if defined(listen) # undef listen #endif // VxWorks' headers specify 'int' instead of '...' for the 3rd ioctl() parameter. template static inline int qt_safe_ioctl(int sockfd, unsigned long request, T arg) { #ifdef Q_OS_VXWORKS return ::ioctl(sockfd, request, (int) arg); #else return ::ioctl(sockfd, request, arg); #endif } static inline int qt_safe_sendmsg(int sockfd, const struct msghdr *msg, int flags) { #ifdef MSG_NOSIGNAL flags |= MSG_NOSIGNAL; #else qt_ignore_sigpipe(); #endif int ret; EINTR_LOOP(ret, ::sendmsg(sockfd, msg, flags)); return ret; } static inline int qt_safe_recvmsg(int sockfd, struct msghdr *msg, int flags) { int ret; EINTR_LOOP(ret, ::recvmsg(sockfd, msg, flags)); return ret; } QT_END_NAMESPACE #endif // QNET_UNIX_P_H