From 8dcdf257f9105946e97969a72132072e35fa576c Mon Sep 17 00:00:00 2001 From: Jérôme Duval Date: Wed, 12 Nov 2025 19:21:10 +0100 Subject: [PATCH] network/stack: Add clone_ancillary_data. Change-Id: I98a56344ffbf0c691a797ad7ce69ba1de08bbbee Reviewed-on: https://review.haiku-os.org/c/haiku/+/9859 Reviewed-by: waddlesplash Tested-by: Commit checker robot --- headers/private/net/net_stack.h | 3 +++ src/add-ons/kernel/network/stack/ancillary_data.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/add-ons/kernel/network/stack/ancillary_data.h | 3 +++ src/add-ons/kernel/network/stack/stack.cpp | 3 ++- src/add-ons/kernel/network/protocols/unix/unix.cpp | 2 +- 5 files changed, 54 insertions(+), 2 deletions(-) diff --git a/headers/private/net/net_stack.h b/headers/private/net/net_stack.h index 7120bd0..704c7cf 100644 --- a/headers/private/net/net_stack.h +++ b/headers/private/net/net_stack.h @@ -175,6 +175,7 @@ status_t (*add_ancillary_data)(ancillary_data_container* container, const ancillary_data_header* header, const void* data, void (*destructor)(const ancillary_data_header*, void*), + void (*clone)(const ancillary_data_header*, void*), void** _allocatedData); status_t (*remove_ancillary_data)(ancillary_data_container* container, void* data, bool destroy); @@ -182,6 +183,8 @@ ancillary_data_container* to); void* (*next_ancillary_data)(const ancillary_data_container* container, void* previousData, ancillary_data_header* _header); + status_t (*clone_ancillary_data)(const ancillary_data_container* from, + ancillary_data_container* to); }; diff --git a/src/add-ons/kernel/network/stack/ancillary_data.cpp b/src/add-ons/kernel/network/stack/ancillary_data.cpp index 4c307e1..f3d2ace 100644 --- a/src/add-ons/kernel/network/stack/ancillary_data.cpp +++ b/src/add-ons/kernel/network/stack/ancillary_data.cpp @@ -29,6 +29,7 @@ ancillary_data_header header; void (*destructor)(const ancillary_data_header*, void*); + void (*clone)(const ancillary_data_header*, void*); }; typedef DoublyLinkedList ancillary_data_list; @@ -69,6 +70,8 @@ \param data If not \c NULL, the data are copied into the allocated storage. \param destructor If not \c NULL, this function will be invoked with the data as parameter when the container is destroyed. + \param clone If not \c NULL, this function will be invoked with the + data as parameter when the container is cloned. \param _allocatedData Will be set to the storage allocated for the data. \return \c B_OK when everything goes well, another error code otherwise. */ @@ -76,6 +79,7 @@ add_ancillary_data(ancillary_data_container* container, const ancillary_data_header* header, const void* data, void (*destructor)(const ancillary_data_header*, void*), + void (*clone)(const ancillary_data_header*, void*), void** _allocatedData) { // check parameters @@ -94,6 +98,7 @@ ancillary_data *ancillaryData = new(dataBuffer) ancillary_data; ancillaryData->header = *header; ancillaryData->destructor = destructor; + ancillaryData->clone = clone; container->data_list.Add(ancillaryData); @@ -202,4 +207,44 @@ *_header = ancillaryData->header; return ancillaryData->Data(); +} + + +/*! + Clones all ancillary data from container \c from to the end of the list of + ancillary data of container \c to. + + \param from The container from which to clone the ancillary data. + \param to The container to which to add the ancillary data. + \return \c B_OK when everything goes well, another error code otherwise. +*/ +status_t +clone_ancillary_data(const ancillary_data_container* from, + ancillary_data_container* to) +{ + ancillary_data *ancillaryData = from->data_list.Head(); + + while (ancillaryData != NULL) { + // allocate buffer + void *dataBuffer = malloc(_ALIGN(sizeof(ancillary_data)) + ancillaryData->header.len); + if (dataBuffer == NULL) + return B_NO_MEMORY; + + // init and attach the structure + ancillary_data *clone = new(dataBuffer) ancillary_data; + clone->header = ancillaryData->header; + if (ancillaryData->clone != NULL) + ancillaryData->clone(&ancillaryData->header, ancillaryData->Data()); + clone->destructor = ancillaryData->destructor; + clone->clone = ancillaryData->clone; + + to->data_list.Add(clone); + + if (ancillaryData->Data() != NULL) + memcpy(clone->Data(), ancillaryData->Data(), ancillaryData->header.len); + + ancillaryData = from->data_list.GetNext(ancillaryData); + } + + return B_OK; } diff --git a/src/add-ons/kernel/network/stack/ancillary_data.h b/src/add-ons/kernel/network/stack/ancillary_data.h index fd012ba..542cd06 100644 --- a/src/add-ons/kernel/network/stack/ancillary_data.h +++ b/src/add-ons/kernel/network/stack/ancillary_data.h @@ -16,6 +16,7 @@ status_t add_ancillary_data(ancillary_data_container* container, const ancillary_data_header* header, const void* data, void (*destructor)(const ancillary_data_header*, void*), + void (*clone)(const ancillary_data_header*, void*), void** _allocatedData); status_t remove_ancillary_data(ancillary_data_container* container, void* data, bool destroy); @@ -24,6 +25,8 @@ void* next_ancillary_data(const ancillary_data_container* container, void* previousData, ancillary_data_header* _header); +status_t clone_ancillary_data(const ancillary_data_container* from, + ancillary_data_container* to); #endif // NET_ANCILLARY_DATA_H diff --git a/src/add-ons/kernel/network/stack/stack.cpp b/src/add-ons/kernel/network/stack/stack.cpp index 599fbe4..75f5e26 100644 --- a/src/add-ons/kernel/network/stack/stack.cpp +++ b/src/add-ons/kernel/network/stack/stack.cpp @@ -989,7 +989,8 @@ add_ancillary_data, remove_ancillary_data, move_ancillary_data, - next_ancillary_data + next_ancillary_data, + clone_ancillary_data }; module_info* modules[] = { diff --git a/src/add-ons/kernel/network/protocols/unix/unix.cpp b/src/add-ons/kernel/network/protocols/unix/unix.cpp index 3ca8693..e2265d4 100644 --- a/src/add-ons/kernel/network/protocols/unix/unix.cpp +++ b/src/add-ons/kernel/network/protocols/unix/unix.cpp @@ -334,7 +334,7 @@ "container\n", find_thread(NULL), count); error = gStackModule->add_ancillary_data(container, &header, - descriptors, destroy_scm_rights_descriptors, NULL); + descriptors, destroy_scm_rights_descriptors, NULL, NULL); } // cleanup on error -- gitore 0.2.3