1 /* 2 * Copyright (c) 2021 Apple Inc. All rights reserved. 3 */ 4 5 #include <stdio.h> 6 #include <sys/socket.h> 7 #include <sys/resource.h> 8 #include <errno.h> 9 10 #include <darwintest.h> 11 #include <darwintest_utils.h> 12 13 #define SCM_RIGHTS 0x01 14 15 T_DECL(scm_rights_control_msg, "Test the fd alloc failure behavior with SCM_RIGHTS control msg") 16 { 17 T_SETUPBEGIN; 18 int res, sock[2]; 19 20 int fd = open("/dev/null", O_RDWR); 21 T_ASSERT_POSIX_SUCCESS(fd, "open(/dev/null)"); 22 23 struct rlimit rlim = { 6, 6 }; 24 setrlimit(RLIMIT_NOFILE, &rlim); 25 26 res = socketpair(AF_UNIX, SOCK_STREAM, 0, sock); 27 T_QUIET; T_ASSERT_TRUE(sock[0] >= 0, "failed to create socket"); 28 29 struct iovec iovec[1]; 30 struct msghdr msg = {0}; 31 struct cmsghdr *cmsghdr; 32 char buf[CMSG_SPACE(sizeof(int))]; 33 34 iovec[0].iov_base = ""; 35 iovec[0].iov_len = 1; 36 37 msg.msg_iov = iovec; 38 msg.msg_iovlen = 1; 39 msg.msg_control = buf; 40 msg.msg_controllen = CMSG_SPACE(sizeof(int)); 41 42 cmsghdr = CMSG_FIRSTHDR(&msg); 43 cmsghdr->cmsg_len = CMSG_LEN(sizeof(int)); 44 cmsghdr->cmsg_level = SOL_SOCKET; 45 cmsghdr->cmsg_type = SCM_RIGHTS; 46 memcpy(CMSG_DATA(cmsghdr), &fd, sizeof(fd)); 47 48 T_SETUPEND; 49 50 sendmsg(sock[1], &msg, 0); 51 52 u_char c; 53 struct iovec riovec[1]; 54 struct msghdr rmsg = { 0, }; 55 char rbuf[CMSG_SPACE(sizeof(int))]; 56 57 riovec[0].iov_base = &c; 58 riovec[0].iov_len = 1; 59 60 rmsg.msg_iov = riovec; 61 rmsg.msg_iovlen = 1; 62 rmsg.msg_control = rbuf; 63 rmsg.msg_controllen = CMSG_SPACE(sizeof(int)); 64 65 ssize_t ret = recvmsg(sock[0], &rmsg, 0); 66 T_ASSERT_TRUE(ret == -1, "recvmsg should fail"); 67 T_ASSERT_TRUE(errno == 24, "the fail code is EMFILE"); 68 69 close(fd); 70 close(sock[0]); 71 close(sock[1]); 72 } 73