1// Copyright 2009 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
5package os
6
7import (
8	"runtime"
9	"syscall"
10)
11
12func hostname() (name string, err error) {
13	// Try uname first, as it's only one system call and reading
14	// from /proc is not allowed on Android.
15	var un syscall.Utsname
16	err = syscall.Uname(&un)
17
18	var buf [512]byte // Enough for a DNS name.
19	for i, b := range un.Nodename[:] {
20		buf[i] = uint8(b)
21		if b == 0 {
22			name = string(buf[:i])
23			break
24		}
25	}
26	// If we got a name and it's not potentially truncated
27	// (Nodename is 65 bytes), return it.
28	if err == nil && len(name) > 0 && len(name) < 64 {
29		return name, nil
30	}
31	if runtime.GOOS == "android" {
32		if name != "" {
33			return name, nil
34		}
35		return "localhost", nil
36	}
37
38	f, err := Open("/proc/sys/kernel/hostname")
39	if err != nil {
40		return "", err
41	}
42	defer f.Close()
43
44	n, err := f.Read(buf[:])
45	if err != nil {
46		return "", err
47	}
48
49	if n > 0 && buf[n-1] == '\n' {
50		n--
51	}
52	return string(buf[:n]), nil
53}
54