add os.Hostname

R=r
DELTA=188  (182 added, 3 deleted, 3 changed)
OCL=30856
CL=30860
This commit is contained in:
Russ Cox 2009-06-29 13:44:46 -07:00
parent 6a71f43f82
commit b32769b1a3
8 changed files with 187 additions and 6 deletions

View File

@ -2,8 +2,9 @@
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
# DO NOT EDIT. Automatically generated by gobuild.
# gobuild -m dir_${GOOS}_${GOARCH}.go env.go error.go file.go path.go stat_${GOOS}_${GOARCH}.go time.go types.go exec.go proc.go getwd.go >Makefile
# gobuild -m dir_${GOOS}_${GOARCH}.go env.go error.go file.go path.go stat_${GOOS}_${GOARCH}.go time.go types.go exec.go proc.go getwd.go sys_${GOOS}.go >Makefile
D=
@ -20,7 +21,7 @@ test: packages
coverage: packages
gotest
6cov -g `pwd` | grep -v '_test\.go:'
6cov -g $$(pwd) | grep -v '_test\.go:'
%.$O: %.go
$(GC) -I_obj $*.go
@ -49,6 +50,7 @@ O4=\
exec.$O\
getwd.$O\
path.$O\
sys_$(GOOS).$O\
phases: a1 a2 a3 a4
@ -67,7 +69,7 @@ a3: $(O3)
rm -f $(O3)
a4: $(O4)
$(AR) grc _obj$D/os.a dir_$(GOOS)_$(GOARCH).$O exec.$O getwd.$O path.$O
$(AR) grc _obj$D/os.a dir_$(GOOS)_$(GOARCH).$O exec.$O getwd.$O path.$O sys_$(GOOS).$O
rm -f $(O4)

View File

@ -587,3 +587,43 @@ func TestOpenError(t *testing.T) {
}
}
}
func run(t *testing.T, cmd []string) string {
// Run /bin/hostname and collect output.
r, w, err := Pipe();
if err != nil {
t.Fatal(err);
}
pid, err := ForkExec("/bin/hostname", []string{"hostname"}, nil, "/", []*File{nil, w, Stderr});
if err != nil {
t.Fatal(err);
}
w.Close();
var b io.ByteBuffer;
io.Copy(r, &b);
Wait(pid, 0);
output := string(b.Data());
if n := len(output); n > 0 && output[n-1] == '\n' {
output = output[0:n-1];
}
if output == "" {
t.Fatalf("%v produced no output", cmd);
}
return output;
}
func TestHostname(t *testing.T) {
// Check internal Hostname() against the output of /bin/hostname.
hostname, err := Hostname();
if err != nil {
t.Fatalf("%v", err);
}
want := run(t, []string{"/bin/hostname"});
if hostname != want {
t.Errorf("Hostname() = %q, want %q", hostname, want);
}
}

21
src/pkg/os/sys_darwin.go Normal file
View File

@ -0,0 +1,21 @@
// Copyright 2009 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.
// Darwin-specific
package os
import (
"os";
"syscall";
)
func Hostname() (name string, err os.Error) {
var errno int;
name, errno = syscall.Sysctl("kern.hostname");
if errno != 0 {
return "", NewSyscallError("sysctl kern.hostname", errno);
}
return name, nil;
}

29
src/pkg/os/sys_linux.go Normal file
View File

@ -0,0 +1,29 @@
// Copyright 2009 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.
// Linux-specific
package os
import "os"
// Hostname returns the host name reported by the kernel.
func Hostname() (name string, err os.Error) {
f, err := Open("/proc/sys/kernel/hostname", O_RDONLY, 0);
if err != nil {
return "", err;
}
defer f.Close();
var buf [512]byte; // Enough for a DNS name.
n, err := f.Read(&buf);
if err != nil {
return "", err;
}
if n > 0 && buf[n-1] == '\n' {
n--;
}
return string(buf[0:n]), nil;
}

View File

@ -361,6 +361,82 @@ func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, errno
return kevent(kq, change, len(changes), event, len(events), timeout);
}
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (errno int) = SYS___SYSCTL
// Translate "kern.hostname" to []_C_int{0,1,2,3}.
func nametomib(name string) (mib []_C_int, errno int) {
const CTL_MAXNAME = 12;
const siz = uintptr(unsafe.Sizeof(mib[0]));
// NOTE(rsc): It seems strange to set the buffer to have
// size CTL_MAXNAME+2 but use only CTL_MAXNAME
// as the size. I don't know why the +2 is here, but the
// kernel uses +2 for its own implementation of this function.
// I am scared that if we don't include the +2 here, the kernel
// will silently write 2 words farther than we specify
// and we'll get memory corruption.
var buf [CTL_MAXNAME+2] _C_int;
n := uintptr(CTL_MAXNAME)*siz;
p := (*byte)(unsafe.Pointer(&buf[0]));
bytes := StringByteSlice(name);
// Magic sysctl: "setting" 0.3 to a string name
// lets you read back the array of integers form.
if errno = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); errno != 0 {
return nil, errno;
}
return buf[0:n/siz], 0;
}
func Sysctl(name string) (value string, errno int) {
// Translate name to mib number.
mib, errno := nametomib(name);
if errno != 0 {
return "", errno;
}
// Find size.
n := uintptr(0);
if errno = sysctl(mib, nil, &n, nil, 0); errno != 0 {
return "", errno;
}
if n == 0 {
return "", 0;
}
// Read into buffer of that size.
buf := make([]byte, n);
if errno = sysctl(mib, &buf[0], &n, nil, 0); errno != 0 {
return "", errno;
}
// Throw away terminating NUL.
if n > 0 && buf[n-1] == '\x00' {
n--;
}
return string(buf[0:n]), 0;
}
func SysctlUint32(name string) (value uint32, errno int) {
// Translate name to mib number.
mib, errno := nametomib(name);
if errno != 0 {
return 0, errno;
}
// Read into buffer of that size.
n := uintptr(4);
buf := make([]byte, 4);
if errno = sysctl(mib, &buf[0], &n, nil, 0); errno != 0 {
return 0, errno;
}
if n != 4 {
return 0, EIO;
}
return *(*uint32)(unsafe.Pointer(&buf[0])), 0;
}
// TODO: wrap
// Acct(name nil-string) (errno int)
// Futimes(fd int, timeval *Timeval) (errno int) // Pointer to 2 timevals!
@ -500,7 +576,6 @@ func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, errno
// Kdebug_trace
// Sigreturn
// Mmap
// __Sysctl
// Mlock
// Munlock
// Atsocket

View File

@ -383,8 +383,6 @@ func SetsockoptLinger(fd, level, opt int, l *Linger) (errno int) {
// Recvfrom
// Sendmsg
// Recvmsg
// Getsockname
// Getpeername
// Socketpair
// Getsockopt

View File

@ -87,6 +87,14 @@ func kevent(kq int, change uintptr, nchange int, event uintptr, nevent int, time
return;
}
func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (errno int) {
var _p0 *_C_int;
if len(mib) > 0 { _p0 = &mib[0]; }
r0, r1, e1 := Syscall6(SYS___SYSCTL, uintptr(unsafe.Pointer(_p0)), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen));
errno = int(e1);
return;
}
func fcntl(fd int, cmd int, arg int) (val int, errno int) {
r0, r1, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg));
val = int(r0);

View File

@ -87,6 +87,14 @@ func kevent(kq int, change uintptr, nchange int, event uintptr, nevent int, time
return;
}
func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (errno int) {
var _p0 *_C_int;
if len(mib) > 0 { _p0 = &mib[0]; }
r0, r1, e1 := Syscall6(SYS___SYSCTL, uintptr(unsafe.Pointer(_p0)), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen));
errno = int(e1);
return;
}
func fcntl(fd int, cmd int, arg int) (val int, errno int) {
r0, r1, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg));
val = int(r0);