-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathshellcgo.go
48 lines (42 loc) · 975 Bytes
/
shellcgo.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//go:build (cgo && aix) || (cgo && android) || (cgo && darwin) || (cgo && dragonfly) || (cgo && freebsd) || (cgo && linux) || (cgo && netbsd) || (cgo && openbsd) || (cgo && illumos)
package shell
// #cgo illumos CFLAGS: -D_POSIX_PTHREAD_SEMANTICS=1
// #include <errno.h>
// #include <pwd.h>
// #include <stdlib.h>
// #include <sys/types.h>
// #include <unistd.h>
import "C"
import (
"unsafe"
)
func cgoGetUserShell(name string) (string, bool) {
buflen := C.sysconf(C._SC_GETPW_R_SIZE_MAX)
if buflen == -1 {
buflen = 1024
}
for {
var (
cName = C.CString(name)
pwd C.struct_passwd
buf = make([]byte, buflen)
result *C.struct_passwd
)
rc := C.getpwnam_r(
cName,
&pwd,
(*C.char)(unsafe.Pointer(&buf[0])),
C.size_t(buflen),
&result, //nolint:gocritic
)
C.free(unsafe.Pointer(cName))
switch rc {
case 0:
return C.GoString(result.pw_shell), true
case C.ERANGE:
buflen *= 2
default:
return "", false
}
}
}