// Copyright 2021 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.//go:build ((darwin || dragonfly || freebsd || (js && wasm) || wasip1 || (!android && linux) || netbsd || openbsd || solaris) && ((!cgo && !darwin) || osusergo)) || aix || illumospackage userimport ()func listGroupsFromReader( *User, io.Reader) ([]string, error) {if .Username == "" {returnnil, errors.New("user: list groups: empty username") } , := strconv.Atoi(.Gid)if != nil {returnnil, fmt.Errorf("user: list groups for %s: invalid gid %q", .Username, .Gid) } := []byte("," + .Username + ",") // ,john, := [1:] // john, := [:len()-1] // ,john := [1 : len()-1] // john// Add primary Gid first. := []string{.Gid} := bufio.NewReader() := falsefor ! { , := .ReadBytes('\n')if != nil {if == io.EOF { = true } else {return , } }// Look for username in the list of users. If user is found, // append the GID to the groups slice.// There's no spec for /etc/passwd or /etc/group, but we try to follow // the same rules as the glibc parser, which allows comments and blank // space at the beginning of a line. = bytes.TrimSpace()iflen() == 0 || [0] == '#' ||// If you search for a gid in a row where the group // name (the first field) starts with "+" or "-", // glibc fails to find the record, and so should we. [0] == '+' || [0] == '-' {continue }// Format of /etc/group is // groupname:password:GID:user_list // for example // wheel:x:10:john,paul,jack // tcpdump:x:72: := bytes.LastIndexByte(, ':')if == -1 || == len()-1 {// No commas, or empty group list.continue }ifbytes.Count([:], colon) != 2 {// Incorrect number of colons.continue } := [+1:]// Check the list for user without splitting or copying.if !(bytes.Equal(, ) || bytes.HasPrefix(, ) || bytes.HasSuffix(, ) || bytes.Contains(, )) {continue }// groupname:password:GID := bytes.Split([:], colon)iflen() != 3 || len([0]) == 0 {continue } := string([2])// Make sure it's numeric and not the same as primary GID. , := strconv.Atoi()if != nil || == {continue } = append(, ) }return , nil}func listGroups( *User) ([]string, error) { , := os.Open(groupFile)if != nil {returnnil, }defer .Close()returnlistGroupsFromReader(, )}
The pages are generated with Goldsv0.7.0-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.