github.com/newrelic/go-agent@v3.26.0+incompatible/internal/sysinfo/hostname_linux.go (about) 1 // Copyright 2020 New Relic Corporation. All rights reserved. 2 // SPDX-License-Identifier: Apache-2.0 3 4 package sysinfo 5 6 import ( 7 "os" 8 "syscall" 9 ) 10 11 // Hostname returns the host name. 12 func Hostname() (string, error) { 13 // Try the builtin API first, which is designed to match the output of 14 // /bin/hostname, and fallback to uname(2) if that fails to match the 15 // behavior of gethostname(2) as implemented by glibc. On Linux, all 16 // these method should result in the same value because sethostname(2) 17 // limits the hostname to 64 bytes, the same size of the nodename field 18 // returned by uname(2). Note that is correspondence is not true on 19 // other platforms. 20 // 21 // os.Hostname failures should be exceedingly rare, however some systems 22 // configure SELinux to deny read access to /proc/sys/kernel/hostname. 23 // Redhat's OpenShift platform for example. os.Hostname can also fail if 24 // some or all of /proc has been hidden via chroot(2) or manipulation of 25 // the current processes' filesystem namespace via the cgroups APIs. 26 // Docker is an example of a tool that can configure such an 27 // environment. 28 name, err := os.Hostname() 29 if err == nil { 30 return name, nil 31 } 32 33 var uts syscall.Utsname 34 if err2 := syscall.Uname(&uts); err2 != nil { 35 // The man page documents only one possible error for uname(2), 36 // suggesting that as long as the buffer given is valid, the 37 // call will never fail. Return the original error in the hope 38 // it provides more relevant information about why the hostname 39 // can't be retrieved. 40 return "", err 41 } 42 43 // Convert Nodename to a Go string. 44 buf := make([]byte, 0, len(uts.Nodename)) 45 for _, c := range uts.Nodename { 46 if c == 0 { 47 break 48 } 49 buf = append(buf, byte(c)) 50 } 51 52 return string(buf), nil 53 }