POSIX-2024: support for MSG_CMSG_CLOEXEC and MSG_CMSG_CLOFORK

Change-Id: I55551860fb7dac5d0c11a6d4201502fff9ab2d13
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9332
Reviewed-by: waddlesplash <[email protected]>
Reviewed-by: Jérôme Duval <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
Jérôme Duval
2025-06-09 16:26:13 +00:00
committed by waddlesplash
parent 904fd2abf0
commit 396ebbc16f
5 changed files with 20 additions and 9 deletions
+2
View File
@@ -126,6 +126,8 @@ struct msghdr {
#define MSG_MCAST 0x0200 /* this message rec'd as multicast */
#define MSG_EOF 0x0400 /* data completes connection */
#define MSG_NOSIGNAL 0x0800 /* don't raise SIGPIPE if socket is closed */
#define MSG_CMSG_CLOEXEC 0x1000 /* set FD_CLOEXEC flag on FDs created via SCM_RIGHTS */
#define MSG_CMSG_CLOFORK 0x2000 /* set FD_CLOFORK flag on FDs created via SCM_RIGHTS */
struct cmsghdr {
socklen_t cmsg_len;
+1 -1
View File
@@ -102,7 +102,7 @@ struct net_protocol_module_info {
ancillary_data_container* container, const cmsghdr* header);
ssize_t (*process_ancillary_data)(net_protocol* self,
const ancillary_data_container* container,
void* buffer, size_t bufferSize);
void* buffer, size_t bufferSize, int flags);
ssize_t (*process_ancillary_data_no_container)(net_protocol* self,
net_buffer* buffer, void* data, size_t bufferSize);
@@ -354,7 +354,7 @@ unix_add_ancillary_data(net_protocol *self, ancillary_data_container *container,
ssize_t
unix_process_ancillary_data(net_protocol *self,
const ancillary_data_container *container, void *buffer,
size_t bufferSize)
size_t bufferSize, int flags)
{
TRACE("[%" B_PRId32 "] unix_process_ancillary_data(%p, %p, %p, %p, %lu)\n",
find_thread(NULL), self, container, buffer, bufferSize);
@@ -409,6 +409,12 @@ unix_process_ancillary_data(net_protocol *self,
close_fd_index(ioContext, fds[j]);
break;
}
WriteLocker locker(ioContext->lock);
if ((flags & MSG_CMSG_CLOEXEC) != 0)
fd_set_close_on_exec(ioContext, fds[i], true);
if ((flags & MSG_CMSG_CLOFORK) != 0)
fd_set_close_on_fork(ioContext, fds[i], true);
}
if (error != B_OK)
break;
@@ -233,7 +233,7 @@ add_ancillary_data(net_socket* socket, ancillary_data_container* container,
static status_t
process_ancillary_data(net_socket* socket, ancillary_data_container* container,
msghdr* messageHeader)
msghdr* messageHeader, int flags)
{
uint8* dataBuffer = (uint8*)messageHeader->msg_control;
int dataBufferLen = messageHeader->msg_controllen;
@@ -247,7 +247,7 @@ process_ancillary_data(net_socket* socket, ancillary_data_container* container,
return B_NOT_SUPPORTED;
ssize_t bytesWritten = socket->first_info->process_ancillary_data(
socket->first_protocol, container, dataBuffer, dataBufferLen);
socket->first_protocol, container, dataBuffer, dataBufferLen, flags);
if (bytesWritten < 0)
return bytesWritten;
@@ -258,7 +258,7 @@ process_ancillary_data(net_socket* socket, ancillary_data_container* container,
static status_t
process_ancillary_data(net_socket* socket,
net_buffer* buffer, msghdr* messageHeader)
net_buffer* buffer, msghdr* messageHeader, int flags)
{
void *dataBuffer = messageHeader->msg_control;
ssize_t bytesWritten;
@@ -295,7 +295,7 @@ socket_receive_no_buffer(net_socket* socket, msghdr* header, void* data,
ancillary_data_container* ancillaryData = NULL;
ssize_t bytesRead = socket->first_info->read_data_no_buffer(
socket->first_protocol, vecs, vecCount, &ancillaryData, address,
addressLen, flags);
addressLen, flags & ~(MSG_CMSG_CLOEXEC | MSG_CMSG_CLOFORK));
if (bytesRead < 0)
return bytesRead;
@@ -305,7 +305,8 @@ socket_receive_no_buffer(net_socket* socket, msghdr* header, void* data,
// process ancillary data
if (header != NULL) {
status_t status = process_ancillary_data(socket, ancillaryData, header);
status_t status = process_ancillary_data(socket, ancillaryData, header,
flags & (MSG_CMSG_CLOEXEC | MSG_CMSG_CLOFORK));
if (status != B_OK)
return status;
@@ -1165,9 +1166,9 @@ socket_receive(net_socket* socket, msghdr* header, void* data, size_t length,
ancillary_data_container* container
= gNetBufferModule.get_ancillary_data(buffer);
if (container != NULL)
status = process_ancillary_data(socket, container, header);
status = process_ancillary_data(socket, container, header, flags);
else
status = process_ancillary_data(socket, buffer, header);
status = process_ancillary_data(socket, buffer, header, flags);
if (status != B_OK) {
gNetBufferModule.free(buffer);
return status;
+2
View File
@@ -38,6 +38,8 @@ static const FlagsTypeHandler::FlagInfo kRecvFlagInfos[] = {
FLAG_INFO_ENTRY(MSG_MCAST),
FLAG_INFO_ENTRY(MSG_EOF),
FLAG_INFO_ENTRY(MSG_NOSIGNAL),
FLAG_INFO_ENTRY(MSG_CMSG_CLOEXEC),
FLAG_INFO_ENTRY(MSG_CMSG_CLOFORK),
{ 0, NULL }
};