This is my solution so far:
int is_descendant(task_t* ansc, task_t* targ)
for(p_tmp = targ ; (p_tmp) && (ansc) && (p_tmp->pid) && (p_tmp->pid != ansc->pid) ; p_tmp = p_tmp->p_pptr) ;
if((!p_tmp) || (!current) || (!p_tmp->pid)) return -ESRCH;
p_tmp->pid == 0
As for 4.: What are you hoping to get by using a macro instead of a function? It is almost always better to use a function and to not use a macro.
The basic problems with macros include (but are not necessarily limited to) the following:
return NOTDESCENDANTline. (It might work, if the macro is used inside of a function that has a matching return type.)
All these points are also discussed here: Macro vs Function in C You can also see some examples for all these problems there.
Bottom line: When in doubt, always use functions or inline functions instead of macros.