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:
committed by
waddlesplash
parent
904fd2abf0
commit
396ebbc16f
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 }
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user