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_MCAST 0x0200 /* this message rec'd as multicast */
|
||||||
#define MSG_EOF 0x0400 /* data completes connection */
|
#define MSG_EOF 0x0400 /* data completes connection */
|
||||||
#define MSG_NOSIGNAL 0x0800 /* don't raise SIGPIPE if socket is closed */
|
#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 {
|
struct cmsghdr {
|
||||||
socklen_t cmsg_len;
|
socklen_t cmsg_len;
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ struct net_protocol_module_info {
|
|||||||
ancillary_data_container* container, const cmsghdr* header);
|
ancillary_data_container* container, const cmsghdr* header);
|
||||||
ssize_t (*process_ancillary_data)(net_protocol* self,
|
ssize_t (*process_ancillary_data)(net_protocol* self,
|
||||||
const ancillary_data_container* container,
|
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,
|
ssize_t (*process_ancillary_data_no_container)(net_protocol* self,
|
||||||
net_buffer* buffer, void* data, size_t bufferSize);
|
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
|
ssize_t
|
||||||
unix_process_ancillary_data(net_protocol *self,
|
unix_process_ancillary_data(net_protocol *self,
|
||||||
const ancillary_data_container *container, void *buffer,
|
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",
|
TRACE("[%" B_PRId32 "] unix_process_ancillary_data(%p, %p, %p, %p, %lu)\n",
|
||||||
find_thread(NULL), self, container, buffer, bufferSize);
|
find_thread(NULL), self, container, buffer, bufferSize);
|
||||||
@@ -409,6 +409,12 @@ unix_process_ancillary_data(net_protocol *self,
|
|||||||
close_fd_index(ioContext, fds[j]);
|
close_fd_index(ioContext, fds[j]);
|
||||||
break;
|
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)
|
if (error != B_OK)
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ add_ancillary_data(net_socket* socket, ancillary_data_container* container,
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
process_ancillary_data(net_socket* socket, ancillary_data_container* container,
|
process_ancillary_data(net_socket* socket, ancillary_data_container* container,
|
||||||
msghdr* messageHeader)
|
msghdr* messageHeader, int flags)
|
||||||
{
|
{
|
||||||
uint8* dataBuffer = (uint8*)messageHeader->msg_control;
|
uint8* dataBuffer = (uint8*)messageHeader->msg_control;
|
||||||
int dataBufferLen = messageHeader->msg_controllen;
|
int dataBufferLen = messageHeader->msg_controllen;
|
||||||
@@ -247,7 +247,7 @@ process_ancillary_data(net_socket* socket, ancillary_data_container* container,
|
|||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
|
|
||||||
ssize_t bytesWritten = socket->first_info->process_ancillary_data(
|
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)
|
if (bytesWritten < 0)
|
||||||
return bytesWritten;
|
return bytesWritten;
|
||||||
|
|
||||||
@@ -258,7 +258,7 @@ process_ancillary_data(net_socket* socket, ancillary_data_container* container,
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
process_ancillary_data(net_socket* socket,
|
process_ancillary_data(net_socket* socket,
|
||||||
net_buffer* buffer, msghdr* messageHeader)
|
net_buffer* buffer, msghdr* messageHeader, int flags)
|
||||||
{
|
{
|
||||||
void *dataBuffer = messageHeader->msg_control;
|
void *dataBuffer = messageHeader->msg_control;
|
||||||
ssize_t bytesWritten;
|
ssize_t bytesWritten;
|
||||||
@@ -295,7 +295,7 @@ socket_receive_no_buffer(net_socket* socket, msghdr* header, void* data,
|
|||||||
ancillary_data_container* ancillaryData = NULL;
|
ancillary_data_container* ancillaryData = NULL;
|
||||||
ssize_t bytesRead = socket->first_info->read_data_no_buffer(
|
ssize_t bytesRead = socket->first_info->read_data_no_buffer(
|
||||||
socket->first_protocol, vecs, vecCount, &ancillaryData, address,
|
socket->first_protocol, vecs, vecCount, &ancillaryData, address,
|
||||||
addressLen, flags);
|
addressLen, flags & ~(MSG_CMSG_CLOEXEC | MSG_CMSG_CLOFORK));
|
||||||
if (bytesRead < 0)
|
if (bytesRead < 0)
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
|
|
||||||
@@ -305,7 +305,8 @@ socket_receive_no_buffer(net_socket* socket, msghdr* header, void* data,
|
|||||||
|
|
||||||
// process ancillary data
|
// process ancillary data
|
||||||
if (header != NULL) {
|
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)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -1165,9 +1166,9 @@ socket_receive(net_socket* socket, msghdr* header, void* data, size_t length,
|
|||||||
ancillary_data_container* container
|
ancillary_data_container* container
|
||||||
= gNetBufferModule.get_ancillary_data(buffer);
|
= gNetBufferModule.get_ancillary_data(buffer);
|
||||||
if (container != NULL)
|
if (container != NULL)
|
||||||
status = process_ancillary_data(socket, container, header);
|
status = process_ancillary_data(socket, container, header, flags);
|
||||||
else
|
else
|
||||||
status = process_ancillary_data(socket, buffer, header);
|
status = process_ancillary_data(socket, buffer, header, flags);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
gNetBufferModule.free(buffer);
|
gNetBufferModule.free(buffer);
|
||||||
return status;
|
return status;
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ static const FlagsTypeHandler::FlagInfo kRecvFlagInfos[] = {
|
|||||||
FLAG_INFO_ENTRY(MSG_MCAST),
|
FLAG_INFO_ENTRY(MSG_MCAST),
|
||||||
FLAG_INFO_ENTRY(MSG_EOF),
|
FLAG_INFO_ENTRY(MSG_EOF),
|
||||||
FLAG_INFO_ENTRY(MSG_NOSIGNAL),
|
FLAG_INFO_ENTRY(MSG_NOSIGNAL),
|
||||||
|
FLAG_INFO_ENTRY(MSG_CMSG_CLOEXEC),
|
||||||
|
FLAG_INFO_ENTRY(MSG_CMSG_CLOFORK),
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user