File indexing completed on 2024-05-19 13:35:40
0001 /***************************************************************************** 0002 * Copyright 2014 - 2015 Yichao Yu <yyc1992@gmail.com> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify * 0005 * it under the terms of the GNU Lesser General Public License as * 0006 * published by the Free Software Foundation; either version 2.1 of the * 0007 * License, or (at your option) version 3, or any later version accepted * 0008 * by the membership of KDE e.V. (or its successor approved by the * 0009 * membership of KDE e.V.), which shall act as a proxy defined in * 0010 * Section 6 of version 3 of the license. * 0011 * * 0012 * This program is distributed in the hope that it will be useful, * 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 0015 * Lesser General Public License for more details. * 0016 * * 0017 * You should have received a copy of the GNU Lesser General Public * 0018 * License along with this library. If not, * 0019 * see <http://www.gnu.org/licenses/>. * 0020 *****************************************************************************/ 0021 0022 #include "fd_utils.h" 0023 #include <sys/socket.h> 0024 #include <fcntl.h> 0025 0026 QTC_EXPORT bool 0027 qtcSendFD(int sock, int fd) 0028 { 0029 QTC_RET_IF_FAIL(fd >= 0 && sock >= 0, false); 0030 char buf = 0; 0031 iovec iov; 0032 iov.iov_base = &buf; 0033 iov.iov_len = 1; 0034 union { 0035 struct cmsghdr cmsghdr; 0036 char control[CMSG_SPACE(sizeof(int))]; 0037 } cmsgu; 0038 memset(&cmsgu, 0, sizeof(cmsgu)); 0039 msghdr msg; 0040 msg.msg_iov = &iov; 0041 msg.msg_iovlen = 1; 0042 msg.msg_control = cmsgu.control; 0043 msg.msg_controllen = sizeof(cmsgu.control); 0044 cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); 0045 cmsg->cmsg_len = CMSG_LEN(sizeof(int)); 0046 cmsg->cmsg_level = SOL_SOCKET; 0047 cmsg->cmsg_type = SCM_RIGHTS; 0048 memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); 0049 return sendmsg(sock, &msg, 0) >= 0; 0050 } 0051 0052 QTC_EXPORT int 0053 qtcRecvFD(int sock) 0054 { 0055 QTC_RET_IF_FAIL(sock >= 0, -1); 0056 char buf = 0; 0057 iovec iov; 0058 iov.iov_base = &buf; 0059 iov.iov_len = 1; 0060 union { 0061 struct cmsghdr cmsghdr; 0062 char control[CMSG_SPACE(sizeof(int))]; 0063 } cmsgu; 0064 memset(&cmsgu, 0, sizeof(cmsgu)); 0065 msghdr msg; 0066 msg.msg_iov = &iov; 0067 msg.msg_iovlen = 1; 0068 msg.msg_control = cmsgu.control; 0069 msg.msg_controllen = sizeof(cmsgu.control); 0070 QTC_RET_IF_FAIL(recvmsg(sock, &msg, 0) >= 0, -1); 0071 struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); 0072 QTC_RET_IF_FAIL(cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(int)) && 0073 cmsg->cmsg_level == SOL_SOCKET && 0074 cmsg->cmsg_type == SCM_RIGHTS, -1); 0075 int fd; 0076 memcpy(&fd, CMSG_DATA(cmsg), sizeof(int)); 0077 return fd; 0078 } 0079 0080 QTC_EXPORT bool 0081 qtcFDSetCloexec(int fd, bool cloexec) 0082 { 0083 long flags; 0084 flags = fcntl(fd, F_GETFD, 0); 0085 if (flags == -1) { 0086 return false; 0087 } 0088 if (cloexec) { 0089 flags |= FD_CLOEXEC; 0090 } else { 0091 flags &= ~FD_CLOEXEC; 0092 } 0093 return fcntl(fd, F_SETFD, flags) != -1; 0094 } 0095 0096 QTC_EXPORT bool 0097 qtcFDSetNonBlock(int fd, bool nonblock) 0098 { 0099 long flags; 0100 flags = fcntl(fd, F_GETFL, 0); 0101 if (flags == -1) { 0102 return false; 0103 } 0104 if (nonblock) { 0105 nonblock |= O_NONBLOCK; 0106 } else { 0107 nonblock &= ~O_NONBLOCK; 0108 } 0109 return fcntl(fd, F_SETFL, flags) != -1; 0110 }