At the beginning, you do
pp = &list_head;
and, as you traverse the list, you advance this “cursor” with
pp = &(*pp)->next;
This way, you always keep track of the point where “you come from” and can modify the pointer living there.
So when you find the entry to be deleted, you can just do
*pp = entry->next
This way, you take care of all 3 cases Afaq mentions in another answer, effectively eliminating the NULL
check on prev
.