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
This commit is contained in:
parent
baf8f20a4a
commit
48a55bbfe9
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user