linux系统调用kernel code

linux系统调用kernel code

kernel\include\uapi\asm-generic\unistd.h

kernel/sys.c

SYSCALL_DEFINE2(setpgid, pid_t, pid, pid_t, pgid)
{
    struct task_struct *p;
    struct task_struct *group_leader = current->group_leader;
    struct pid *pgrp;
    int err;

    if (!pid)
        pid = task_pid_vnr(group_leader);
    if (!pgid)
        pgid = pid;
    if (pgid < 0)
        return -EINVAL;
    rcu_read_lock();

    /* From this point forward we keep holding onto the tasklist lock
     * so that our parent does not change from under us. -DaveM
     */
    write_lock_irq(&tasklist_lock);

    err = -ESRCH;
    p = find_task_by_vpid(pid);
    if (!p)
        goto out;

    err = -EINVAL;
    if (!thread_group_leader(p))
        goto out;

    if (same_thread_group(p->real_parent, group_leader)) {
        err = -EPERM;
        if (task_session(p) != task_session(group_leader))
            goto out;
        err = -EACCES;
        if (!(p->flags & PF_FORKNOEXEC))
            goto out;
    } else {
        err = -ESRCH;
        if (p != group_leader)
            goto out;
    }

    err = -EPERM;
    if (p->signal->leader)
        goto out;

    pgrp = task_pid(p);
    if (pgid != pid) {
        struct task_struct *g;

        pgrp = find_vpid(pgid);
        g = pid_task(pgrp, PIDTYPE_PGID);
        if (!g || task_session(g) != task_session(group_leader))
            goto out;
    }

    err = security_task_setpgid(p, pgid);
    if (err)
        goto out;

    if (task_pgrp(p) != pgrp)
        change_pid(p, PIDTYPE_PGID, pgrp);

    err = 0;
out:
    /* All paths lead to here, thus we are safe. -DaveM */
    write_unlock_irq(&tasklist_lock);
    rcu_read_unlock();
    return err;
}

 

posted @ 2020-03-21 19:05  aspirs  阅读(275)  评论(0编辑  收藏  举报