// JoinProcessGroup joins an existing process group.
//
// This function will return EACCES if an exec has been performed since fork
// by the given ThreadGroup, and EPERM if the Sessions are not the same or the
// group does not exist.
//
// If checkExec is set, then the join is not permitted after the process has
// executed exec at least once.
JoinProcessGroup joins an existing process group.

This function will return EACCES if an exec has been performed since fork
by the given ThreadGroup, and EPERM if the Sessions are not the same or the
group does not exist.

If checkExec is set, then the join is not permitted after the process has
executed exec at least once.
// JoinProcessGroup joins an existing process group . // // This function will return EACCES if an exec has been performed since fork // by the given ThreadGroup and EPERM if the Sessions are not the same or the // group does not exist . // // If checkExec is set then the join is not permitted after the process has // executed exec at least once .
func (tg *ThreadGroup) JoinProcessGroup(pidns *PIDNamespace, pgid ProcessGroupID, checkExec bool) error {
	pidns.owner.mu.Lock()
	defer pidns.owner.mu.Unlock()
	pg := pidns.processGroups[pgid]
	if pg == nil {
		return syserror.EPERM
	}
	if checkExec && tg.execed {
		return syserror.EACCES
	}
	if pg.session != tg.processGroup.session {
		return syserror.EPERM
	}
	parentPG := tg.parentPG()
	pg.incRefWithParent(parentPG)
	tg.forEachChildThreadGroupLocked(func(childTG *ThreadGroup) {
		childTG.processGroup.incRefWithParent(pg)
		childTG.processGroup.decRefWithParent(tg.processGroup)
	})
	tg.processGroup.decRefWithParent(parentPG)
	tg.processGroup = pg
	return nil
}
func ( tg * ThreadGroup ) JoinProcessGroup ( pidns * PIDNamespace , pgid ProcessGroupID , checkExec bool ) error { pidns . owner . mu . Lock ( ) defer pidns . owner . mu . Unlock ( ) pg := pidns . processGroups [ pgid ] if pg == nil { return syserror . EPERM } if checkExec && tg . execed { return syserror . EACCES } if pg . session != tg . processGroup . session { return syserror . EPERM } parentPG := tg . parentPG ( ) pg . incRefWithParent ( parentPG ) tg . forEachChildThreadGroupLocked ( func ( childTG * ThreadGroup ) { childTG . processGroup . incRefWithParent ( pg ) childTG . processGroup . decRefWithParent ( tg . processGroup ) } ) tg . processGroup . decRefWithParent ( parentPG ) tg . processGroup = pg return nil }
JoinProcessGroup joins an existing process group.
JoinProcessGroup joins an existing process group .
// Lookup the ProcessGroup. // Disallow the join if an execve has performed, per POSIX. // See if it's in the same session as ours. // Join the group; adjust children.