Commit 50df1364 authored by Aram Hăvărneanu's avatar Aram Hăvărneanu Committed by Russ Cox

runtime, net: add support for GOOS=solaris

LGTM=dave, rsc
R=golang-codereviews, minux.ma, mikioh.mikioh, dave, iant, rsc
CC=golang-codereviews
https://golang.org/cl/36030043
parent c738591e
......@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// +build !netgo
// +build darwin dragonfly freebsd
// +build darwin dragonfly freebsd solaris
package net
......
......@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// +build !netgo
// +build darwin dragonfly freebsd linux netbsd openbsd
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package net
......
......@@ -141,7 +141,7 @@ func TestSelfConnect(t *testing.T) {
n = 1000
}
switch runtime.GOOS {
case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd", "plan9", "windows":
case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd", "plan9", "solaris", "windows":
// Non-Linux systems take a long time to figure
// out that there is nothing listening on localhost.
n = 100
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
// DNS client: see RFC 1035.
// Has to be linked into package net for Dial.
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
// Read system DNS config from /etc/resolv.conf
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd windows
// +build darwin dragonfly freebsd linux netbsd openbsd windows solaris
package net
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package net
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package net
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package net
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build plan9
// +build plan9 solaris
package net
......
......@@ -277,7 +277,7 @@ func TestIPConnRemoteName(t *testing.T) {
}
}
raddr := &IPAddr{IP: IPv4(127, 0, 0, 10).To4()}
raddr := &IPAddr{IP: IPv4(127, 0, 0, 1).To4()}
c, err := DialIP("ip:tcp", &IPAddr{IP: IPv4(127, 0, 0, 1)}, raddr)
if err != nil {
t.Fatalf("DialIP failed: %v", err)
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd windows
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
package net
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd windows
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
// Internet protocol family sockets for POSIX
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package net
......
......@@ -27,6 +27,8 @@ func TestIPv4MulticastListener(t *testing.T) {
switch runtime.GOOS {
case "plan9":
t.Skipf("skipping test on %q", runtime.GOOS)
case "solaris":
t.Skipf("skipping test on solaris, see issue 7399")
}
closer := func(cs []*UDPConn) {
......@@ -93,8 +95,10 @@ var ipv6MulticastListenerTests = []struct {
// port.
func TestIPv6MulticastListener(t *testing.T) {
switch runtime.GOOS {
case "plan9", "solaris":
case "plan9":
t.Skipf("skipping test on %q", runtime.GOOS)
case "solaris":
t.Skipf("skipping test on solaris, see issue 7399")
}
if !supportsIPv6 {
t.Skip("ipv6 is not supported")
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
// Read system port mappings from /etc/services
......@@ -10,12 +10,16 @@ package net
import "sync"
var services map[string]map[string]int
// services contains minimal mappings between services names and port
// numbers for platforms that don't have a complete list of port numbers
// (some Solaris distros).
var services = map[string]map[string]int{
"tcp": {"http": 80},
}
var servicesError error
var onceReadServices sync.Once
func readServices() {
services = make(map[string]map[string]int)
var file *file
if file, servicesError = open("/etc/services"); servicesError != nil {
return
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin netbsd openbsd
// +build darwin netbsd openbsd solaris
package net
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd windows
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
package net
......
// 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.
package net
import "syscall"
func maxListenerBacklog() int {
// TODO: Implement this
// NOTE: Never return a number bigger than 1<<16 - 1. See issue 5030.
return syscall.SOMAXCONN
}
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd windows
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
package net
......
// Copyright 2011 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.
package net
import (
"os"
"syscall"
)
func setDefaultSockopts(s, family, sotype int, ipv6only bool) error {
if family == syscall.AF_INET6 && sotype != syscall.SOCK_RAW {
// Allow both IP versions even if the OS default
// is otherwise. Note that some operating systems
// never admit this option.
syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only))
}
// Allow broadcast.
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1))
}
func setDefaultListenerSockopts(s int) error {
// Allow reuse of recently-used addresses.
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1))
}
func setDefaultMulticastSockopts(s int) error {
// Allow multicast UDP and raw IP datagram sockets to listen
// concurrently across multiple listeners.
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1))
}
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd netbsd openbsd
// +build darwin dragonfly freebsd netbsd openbsd solaris
package net
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd windows
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
package net
......
......@@ -5,7 +5,7 @@
// This file implements sysSocket and accept for platforms that do not
// provide a fast path for setting SetNonblock and CloseOnExec.
// +build darwin dragonfly freebsd netbsd openbsd
// +build darwin dragonfly freebsd netbsd openbsd solaris
package net
......
......@@ -440,6 +440,9 @@ func TestIPv6LinkLocalUnicastTCP(t *testing.T) {
}
func TestTCPConcurrentAccept(t *testing.T) {
if runtime.GOOS == "solaris" {
t.Skip("skipping on Solaris, see issue 7400")
}
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
ln, err := Listen("tcp", "127.0.0.1:0")
if err != nil {
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd windows
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
package net
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd windows
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
package net
......
// Copyright 2013 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.
// TCP socket options for solaris
package net
import (
"os"
"syscall"
"time"
)
// Set keep alive period.
func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
if err := fd.incref(); err != nil {
return err
}
defer fd.decref()
// The kernel expects seconds so round to next highest second.
d += (time.Second - time.Nanosecond)
secs := int(d.Seconds())
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.SO_KEEPALIVE, secs))
}
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd windows
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
package net
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd windows
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
package net
......
// Copyright 2013 The Go Authors. All rights reserved.
// Copyright 2014 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.
......
......@@ -58,6 +58,7 @@ struct PollDesc
G* wg; // READY, WAIT, G waiting for write or nil
Timer wt; // write deadline timer
int64 wd; // write deadline
void* user; // user settable cookie
};
static struct
......@@ -141,7 +142,7 @@ func runtime_pollWait(pd *PollDesc, mode int) (err int) {
if(err == 0) {
// As for now only Solaris uses level-triggered IO.
if(Solaris)
runtime·netpollarm(pd->fd, mode);
runtime·netpollarm(pd, mode);
while(!netpollblock(pd, mode, false)) {
err = checkerr(pd, mode);
if(err != 0)
......@@ -256,6 +257,12 @@ runtime·netpollfd(PollDesc *pd)
return pd->fd;
}
void**
runtime·netpolluser(PollDesc *pd)
{
return &pd->user;
}
// make pd ready, newly runnable goroutines (if any) are enqueued info gpp list
void
runtime·netpollready(G **gpp, PollDesc *pd, int32 mode)
......
......@@ -53,9 +53,9 @@ runtime·netpollclose(uintptr fd)
}
void
runtime·netpollarm(uintptr fd, int32 mode)
runtime·netpollarm(PollDesc* pd, int32 mode)
{
USED(fd, mode);
USED(pd, mode);
runtime·throw("unused");
}
......
......@@ -60,9 +60,9 @@ runtime·netpollclose(uintptr fd)
}
void
runtime·netpollarm(uintptr fd, int32 mode)
runtime·netpollarm(PollDesc* pd, int32 mode)
{
USED(fd, mode);
USED(pd, mode);
runtime·throw("unused");
}
......
// Copyright 2014 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.
#include "runtime.h"
#include "arch_GOARCH.h"
#include "defs_GOOS_GOARCH.h"
#include "os_GOOS.h"
#pragma dynimport libc·fcntl fcntl "libc.so"
#pragma dynimport libc·port_create port_create "libc.so"
#pragma dynimport libc·port_associate port_associate "libc.so"
#pragma dynimport libc·port_dissociate port_dissociate "libc.so"
#pragma dynimport libc·port_getn port_getn "libc.so"
extern uintptr libc·fcntl;
extern uintptr libc·port_create;
extern uintptr libc·port_associate;
extern uintptr libc·port_dissociate;
extern uintptr libc·port_getn;
#define errno (*m->perrno)
int32
runtime·fcntl(int32 fd, int32 cmd, uintptr arg)
{
return runtime·sysvicall6(libc·fcntl, 3,
(uintptr)fd, (uintptr)cmd, (uintptr)arg);
}
int32
runtime·port_create(void)
{
return runtime·sysvicall6(libc·port_create, 0);
}
int32
runtime·port_associate(int32 port, int32 source, uintptr object, int32 events, uintptr user)
{
return runtime·sysvicall6(libc·port_associate,
5, (uintptr)port, (uintptr)source, object, (uintptr)events, user);
}
int32
runtime·port_dissociate(int32 port, int32 source, uintptr object)
{
return runtime·sysvicall6(libc·port_dissociate,
3, (uintptr)port, (uintptr)source, object);
}
int32
runtime·port_getn(int32 port, PortEvent *evs, uint32 max, uint32 *nget, Timespec *timeout)
{
return runtime·sysvicall6(libc·port_getn, 5, (uintptr)port,
(uintptr)evs, (uintptr)max, (uintptr)nget, (uintptr)timeout);
}
static int32 portfd = -1;
void
runtime·netpollinit(void)
{
if((portfd = runtime·port_create()) >= 0) {
runtime·fcntl(portfd, F_SETFD, FD_CLOEXEC);
return;
}
runtime·printf("netpollinit: failed to create port (%d)\n", errno);
runtime·throw("netpollinit: failed to create port");
}
int32
runtime·netpollopen(uintptr fd, PollDesc *pd)
{
uint32 events = POLLIN | POLLOUT;
*runtime·netpolluser(pd) = (void*)events;
return runtime·port_associate(portfd, PORT_SOURCE_FD, fd, events, (uintptr)pd);
}
int32
runtime·netpollclose(uintptr fd)
{
return runtime·port_dissociate(portfd, PORT_SOURCE_FD, fd);
}
void
runtime·netpollupdate(PollDesc* pd, uint32 set, uint32 clear)
{
uint32 *ep, old, events;
uintptr fd = runtime·netpollfd(pd);
ep = (uint32*)runtime·netpolluser(pd);
do {
old = *ep;
events = (old & ~clear) | set;
if(old == events)
return;
if(events && runtime·port_associate(portfd, PORT_SOURCE_FD, fd, events, (uintptr)pd) != 0) {
runtime·printf("netpollupdate: failed to associate (%d)\n", errno);
runtime·throw("netpollupdate: failed to associate");
}
} while(runtime·cas(ep, old, events) != events);
}
void
runtime·netpollarm(PollDesc* pd, int32 mode)
{
switch(mode) {
case 'r':
runtime·netpollupdate(pd, POLLIN, 0);
break;
case 'w':
runtime·netpollupdate(pd, POLLOUT, 0);
break;
default:
runtime·throw("netpollarm: bad mode");
}
}
// polls for ready network connections
// returns list of goroutines that become runnable
G*
runtime·netpoll(bool block)
{
static int32 lasterr;
PortEvent events[128], *ev;
PollDesc *pd;
int32 i, mode;
uint32 n;
Timespec *wait = nil, zero;
G *gp;
if(portfd == -1)
return (nil);
if(!block) {
zero.tv_sec = 0;
zero.tv_nsec = 0;
wait = &zero;
}
retry:
n = 1;
if(runtime·port_getn(portfd, events, nelem(events), &n, wait) < 0) {
if(errno != EINTR && errno != lasterr) {
lasterr = errno;
runtime·printf("runtime: port_getn on fd %d "
"failed with %d\n", portfd, errno);
}
goto retry;
}
gp = nil;
for(i = 0; i < n; i++) {
ev = &events[i];
if(ev->portev_events == 0)
continue;
if((pd = (PollDesc *)ev->portev_user) == nil)
continue;
mode = 0;
if(ev->portev_events & (POLLIN|POLLHUP|POLLERR))
mode += 'r';
if(ev->portev_events & (POLLOUT|POLLHUP|POLLERR))
mode += 'w';
//
// To effect edge-triggered events, we need to be sure to
// update our association with whatever events were not
// set with the event.
//
runtime·netpollupdate(pd, 0, ev->portev_events & (POLLIN|POLLOUT));
if(mode)
runtime·netpollready(&gp, pd, mode);
}
if(block && gp == nil)
goto retry;
return gp;
}
......@@ -73,9 +73,9 @@ runtime·netpollclose(uintptr fd)
}
void
runtime·netpollarm(uintptr fd, int32 mode)
runtime·netpollarm(PollDesc* pd, int32 mode)
{
USED(fd, mode);
USED(pd, mode);
runtime·throw("unused");
}
......
// Copyright 2013 The Go Authors. All rights reserved.
// Copyright 2014 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.
......
// Copyright 2013 The Go Authors. All rights reserved.
// Copyright 2014 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.
......
......@@ -919,7 +919,8 @@ int32 runtime·netpollopen(uintptr, PollDesc*);
int32 runtime·netpollclose(uintptr);
void runtime·netpollready(G**, PollDesc*, int32);
uintptr runtime·netpollfd(PollDesc*);
void runtime·netpollarm(uintptr, int32);
void runtime·netpollarm(PollDesc*, int32);
void** runtime·netpolluser(PollDesc*);
void runtime·crash(void);
void runtime·parsedebugvars(void);
void _rt0_go(void);
......
// Copyright 2013 The Go Authors. All rights reserved.
// Copyright 2014 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.
......
// Copyright 2013 The Go Authors. All rights reserved.
// Copyright 2014 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.
......
// Copyright 2013 The Go Authors. All rights reserved.
// Copyright 2014 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.
//
......
// Copyright 2013 The Go Authors. All rights reserved.
// Copyright 2014 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.
......@@ -50,7 +50,7 @@ extern uintptr libc·forkx;
extern uintptr libc·wait4;
extern uintptr libc·write;
func Sysvicall6(func uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err uintptr)
func sysvicall6(func uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err uintptr)
{
LibCall c;
......@@ -69,7 +69,7 @@ func Sysvicall6(func uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr,
}
#pragma textflag NOSPLIT
func RawSysvicall6(func uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err uintptr)
func rawSysvicall6(func uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err uintptr)
{
LibCall c;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment