// CreateProcessGroup creates a new process group.
//
// An EPERM error will be returned if the ThreadGroup belongs to a different
// Session, is a Session leader or the group already exists.
CreateProcessGroup creates a new process group.

An EPERM error will be returned if the ThreadGroup belongs to a different
Session, is a Session leader or the group already exists.
// CreateProcessGroup creates a new process group . // // An EPERM error will be returned if the ThreadGroup belongs to a different // Session is a Session leader or the group already exists .
func (tg *ThreadGroup) CreateProcessGroup() error {
	tg.pidns.owner.mu.Lock()
	defer tg.pidns.owner.mu.Unlock()
	id := tg.pidns.tgids[tg]
	for s := tg.pidns.owner.sessions.Front(); s != nil; s = s.Next() {
		if s.leader.pidns != tg.pidns {
			continue
		}
		if s.leader == tg {
			return syserror.EPERM
		}
		for pg := s.processGroups.Front(); pg != nil; pg = pg.Next() {
			if pg.id == ProcessGroupID(id) {
				return syserror.EPERM
			}
		}
	}
	 We manually adjust the ancestors if the parent is in the same
	 session.
	tg.processGroup.session.IncRef()
	pg := ProcessGroup{
		id:         ProcessGroupID(id),
		originator: tg,
		session:    tg.processGroup.session,
	}
	pg.refs.InitRefs()
	if tg.leader.parent != nil && tg.leader.parent.tg.processGroup.session == pg.session {
		pg.ancestors++
	}
	 Assign the new process group; adjust children.
	oldParentPG := tg.parentPG()
	tg.forEachChildThreadGroupLocked(func(childTG *ThreadGroup) {
		childTG.processGroup.incRefWithParent(&pg)
		childTG.processGroup.decRefWithParent(oldParentPG)
	})
	tg.processGroup.decRefWithParent(oldParentPG)
	tg.processGroup = &pg
	 Add the new process group to the session.
	pg.session.processGroups.PushBack(&pg)
	 Ensure this translation is added to all namespaces.
	for ns := tg.pidns; ns != nil; ns = ns.parent {
		local := ns.tgids[tg]
		ns.pgids[&pg] = ProcessGroupID(local)
		ns.processGroups[ProcessGroupID(local)] = &pg
	}
	return nil
}
func ( tg * ThreadGroup ) CreateProcessGroup ( ) error { tg . pidns . owner . mu . Lock ( ) defer tg . pidns . owner . mu . Unlock ( ) id := tg . pidns . tgids [ tg ] for s := tg . pidns . owner . sessions . Front ( ) ; s != nil ; s = s . Next ( ) { if s . leader . pidns != tg . pidns { continue } if s . leader == tg { return syserror . EPERM } for pg := s . processGroups . Front ( ) ; pg != nil ; pg = pg . Next ( ) { if pg . id == ProcessGroupID ( id ) { return syserror . EPERM } } } tg . processGroup . session . IncRef ( ) pg := ProcessGroup { id : ProcessGroupID ( id ) , originator : tg , session : tg . processGroup . session , } pg . refs . InitRefs ( ) if tg . leader . parent != nil && tg . leader . parent . tg . processGroup . session == pg . session { pg . ancestors ++ } oldParentPG := tg . parentPG ( ) tg . forEachChildThreadGroupLocked ( func ( childTG * ThreadGroup ) { childTG . processGroup . incRefWithParent ( & pg ) childTG . processGroup . decRefWithParent ( oldParentPG ) } ) tg . processGroup . decRefWithParent ( oldParentPG ) tg . processGroup = & pg pg . session . processGroups . PushBack ( & pg ) for ns := tg . pidns ; ns != nil ; ns = ns . parent { local := ns . tgids [ tg ] ns . pgids [ & pg ] = ProcessGroupID ( local ) ns . processGroups [ ProcessGroupID ( local ) ] = & pg } return nil }
CreateProcessGroup creates a new process group.
CreateProcessGroup creates a new process group .
// Get the ID for this thread in the current namespace. // Per above, check for a Session leader or existing group. // Create a new ProcessGroup, belonging to the current Session. // // We manually adjust the ancestors if the parent is in the same // session. // Assign the new process group; adjust children. // Add the new process group to the session. // Ensure this translation is added to all namespaces.