git: 48a55bbfe95b - main - unix: change error code for recvmsg() failed due to RLIMIT_NOFILE
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 29 Jun 2022 16:43:14 UTC
The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=48a55bbfe95bc7b32d37673839edc2f365ffc028 commit 48a55bbfe95bc7b32d37673839edc2f365ffc028 Author: Gleb Smirnoff <glebius@FreeBSD.org> AuthorDate: 2022-06-29 16:42:58 +0000 Commit: Gleb Smirnoff <glebius@FreeBSD.org> CommitDate: 2022-06-29 16:42:58 +0000 unix: change error code for recvmsg() failed due to RLIMIT_NOFILE Instead of returning EMSGSIZE pass the error code from fdallocn() directly to userland. That would be EMFILE, which makes much more sense. This error code is not listed in the specification[1], but the specification doesn't cover such edge case at all. Meanwhile the specification lists EMSGSIZE as the error code for invalid value of msg_iovlen, and FreeBSD follows that, see sys_recmsg(). Differentiating these two cases will make a developer/admin life much easier when debugging. [1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html Reviewed by: markj Differential revision: https://reviews.freebsd.org/D35640 --- lib/libc/sys/recv.2 | 19 +++++++++++++++---- sys/kern/uipc_usrreq.c | 3 +-- tests/sys/kern/unix_passfd_test.c | 4 ++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/lib/libc/sys/recv.2 b/lib/libc/sys/recv.2 index 46e0cf8163dd..1f3bf531c3e7 100644 --- a/lib/libc/sys/recv.2 +++ b/lib/libc/sys/recv.2 @@ -28,7 +28,7 @@ .\" @(#)recv.2 8.3 (Berkeley) 2/21/94 .\" $FreeBSD$ .\" -.Dd August 19, 2018 +.Dd June 29, 2022 .Dt RECV 2 .Os .Sh NAME @@ -332,7 +332,7 @@ and The argument .Fa s does not refer to a socket. -.It Bq Er EMSGSIZE +.It Bq Er EMFILE The .Fn recvmsg system call @@ -340,9 +340,20 @@ was used to receive rights (file descriptors) that were in flight on the connection. However, the receiving program did not have enough free file descriptor slots to accept them. -In this case the descriptors are -closed, any pending data can be returned by another call to +In this case the descriptors are closed, with pending data either discarded +in the case of the unreliable datagram protocol or preserved in the case of a +reliable protocol. +The pending data can be retrieved with another call to .Fn recvmsg . +.It Bq Er EMSGSIZE +The +.Fa msg_iovlen +member of the +.Fa msghdr +structure pointed to by +.Fa msg +is less than or equal to 0, or is greater than +.Va IOV_MAX . .It Bq Er EAGAIN The socket is marked non-blocking and the receive operation would block, or diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 2eb9db632a11..b0661c0d0daf 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -2547,9 +2547,8 @@ unp_externalize(struct mbuf *control, struct mbuf **controlp, int flags) fdp = (int *) CMSG_DATA(mtod(*controlp, struct cmsghdr *)); - if (fdallocn(td, 0, fdp, newfds) != 0) { + if ((error = fdallocn(td, 0, fdp, newfds))) { FILEDESC_XUNLOCK(fdesc); - error = EMSGSIZE; unp_freerights(fdep, newfds); m_freem(*controlp); *controlp = NULL; diff --git a/tests/sys/kern/unix_passfd_test.c b/tests/sys/kern/unix_passfd_test.c index bbd298f9a26f..dc017db4f1ce 100644 --- a/tests/sys/kern/unix_passfd_test.c +++ b/tests/sys/kern/unix_passfd_test.c @@ -428,8 +428,8 @@ ATF_TC_BODY(send_a_lot, tc) msghdr.msg_controllen = CMSG_LEN(sizeof(int)); ATF_REQUIRE(sendmsg(fd[0], &msghdr, 0) == 1); ATF_REQUIRE(recvmsg(fd[1], &msghdr, 0) == -1); - /* Such attempt shall fail with EMSGSIZE. */ - ATF_REQUIRE(errno == EMSGSIZE); + /* Such attempt shall fail with EMFILE. */ + ATF_REQUIRE(errno == EMFILE); ATF_REQUIRE(getnfds() == nfds); #if TEST_PROTO == SOCK_STREAM /*