int sys_clone(int (*fn)(void *), void *child_stack, int flags, void *arg) { volatile task_t* child = task_clone(fn, child_stack, flags, arg); if(unlikely(!child)) { errno = EINVAL; return -1; } return child->pid; });
static int do_clone(struct task *task, struct task *newtask) { debug(DEBUG_EVENT, "+++ process %s pid=%d, newpid=%d", get_clone_type(task->event.type), task->pid, newtask->pid); if (unlikely(options.verbose)) fprintf(stderr, "+++ process %s pid=%d, newpid=%d\n", get_clone_type(task->event.type), task->pid, newtask->pid); assert(task->stopped); assert(newtask->stopped); assert(newtask->is_new); if (unlikely(options.verbose && newtask->event.type != EVENT_NEW)) fprintf(stderr, "!!!task new unexpected event for pid=%d: %d\n", newtask->pid, newtask->event.type); else if (unlikely(options.verbose && newtask->event.e_un.signum)) fprintf(stderr, "!!!task new unexpected signal for pid=%d: %d\n", newtask->pid, newtask->event.e_un.signum); if (newtask->leader == newtask) { if (task_fork(task, newtask) < 0) goto fail; if (!options.follow) { remove_proc(newtask); return RET_DELETED; } report_fork(newtask, task); } else { if (task_clone(task, newtask) < 0) goto fail; } newtask->is_new = 0; return continue_task(newtask, 0); fail: fprintf(stderr, "Error during clone of pid=%d - This process won't be traced!\n", newtask->pid); return -1; }