mirror of
https://github.com/golang/go.git
synced 2024-10-01 15:27:13 +00:00
add os.Hostname
R=r DELTA=188 (182 added, 3 deleted, 3 changed) OCL=30856 CL=30860
This commit is contained in:
parent
6a71f43f82
commit
b32769b1a3
@ -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)
|
||||
|
||||
|
||||
|
@ -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
21
src/pkg/os/sys_darwin.go
Normal 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
29
src/pkg/os/sys_linux.go
Normal 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;
|
||||
}
|
@ -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
|
||||
|
@ -383,8 +383,6 @@ func SetsockoptLinger(fd, level, opt int, l *Linger) (errno int) {
|
||||
// Recvfrom
|
||||
// Sendmsg
|
||||
// Recvmsg
|
||||
// Getsockname
|
||||
// Getpeername
|
||||
// Socketpair
|
||||
// Getsockopt
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user