network/stack: Add clone_ancillary_data.
Change-Id: I98a56344ffbf0c691a797ad7ce69ba1de08bbbee
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9859
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Diff
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(-)
@@ -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);
};
@@ -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> 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)
{
@@ -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) {
void *dataBuffer = malloc(_ALIGN(sizeof(ancillary_data)) + ancillaryData->header.len);
if (dataBuffer == NULL)
return B_NO_MEMORY;
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;
}
@@ -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
@@ -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[] = {
@@ -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);
}