summaryrefslogtreecommitdiffstats
path: root/lib/list_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/list_util.c')
-rw-r--r--lib/list_util.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/lib/list_util.c b/lib/list_util.c
index 0d61a67a..720b8ca7 100644
--- a/lib/list_util.c
+++ b/lib/list_util.c
@@ -31,24 +31,45 @@
*
* Have to chase down list to find item.
*
+ * Note that p_this:
+ *
+ * * starts as pointer to the base pointer, so should really be void**,
+ * but that causes all sorts of problems with strict-aliasing.
+ *
+ * So: have to cast to (void**) before dereferencing to get the address
+ * of the first item on the list.
+ *
+ * * as steps along the list p_this points to the "next pointer" in the
+ * previous item.
+ *
+ * The _sl_p_next() macro adds the offset of the "next pointer" to the
+ * address of the this item.
+ *
+ * * at the end, assigns the item's "next pointer" to the "next pointer"
+ * field pointed at by p_this.
+ *
+ * Note again the cast to (void**).
+ *
* Returns: 0 => OK -- removed item from list (OR item == NULL)
* -1 => item not found on list
*/
extern int
-ssl_del_func(void** p_this, void* item, size_t link_offset)
+ssl_del_func(void* p_this, void* item, size_t link_offset)
{
+ void* this ;
+
if (item == NULL)
return 0 ;
- while (*p_this != item)
+ while ((this = *(void**)p_this) != item)
{
- if (*p_this == NULL)
+ if (this == NULL)
return -1 ;
- p_this = _sl_p_next(*p_this, link_offset) ;
+ p_this = _sl_p_next(this, link_offset) ;
} ;
- *p_this = _sl_next(item, link_offset) ;
+ *(void**)p_this = _sl_next(item, link_offset) ;
return 0 ;
} ;