Your question is tagged c, and your file ends in .c. So here's some thoughts from that angle:
Don't bother casting
void *to another pointer type. This is a C++ thing. In C,void *can be implicitly cast to any pointer type.There is no such thing as a namespace, so don't use collision-prone names like
nodeorlen(). Add some kind of prefix.malloccan fail. You will want to bubble up that error status. All your functions that end up callingmallocfurther down the stack will need a means to return error status as well. Typically the way to do this is returnNULL(if your function returns a pointer type) or make the function returnbool(<stdbool.h>in C99) orintand have some convention where a certain value means failure. (In POSIX it's typicallyintreturning 0 on success. Windows will typically have a boolean where nonzero means success. Returning error codes is also popular.)
Some other thoughts:
Consider an alternate allocation scheme for
struct llist. Personally I would prefer the structure itself (not the nodes of course) to be caller-allocated. Is it worth doing amallocfor something only the size of two pointers inllist_init? I would say no. Further, consider the memory layout if you want to include a list inside a structure: why bother having a pointer to it when you can just have thestruct llistbe a member of the larger structure?The use of whitespace seems inconsistent. At times you put an extra newline between declarations and statements, and at times you don't. It's of course subjective which one of these you choose (I would rather more space personally), but it's important to be consistent.