github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/os/user/getgrouplist_darwin.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build cgo,!osusergo 6 7 package user 8 9 /* 10 #include <unistd.h> 11 #include <sys/types.h> 12 #include <stdlib.h> 13 14 static int mygetgrouplist(const char* user, gid_t group, gid_t* groups, int* ngroups) { 15 int* buf = malloc(*ngroups * sizeof(int)); 16 int rv = getgrouplist(user, (int) group, buf, ngroups); 17 int i; 18 if (rv == 0) { 19 for (i = 0; i < *ngroups; i++) { 20 groups[i] = (gid_t) buf[i]; 21 } 22 } 23 free(buf); 24 return rv; 25 } 26 */ 27 import "C" 28 import ( 29 "fmt" 30 "unsafe" 31 ) 32 33 func getGroupList(name *C.char, userGID C.gid_t, gids *C.gid_t, n *C.int) C.int { 34 return C.mygetgrouplist(name, userGID, gids, n) 35 } 36 37 // groupRetry retries getGroupList with an increasingly large size for n. The 38 // result is stored in gids. 39 func groupRetry(username string, name []byte, userGID C.gid_t, gids *[]C.gid_t, n *C.int) error { 40 *n = C.int(256 * 2) 41 for { 42 *gids = make([]C.gid_t, *n) 43 rv := getGroupList((*C.char)(unsafe.Pointer(&name[0])), userGID, &(*gids)[0], n) 44 if rv >= 0 { 45 // n is set correctly 46 break 47 } 48 if *n > maxGroups { 49 return fmt.Errorf("user: %q is a member of more than %d groups", username, maxGroups) 50 } 51 *n = *n * C.int(2) 52 } 53 return nil 54 }