int copy_context_skas0()

in os-Linux/skas/process.c [530:615]


int copy_context_skas0(unsigned long new_stack, int pid)
{
	int err;
	unsigned long current_stack = current_stub_stack();
	struct stub_data *data = (struct stub_data *) current_stack;
	struct stub_data *child_data = (struct stub_data *) new_stack;
	unsigned long long new_offset;
	int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset);

	/*
	 * prepare offset and fd of child's stack as argument for parent's
	 * and child's mmap2 calls
	 */
	*data = ((struct stub_data) {
		.offset	= MMAP_OFFSET(new_offset),
		.fd     = new_fd,
		.parent_err = -ESRCH,
		.child_err = 0,
	});

	*child_data = ((struct stub_data) {
		.child_err = -ESRCH,
	});

	err = ptrace_setregs(pid, thread_regs);
	if (err < 0) {
		err = -errno;
		printk(UM_KERN_ERR "copy_context_skas0 : PTRACE_SETREGS "
		       "failed, pid = %d, errno = %d\n", pid, -err);
		return err;
	}

	err = put_fp_registers(pid, thread_fp_regs);
	if (err < 0) {
		printk(UM_KERN_ERR "copy_context_skas0 : put_fp_registers "
		       "failed, pid = %d, err = %d\n", pid, err);
		return err;
	}

	/*
	 * Wait, until parent has finished its work: read child's pid from
	 * parent's stack, and check, if bad result.
	 */
	err = ptrace(PTRACE_CONT, pid, 0, 0);
	if (err) {
		err = -errno;
		printk(UM_KERN_ERR "Failed to continue new process, pid = %d, "
		       "errno = %d\n", pid, errno);
		return err;
	}

	wait_stub_done(pid);

	pid = data->parent_err;
	if (pid < 0) {
		printk(UM_KERN_ERR "copy_context_skas0 - stub-parent reports "
		       "error %d\n", -pid);
		return pid;
	}

	/*
	 * Wait, until child has finished too: read child's result from
	 * child's stack and check it.
	 */
	wait_stub_done(pid);
	if (child_data->child_err != STUB_DATA) {
		printk(UM_KERN_ERR "copy_context_skas0 - stub-child %d reports "
		       "error %ld\n", pid, data->child_err);
		err = data->child_err;
		goto out_kill;
	}

	if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
		   (void *)PTRACE_O_TRACESYSGOOD) < 0) {
		err = -errno;
		printk(UM_KERN_ERR "copy_context_skas0 : PTRACE_OLDSETOPTIONS "
		       "failed, errno = %d\n", errno);
		goto out_kill;
	}

	return pid;

 out_kill:
	os_kill_ptraced_process(pid, 1);
	return err;
}