diff options
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | libgo/Makefile.am | 11 | ||||
-rw-r--r-- | libgo/Makefile.in | 95 | ||||
-rw-r--r-- | libgo/go/exp/README | 3 | ||||
-rw-r--r-- | libgo/go/exp/proxy/direct.go | 18 | ||||
-rw-r--r-- | libgo/go/exp/proxy/per_host.go | 140 | ||||
-rw-r--r-- | libgo/go/exp/proxy/per_host_test.go | 55 | ||||
-rw-r--r-- | libgo/go/exp/proxy/proxy.go | 94 | ||||
-rw-r--r-- | libgo/go/exp/proxy/proxy_test.go | 50 | ||||
-rw-r--r-- | libgo/go/exp/proxy/socks5.go | 207 | ||||
-rw-r--r-- | libgo/go/exp/terminal/terminal.go | 520 | ||||
-rw-r--r-- | libgo/go/exp/terminal/terminal_test.go | 110 | ||||
-rw-r--r-- | libgo/go/exp/terminal/util.go | 118 |
13 files changed, 31 insertions, 1392 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index cb13cf0..13df755 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -87df767807acac466edb3bb6445ad83a48141d17 +4b8036b3f995cdb0b99a9fa26c2af1e2420b4fa2 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/libgo/Makefile.am b/libgo/Makefile.am index d5ea8f6..c8b444c 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -235,12 +235,6 @@ toolexeclibgoencoding_DATA = \ encoding/pem.gox \ encoding/xml.gox -toolexeclibgoexpdir = $(toolexeclibgodir)/exp - -toolexeclibgoexp_DATA = \ - exp/proxy.gox \ - exp/terminal.gox - toolexeclibgogodir = $(toolexeclibgodir)/go toolexeclibgogo_DATA = \ @@ -759,8 +753,6 @@ PACKAGES = \ encoding/pem \ encoding/xml \ errors \ - exp/proxy \ - exp/terminal \ expvar \ flag \ fmt \ @@ -1066,7 +1058,6 @@ CHECK_DEPS = \ $(toolexeclibgocrypto_DATA) \ $(toolexeclibgodebug_DATA) \ $(toolexeclibgoencoding_DATA) \ - $(toolexeclibgoexp_DATA) \ $(toolexeclibgogo_DATA) \ $(toolexeclibgohash_DATA) \ $(toolexeclibgoimage_DATA) \ @@ -1352,8 +1343,6 @@ TEST_PACKAGES = \ encoding/json/check \ encoding/pem/check \ encoding/xml/check \ - exp/proxy/check \ - exp/terminal/check \ html/template/check \ go/ast/check \ go/build/check \ diff --git a/libgo/Makefile.in b/libgo/Makefile.in index 6e03b89..99fbd8c 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -131,7 +131,6 @@ am__installdirs = "$(DESTDIR)$(toolexeclibdir)" \ "$(DESTDIR)$(toolexeclibgodatabasesqldir)" \ "$(DESTDIR)$(toolexeclibgodebugdir)" \ "$(DESTDIR)$(toolexeclibgoencodingdir)" \ - "$(DESTDIR)$(toolexeclibgoexpdir)" \ "$(DESTDIR)$(toolexeclibgogodir)" \ "$(DESTDIR)$(toolexeclibgohashdir)" \ "$(DESTDIR)$(toolexeclibgohtmldir)" \ @@ -257,17 +256,16 @@ DATA = $(noinst_DATA) $(toolexeclibgo_DATA) \ $(toolexeclibgocontainer_DATA) $(toolexeclibgocrypto_DATA) \ $(toolexeclibgocryptox509_DATA) $(toolexeclibgodatabase_DATA) \ $(toolexeclibgodatabasesql_DATA) $(toolexeclibgodebug_DATA) \ - $(toolexeclibgoencoding_DATA) $(toolexeclibgoexp_DATA) \ - $(toolexeclibgogo_DATA) $(toolexeclibgohash_DATA) \ - $(toolexeclibgohtml_DATA) $(toolexeclibgoimage_DATA) \ - $(toolexeclibgoimagecolor_DATA) $(toolexeclibgoindex_DATA) \ - $(toolexeclibgoio_DATA) $(toolexeclibgolog_DATA) \ - $(toolexeclibgomath_DATA) $(toolexeclibgomime_DATA) \ - $(toolexeclibgonet_DATA) $(toolexeclibgonethttp_DATA) \ - $(toolexeclibgonetrpc_DATA) $(toolexeclibgoos_DATA) \ - $(toolexeclibgopath_DATA) $(toolexeclibgoregexp_DATA) \ - $(toolexeclibgoruntime_DATA) $(toolexeclibgosync_DATA) \ - $(toolexeclibgotesting_DATA) \ + $(toolexeclibgoencoding_DATA) $(toolexeclibgogo_DATA) \ + $(toolexeclibgohash_DATA) $(toolexeclibgohtml_DATA) \ + $(toolexeclibgoimage_DATA) $(toolexeclibgoimagecolor_DATA) \ + $(toolexeclibgoindex_DATA) $(toolexeclibgoio_DATA) \ + $(toolexeclibgolog_DATA) $(toolexeclibgomath_DATA) \ + $(toolexeclibgomime_DATA) $(toolexeclibgonet_DATA) \ + $(toolexeclibgonethttp_DATA) $(toolexeclibgonetrpc_DATA) \ + $(toolexeclibgoos_DATA) $(toolexeclibgopath_DATA) \ + $(toolexeclibgoregexp_DATA) $(toolexeclibgoruntime_DATA) \ + $(toolexeclibgosync_DATA) $(toolexeclibgotesting_DATA) \ $(toolexeclibgotestinginternal_DATA) $(toolexeclibgotext_DATA) \ $(toolexeclibgotexttemplate_DATA) $(toolexeclibgounicode_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ @@ -629,11 +627,6 @@ toolexeclibgoencoding_DATA = \ encoding/pem.gox \ encoding/xml.gox -toolexeclibgoexpdir = $(toolexeclibgodir)/exp -toolexeclibgoexp_DATA = \ - exp/proxy.gox \ - exp/terminal.gox - toolexeclibgogodir = $(toolexeclibgodir)/go toolexeclibgogo_DATA = \ go/ast.gox \ @@ -890,8 +883,6 @@ PACKAGES = \ encoding/pem \ encoding/xml \ errors \ - exp/proxy \ - exp/terminal \ expvar \ flag \ fmt \ @@ -1176,18 +1167,17 @@ CHECK = \ CHECK_DEPS = $(toolexeclibgo_DATA) $(toolexeclibgoarchive_DATA) \ $(toolexeclibgocompress_DATA) $(toolexeclibgocontainer_DATA) \ $(toolexeclibgocrypto_DATA) $(toolexeclibgodebug_DATA) \ - $(toolexeclibgoencoding_DATA) $(toolexeclibgoexp_DATA) \ - $(toolexeclibgogo_DATA) $(toolexeclibgohash_DATA) \ - $(toolexeclibgoimage_DATA) $(toolexeclibgoindex_DATA) \ - $(toolexeclibgoio_DATA) $(toolexeclibgolog_DATA) \ - $(toolexeclibgomath_DATA) $(toolexeclibgomime_DATA) \ - $(toolexeclibgonet_DATA) $(toolexeclibgonethttp_DATA) \ - $(toolexeclibgoos_DATA) $(toolexeclibgopath_DATA) \ - $(toolexeclibgorpc_DATA) $(toolexeclibgoruntime_DATA) \ - $(toolexeclibgosync_DATA) $(toolexeclibgotesting_DATA) \ - $(toolexeclibgotext_DATA) $(toolexeclibgotexttemplate_DATA) \ - $(toolexeclibgounicode_DATA) $(noinst_LIBRARIES) \ - $(am__append_3) $(am__append_4) + $(toolexeclibgoencoding_DATA) $(toolexeclibgogo_DATA) \ + $(toolexeclibgohash_DATA) $(toolexeclibgoimage_DATA) \ + $(toolexeclibgoindex_DATA) $(toolexeclibgoio_DATA) \ + $(toolexeclibgolog_DATA) $(toolexeclibgomath_DATA) \ + $(toolexeclibgomime_DATA) $(toolexeclibgonet_DATA) \ + $(toolexeclibgonethttp_DATA) $(toolexeclibgoos_DATA) \ + $(toolexeclibgopath_DATA) $(toolexeclibgorpc_DATA) \ + $(toolexeclibgoruntime_DATA) $(toolexeclibgosync_DATA) \ + $(toolexeclibgotesting_DATA) $(toolexeclibgotext_DATA) \ + $(toolexeclibgotexttemplate_DATA) $(toolexeclibgounicode_DATA) \ + $(noinst_LIBRARIES) $(am__append_3) $(am__append_4) # Pass -ffp-contract=off, or 386-specific options, when building the # math package. MATH_FLAG is defined in configure.ac. @@ -1334,8 +1324,6 @@ TEST_PACKAGES = \ encoding/json/check \ encoding/pem/check \ encoding/xml/check \ - exp/proxy/check \ - exp/terminal/check \ html/template/check \ go/ast/check \ go/build/check \ @@ -2210,27 +2198,6 @@ uninstall-toolexeclibgoencodingDATA: @list='$(toolexeclibgoencoding_DATA)'; test -n "$(toolexeclibgoencodingdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(toolexeclibgoencodingdir)'; $(am__uninstall_files_from_dir) -install-toolexeclibgoexpDATA: $(toolexeclibgoexp_DATA) - @$(NORMAL_INSTALL) - @list='$(toolexeclibgoexp_DATA)'; test -n "$(toolexeclibgoexpdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgoexpdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(toolexeclibgoexpdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(toolexeclibgoexpdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(toolexeclibgoexpdir)" || exit $$?; \ - done - -uninstall-toolexeclibgoexpDATA: - @$(NORMAL_UNINSTALL) - @list='$(toolexeclibgoexp_DATA)'; test -n "$(toolexeclibgoexpdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(toolexeclibgoexpdir)'; $(am__uninstall_files_from_dir) install-toolexeclibgogoDATA: $(toolexeclibgogo_DATA) @$(NORMAL_INSTALL) @list='$(toolexeclibgogo_DATA)'; test -n "$(toolexeclibgogodir)" || list=; \ @@ -2855,7 +2822,7 @@ all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) all-multi $(DATA) \ config.h installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(toolexeclibgodir)" "$(DESTDIR)$(toolexeclibgoarchivedir)" "$(DESTDIR)$(toolexeclibgocompressdir)" "$(DESTDIR)$(toolexeclibgocontainerdir)" "$(DESTDIR)$(toolexeclibgocryptodir)" "$(DESTDIR)$(toolexeclibgocryptox509dir)" "$(DESTDIR)$(toolexeclibgodatabasedir)" "$(DESTDIR)$(toolexeclibgodatabasesqldir)" "$(DESTDIR)$(toolexeclibgodebugdir)" "$(DESTDIR)$(toolexeclibgoencodingdir)" "$(DESTDIR)$(toolexeclibgoexpdir)" "$(DESTDIR)$(toolexeclibgogodir)" "$(DESTDIR)$(toolexeclibgohashdir)" "$(DESTDIR)$(toolexeclibgohtmldir)" "$(DESTDIR)$(toolexeclibgoimagedir)" "$(DESTDIR)$(toolexeclibgoimagecolordir)" "$(DESTDIR)$(toolexeclibgoindexdir)" "$(DESTDIR)$(toolexeclibgoiodir)" "$(DESTDIR)$(toolexeclibgologdir)" "$(DESTDIR)$(toolexeclibgomathdir)" "$(DESTDIR)$(toolexeclibgomimedir)" "$(DESTDIR)$(toolexeclibgonetdir)" "$(DESTDIR)$(toolexeclibgonethttpdir)" "$(DESTDIR)$(toolexeclibgonetrpcdir)" "$(DESTDIR)$(toolexeclibgoosdir)" "$(DESTDIR)$(toolexeclibgopathdir)" "$(DESTDIR)$(toolexeclibgoregexpdir)" "$(DESTDIR)$(toolexeclibgoruntimedir)" "$(DESTDIR)$(toolexeclibgosyncdir)" "$(DESTDIR)$(toolexeclibgotestingdir)" "$(DESTDIR)$(toolexeclibgotestinginternaldir)" "$(DESTDIR)$(toolexeclibgotextdir)" "$(DESTDIR)$(toolexeclibgotexttemplatedir)" "$(DESTDIR)$(toolexeclibgounicodedir)"; do \ + for dir in "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(toolexeclibgodir)" "$(DESTDIR)$(toolexeclibgoarchivedir)" "$(DESTDIR)$(toolexeclibgocompressdir)" "$(DESTDIR)$(toolexeclibgocontainerdir)" "$(DESTDIR)$(toolexeclibgocryptodir)" "$(DESTDIR)$(toolexeclibgocryptox509dir)" "$(DESTDIR)$(toolexeclibgodatabasedir)" "$(DESTDIR)$(toolexeclibgodatabasesqldir)" "$(DESTDIR)$(toolexeclibgodebugdir)" "$(DESTDIR)$(toolexeclibgoencodingdir)" "$(DESTDIR)$(toolexeclibgogodir)" "$(DESTDIR)$(toolexeclibgohashdir)" "$(DESTDIR)$(toolexeclibgohtmldir)" "$(DESTDIR)$(toolexeclibgoimagedir)" "$(DESTDIR)$(toolexeclibgoimagecolordir)" "$(DESTDIR)$(toolexeclibgoindexdir)" "$(DESTDIR)$(toolexeclibgoiodir)" "$(DESTDIR)$(toolexeclibgologdir)" "$(DESTDIR)$(toolexeclibgomathdir)" "$(DESTDIR)$(toolexeclibgomimedir)" "$(DESTDIR)$(toolexeclibgonetdir)" "$(DESTDIR)$(toolexeclibgonethttpdir)" "$(DESTDIR)$(toolexeclibgonetrpcdir)" "$(DESTDIR)$(toolexeclibgoosdir)" "$(DESTDIR)$(toolexeclibgopathdir)" "$(DESTDIR)$(toolexeclibgoregexpdir)" "$(DESTDIR)$(toolexeclibgoruntimedir)" "$(DESTDIR)$(toolexeclibgosyncdir)" "$(DESTDIR)$(toolexeclibgotestingdir)" "$(DESTDIR)$(toolexeclibgotestinginternaldir)" "$(DESTDIR)$(toolexeclibgotextdir)" "$(DESTDIR)$(toolexeclibgotexttemplatedir)" "$(DESTDIR)$(toolexeclibgounicodedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive @@ -2931,9 +2898,9 @@ install-exec-am: install-multi install-toolexeclibLIBRARIES \ install-toolexeclibgodatabaseDATA \ install-toolexeclibgodatabasesqlDATA \ install-toolexeclibgodebugDATA \ - install-toolexeclibgoencodingDATA install-toolexeclibgoexpDATA \ - install-toolexeclibgogoDATA install-toolexeclibgohashDATA \ - install-toolexeclibgohtmlDATA install-toolexeclibgoimageDATA \ + install-toolexeclibgoencodingDATA install-toolexeclibgogoDATA \ + install-toolexeclibgohashDATA install-toolexeclibgohtmlDATA \ + install-toolexeclibgoimageDATA \ install-toolexeclibgoimagecolorDATA \ install-toolexeclibgoindexDATA install-toolexeclibgoioDATA \ install-toolexeclibgologDATA install-toolexeclibgomathDATA \ @@ -2999,8 +2966,7 @@ uninstall-am: uninstall-toolexeclibLIBRARIES \ uninstall-toolexeclibgodatabasesqlDATA \ uninstall-toolexeclibgodebugDATA \ uninstall-toolexeclibgoencodingDATA \ - uninstall-toolexeclibgoexpDATA uninstall-toolexeclibgogoDATA \ - uninstall-toolexeclibgohashDATA \ + uninstall-toolexeclibgogoDATA uninstall-toolexeclibgohashDATA \ uninstall-toolexeclibgohtmlDATA \ uninstall-toolexeclibgoimageDATA \ uninstall-toolexeclibgoimagecolorDATA \ @@ -3046,9 +3012,9 @@ uninstall-am: uninstall-toolexeclibLIBRARIES \ install-toolexeclibgodatabaseDATA \ install-toolexeclibgodatabasesqlDATA \ install-toolexeclibgodebugDATA \ - install-toolexeclibgoencodingDATA install-toolexeclibgoexpDATA \ - install-toolexeclibgogoDATA install-toolexeclibgohashDATA \ - install-toolexeclibgohtmlDATA install-toolexeclibgoimageDATA \ + install-toolexeclibgoencodingDATA install-toolexeclibgogoDATA \ + install-toolexeclibgohashDATA install-toolexeclibgohtmlDATA \ + install-toolexeclibgoimageDATA \ install-toolexeclibgoimagecolorDATA \ install-toolexeclibgoindexDATA install-toolexeclibgoioDATA \ install-toolexeclibgologDATA install-toolexeclibgomathDATA \ @@ -3078,8 +3044,7 @@ uninstall-am: uninstall-toolexeclibLIBRARIES \ uninstall-toolexeclibgodatabasesqlDATA \ uninstall-toolexeclibgodebugDATA \ uninstall-toolexeclibgoencodingDATA \ - uninstall-toolexeclibgoexpDATA uninstall-toolexeclibgogoDATA \ - uninstall-toolexeclibgohashDATA \ + uninstall-toolexeclibgogoDATA uninstall-toolexeclibgohashDATA \ uninstall-toolexeclibgohtmlDATA \ uninstall-toolexeclibgoimageDATA \ uninstall-toolexeclibgoimagecolorDATA \ diff --git a/libgo/go/exp/README b/libgo/go/exp/README deleted file mode 100644 index e602e3a..0000000 --- a/libgo/go/exp/README +++ /dev/null @@ -1,3 +0,0 @@ -This directory tree contains experimental packages and -unfinished code that is subject to even more change than the -rest of the Go tree. diff --git a/libgo/go/exp/proxy/direct.go b/libgo/go/exp/proxy/direct.go deleted file mode 100644 index 4c5ad88..0000000 --- a/libgo/go/exp/proxy/direct.go +++ /dev/null @@ -1,18 +0,0 @@ -// 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 proxy - -import ( - "net" -) - -type direct struct{} - -// Direct is a direct proxy: one that makes network connections directly. -var Direct = direct{} - -func (direct) Dial(network, addr string) (net.Conn, error) { - return net.Dial(network, addr) -} diff --git a/libgo/go/exp/proxy/per_host.go b/libgo/go/exp/proxy/per_host.go deleted file mode 100644 index 0c627e9..0000000 --- a/libgo/go/exp/proxy/per_host.go +++ /dev/null @@ -1,140 +0,0 @@ -// 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 proxy - -import ( - "net" - "strings" -) - -// A PerHost directs connections to a default Dailer unless the hostname -// requested matches one of a number of exceptions. -type PerHost struct { - def, bypass Dialer - - bypassNetworks []*net.IPNet - bypassIPs []net.IP - bypassZones []string - bypassHosts []string -} - -// NewPerHost returns a PerHost Dialer that directs connections to either -// defaultDialer or bypass, depending on whether the connection matches one of -// the configured rules. -func NewPerHost(defaultDialer, bypass Dialer) *PerHost { - return &PerHost{ - def: defaultDialer, - bypass: bypass, - } -} - -// Dial connects to the address addr on the network net through either -// defaultDialer or bypass. -func (p *PerHost) Dial(network, addr string) (c net.Conn, err error) { - host, _, err := net.SplitHostPort(addr) - if err != nil { - return nil, err - } - - return p.dialerForRequest(host).Dial(network, addr) -} - -func (p *PerHost) dialerForRequest(host string) Dialer { - if ip := net.ParseIP(host); ip != nil { - for _, net := range p.bypassNetworks { - if net.Contains(ip) { - return p.bypass - } - } - for _, bypassIP := range p.bypassIPs { - if bypassIP.Equal(ip) { - return p.bypass - } - } - return p.def - } - - for _, zone := range p.bypassZones { - if strings.HasSuffix(host, zone) { - return p.bypass - } - if host == zone[1:] { - // For a zone "example.com", we match "example.com" - // too. - return p.bypass - } - } - for _, bypassHost := range p.bypassHosts { - if bypassHost == host { - return p.bypass - } - } - return p.def -} - -// AddFromString parses a string that contains comma-separated values -// specifying hosts that should use the bypass proxy. Each value is either an -// IP address, a CIDR range, a zone (*.example.com) or a hostname -// (localhost). A best effort is made to parse the string and errors are -// ignored. -func (p *PerHost) AddFromString(s string) { - hosts := strings.Split(s, ",") - for _, host := range hosts { - host = strings.TrimSpace(host) - if len(host) == 0 { - continue - } - if strings.Contains(host, "/") { - // We assume that it's a CIDR address like 127.0.0.0/8 - if _, net, err := net.ParseCIDR(host); err == nil { - p.AddNetwork(net) - } - continue - } - if ip := net.ParseIP(host); ip != nil { - p.AddIP(ip) - continue - } - if strings.HasPrefix(host, "*.") { - p.AddZone(host[1:]) - continue - } - p.AddHost(host) - } -} - -// AddIP specifies an IP address that will use the bypass proxy. Note that -// this will only take effect if a literal IP address is dialed. A connection -// to a named host will never match an IP. -func (p *PerHost) AddIP(ip net.IP) { - p.bypassIPs = append(p.bypassIPs, ip) -} - -// AddIP specifies an IP range that will use the bypass proxy. Note that this -// will only take effect if a literal IP address is dialed. A connection to a -// named host will never match. -func (p *PerHost) AddNetwork(net *net.IPNet) { - p.bypassNetworks = append(p.bypassNetworks, net) -} - -// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of -// "example.com" matches "example.com" and all of its subdomains. -func (p *PerHost) AddZone(zone string) { - if strings.HasSuffix(zone, ".") { - zone = zone[:len(zone)-1] - } - if !strings.HasPrefix(zone, ".") { - zone = "." + zone - } - p.bypassZones = append(p.bypassZones, zone) -} - -// AddHost specifies a hostname that will use the bypass proxy. -func (p *PerHost) AddHost(host string) { - if strings.HasSuffix(host, ".") { - host = host[:len(host)-1] - } - p.bypassHosts = append(p.bypassHosts, host) -} diff --git a/libgo/go/exp/proxy/per_host_test.go b/libgo/go/exp/proxy/per_host_test.go deleted file mode 100644 index a7d8095..0000000 --- a/libgo/go/exp/proxy/per_host_test.go +++ /dev/null @@ -1,55 +0,0 @@ -// 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 proxy - -import ( - "errors" - "net" - "reflect" - "testing" -) - -type recordingProxy struct { - addrs []string -} - -func (r *recordingProxy) Dial(network, addr string) (net.Conn, error) { - r.addrs = append(r.addrs, addr) - return nil, errors.New("recordingProxy") -} - -func TestPerHost(t *testing.T) { - var def, bypass recordingProxy - perHost := NewPerHost(&def, &bypass) - perHost.AddFromString("localhost,*.zone,127.0.0.1,10.0.0.1/8,1000::/16") - - expectedDef := []string{ - "example.com:123", - "1.2.3.4:123", - "[1001::]:123", - } - expectedBypass := []string{ - "localhost:123", - "zone:123", - "foo.zone:123", - "127.0.0.1:123", - "10.1.2.3:123", - "[1000::]:123", - } - - for _, addr := range expectedDef { - perHost.Dial("tcp", addr) - } - for _, addr := range expectedBypass { - perHost.Dial("tcp", addr) - } - - if !reflect.DeepEqual(expectedDef, def.addrs) { - t.Errorf("Hosts which went to the default proxy didn't match. Got %v, want %v", def.addrs, expectedDef) - } - if !reflect.DeepEqual(expectedBypass, bypass.addrs) { - t.Errorf("Hosts which went to the bypass proxy didn't match. Got %v, want %v", bypass.addrs, expectedBypass) - } -} diff --git a/libgo/go/exp/proxy/proxy.go b/libgo/go/exp/proxy/proxy.go deleted file mode 100644 index b6cfd45..0000000 --- a/libgo/go/exp/proxy/proxy.go +++ /dev/null @@ -1,94 +0,0 @@ -// 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 proxy provides support for a variety of protocols to proxy network -// data. -package proxy - -import ( - "errors" - "net" - "net/url" - "os" -) - -// A Dialer is a means to establish a connection. -type Dialer interface { - // Dial connects to the given address via the proxy. - Dial(network, addr string) (c net.Conn, err error) -} - -// Auth contains authentication parameters that specific Dialers may require. -type Auth struct { - User, Password string -} - -// DefaultDialer returns the dialer specified by the proxy related variables in -// the environment. -func FromEnvironment() Dialer { - allProxy := os.Getenv("all_proxy") - if len(allProxy) == 0 { - return Direct - } - - proxyURL, err := url.Parse(allProxy) - if err != nil { - return Direct - } - proxy, err := FromURL(proxyURL, Direct) - if err != nil { - return Direct - } - - noProxy := os.Getenv("no_proxy") - if len(noProxy) == 0 { - return proxy - } - - perHost := NewPerHost(proxy, Direct) - perHost.AddFromString(noProxy) - return perHost -} - -// proxySchemes is a map from URL schemes to a function that creates a Dialer -// from a URL with such a scheme. -var proxySchemes map[string]func(*url.URL, Dialer) (Dialer, error) - -// RegisterDialerType takes a URL scheme and a function to generate Dialers from -// a URL with that scheme and a forwarding Dialer. Registered schemes are used -// by FromURL. -func RegisterDialerType(scheme string, f func(*url.URL, Dialer) (Dialer, error)) { - if proxySchemes == nil { - proxySchemes = make(map[string]func(*url.URL, Dialer) (Dialer, error)) - } - proxySchemes[scheme] = f -} - -// FromURL returns a Dialer given a URL specification and an underlying -// Dialer for it to make network requests. -func FromURL(u *url.URL, forward Dialer) (Dialer, error) { - var auth *Auth - if u.User != nil { - auth = new(Auth) - auth.User = u.User.Username() - if p, ok := u.User.Password(); ok { - auth.Password = p - } - } - - switch u.Scheme { - case "socks5": - return SOCKS5("tcp", u.Host, auth, forward) - } - - // If the scheme doesn't match any of the built-in schemes, see if it - // was registered by another package. - if proxySchemes != nil { - if f, ok := proxySchemes[u.Scheme]; ok { - return f(u, forward) - } - } - - return nil, errors.New("proxy: unknown scheme: " + u.Scheme) -} diff --git a/libgo/go/exp/proxy/proxy_test.go b/libgo/go/exp/proxy/proxy_test.go deleted file mode 100644 index 4078bc7..0000000 --- a/libgo/go/exp/proxy/proxy_test.go +++ /dev/null @@ -1,50 +0,0 @@ -// 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 proxy - -import ( - "net" - "net/url" - "testing" -) - -type testDialer struct { - network, addr string -} - -func (t *testDialer) Dial(network, addr string) (net.Conn, error) { - t.network = network - t.addr = addr - return nil, t -} - -func (t *testDialer) Error() string { - return "testDialer " + t.network + " " + t.addr -} - -func TestFromURL(t *testing.T) { - u, err := url.Parse("socks5://user:password@1.2.3.4:5678") - if err != nil { - t.Fatalf("failed to parse URL: %s", err) - } - - tp := &testDialer{} - proxy, err := FromURL(u, tp) - if err != nil { - t.Fatalf("FromURL failed: %s", err) - } - - conn, err := proxy.Dial("tcp", "example.com:80") - if conn != nil { - t.Error("Dial unexpected didn't return an error") - } - if tp, ok := err.(*testDialer); ok { - if tp.network != "tcp" || tp.addr != "1.2.3.4:5678" { - t.Errorf("Dialer connected to wrong host. Wanted 1.2.3.4:5678, got: %v", tp) - } - } else { - t.Errorf("Unexpected error from Dial: %s", err) - } -} diff --git a/libgo/go/exp/proxy/socks5.go b/libgo/go/exp/proxy/socks5.go deleted file mode 100644 index 62fa5c9..0000000 --- a/libgo/go/exp/proxy/socks5.go +++ /dev/null @@ -1,207 +0,0 @@ -// 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 proxy - -import ( - "errors" - "io" - "net" - "strconv" -) - -// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address -// with an optional username and password. See RFC 1928. -func SOCKS5(network, addr string, auth *Auth, forward Dialer) (Dialer, error) { - s := &socks5{ - network: network, - addr: addr, - forward: forward, - } - if auth != nil { - s.user = auth.User - s.password = auth.Password - } - - return s, nil -} - -type socks5 struct { - user, password string - network, addr string - forward Dialer -} - -const socks5Version = 5 - -const ( - socks5AuthNone = 0 - socks5AuthPassword = 2 -) - -const socks5Connect = 1 - -const ( - socks5IP4 = 1 - socks5Domain = 3 - socks5IP6 = 4 -) - -var socks5Errors = []string{ - "", - "general failure", - "connection forbidden", - "network unreachable", - "host unreachable", - "connection refused", - "TTL expired", - "command not supported", - "address type not supported", -} - -// Dial connects to the address addr on the network net via the SOCKS5 proxy. -func (s *socks5) Dial(network, addr string) (net.Conn, error) { - switch network { - case "tcp", "tcp6", "tcp4": - break - default: - return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network) - } - - conn, err := s.forward.Dial(s.network, s.addr) - if err != nil { - return nil, err - } - closeConn := &conn - defer func() { - if closeConn != nil { - (*closeConn).Close() - } - }() - - host, portStr, err := net.SplitHostPort(addr) - if err != nil { - return nil, err - } - - port, err := strconv.Atoi(portStr) - if err != nil { - return nil, errors.New("proxy: failed to parse port number: " + portStr) - } - if port < 1 || port > 0xffff { - return nil, errors.New("proxy: port number out of range: " + portStr) - } - - // the size here is just an estimate - buf := make([]byte, 0, 6+len(host)) - - buf = append(buf, socks5Version) - if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 { - buf = append(buf, 2 /* num auth methods */, socks5AuthNone, socks5AuthPassword) - } else { - buf = append(buf, 1 /* num auth methods */, socks5AuthNone) - } - - if _, err = conn.Write(buf); err != nil { - return nil, errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - if _, err = io.ReadFull(conn, buf[:2]); err != nil { - return nil, errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - if buf[0] != 5 { - return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0]))) - } - if buf[1] == 0xff { - return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication") - } - - if buf[1] == socks5AuthPassword { - buf = buf[:0] - buf = append(buf, socks5Version) - buf = append(buf, uint8(len(s.user))) - buf = append(buf, s.user...) - buf = append(buf, uint8(len(s.password))) - buf = append(buf, s.password...) - - if _, err = conn.Write(buf); err != nil { - return nil, errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - if _, err = io.ReadFull(conn, buf[:2]); err != nil { - return nil, errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - if buf[1] != 0 { - return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password") - } - } - - buf = buf[:0] - buf = append(buf, socks5Version, socks5Connect, 0 /* reserved */) - - if ip := net.ParseIP(host); ip != nil { - if len(ip) == 4 { - buf = append(buf, socks5IP4) - } else { - buf = append(buf, socks5IP6) - } - buf = append(buf, []byte(ip)...) - } else { - buf = append(buf, socks5Domain) - buf = append(buf, byte(len(host))) - buf = append(buf, host...) - } - buf = append(buf, byte(port>>8), byte(port)) - - if _, err = conn.Write(buf); err != nil { - return nil, errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - if _, err = io.ReadFull(conn, buf[:4]); err != nil { - return nil, errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - failure := "unknown error" - if int(buf[1]) < len(socks5Errors) { - failure = socks5Errors[buf[1]] - } - - if len(failure) > 0 { - return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure) - } - - bytesToDiscard := 0 - switch buf[3] { - case socks5IP4: - bytesToDiscard = 4 - case socks5IP6: - bytesToDiscard = 16 - case socks5Domain: - _, err := io.ReadFull(conn, buf[:1]) - if err != nil { - return nil, errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - bytesToDiscard = int(buf[0]) - default: - return nil, errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr) - } - - if cap(buf) < bytesToDiscard { - buf = make([]byte, bytesToDiscard) - } else { - buf = buf[:bytesToDiscard] - } - if _, err = io.ReadFull(conn, buf); err != nil { - return nil, errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - // Also need to discard the port number - if _, err = io.ReadFull(conn, buf[:2]); err != nil { - return nil, errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - closeConn = nil - return conn, nil -} diff --git a/libgo/go/exp/terminal/terminal.go b/libgo/go/exp/terminal/terminal.go deleted file mode 100644 index c1ed0c0..0000000 --- a/libgo/go/exp/terminal/terminal.go +++ /dev/null @@ -1,520 +0,0 @@ -// 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 terminal - -import ( - "io" - "sync" -) - -// EscapeCodes contains escape sequences that can be written to the terminal in -// order to achieve different styles of text. -type EscapeCodes struct { - // Foreground colors - Black, Red, Green, Yellow, Blue, Magenta, Cyan, White []byte - - // Reset all attributes - Reset []byte -} - -var vt100EscapeCodes = EscapeCodes{ - Black: []byte{keyEscape, '[', '3', '0', 'm'}, - Red: []byte{keyEscape, '[', '3', '1', 'm'}, - Green: []byte{keyEscape, '[', '3', '2', 'm'}, - Yellow: []byte{keyEscape, '[', '3', '3', 'm'}, - Blue: []byte{keyEscape, '[', '3', '4', 'm'}, - Magenta: []byte{keyEscape, '[', '3', '5', 'm'}, - Cyan: []byte{keyEscape, '[', '3', '6', 'm'}, - White: []byte{keyEscape, '[', '3', '7', 'm'}, - - Reset: []byte{keyEscape, '[', '0', 'm'}, -} - -// Terminal contains the state for running a VT100 terminal that is capable of -// reading lines of input. -type Terminal struct { - // AutoCompleteCallback, if non-null, is called for each keypress - // with the full input line and the current position of the cursor. - // If it returns a nil newLine, the key press is processed normally. - // Otherwise it returns a replacement line and the new cursor position. - AutoCompleteCallback func(line []byte, pos, key int) (newLine []byte, newPos int) - - // Escape contains a pointer to the escape codes for this terminal. - // It's always a valid pointer, although the escape codes themselves - // may be empty if the terminal doesn't support them. - Escape *EscapeCodes - - // lock protects the terminal and the state in this object from - // concurrent processing of a key press and a Write() call. - lock sync.Mutex - - c io.ReadWriter - prompt string - - // line is the current line being entered. - line []byte - // pos is the logical position of the cursor in line - pos int - // echo is true if local echo is enabled - echo bool - - // cursorX contains the current X value of the cursor where the left - // edge is 0. cursorY contains the row number where the first row of - // the current line is 0. - cursorX, cursorY int - // maxLine is the greatest value of cursorY so far. - maxLine int - - termWidth, termHeight int - - // outBuf contains the terminal data to be sent. - outBuf []byte - // remainder contains the remainder of any partial key sequences after - // a read. It aliases into inBuf. - remainder []byte - inBuf [256]byte -} - -// NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is -// a local terminal, that terminal must first have been put into raw mode. -// prompt is a string that is written at the start of each input line (i.e. -// "> "). -func NewTerminal(c io.ReadWriter, prompt string) *Terminal { - return &Terminal{ - Escape: &vt100EscapeCodes, - c: c, - prompt: prompt, - termWidth: 80, - termHeight: 24, - echo: true, - } -} - -const ( - keyCtrlD = 4 - keyEnter = '\r' - keyEscape = 27 - keyBackspace = 127 - keyUnknown = 256 + iota - keyUp - keyDown - keyLeft - keyRight - keyAltLeft - keyAltRight -) - -// bytesToKey tries to parse a key sequence from b. If successful, it returns -// the key and the remainder of the input. Otherwise it returns -1. -func bytesToKey(b []byte) (int, []byte) { - if len(b) == 0 { - return -1, nil - } - - if b[0] != keyEscape { - return int(b[0]), b[1:] - } - - if len(b) >= 3 && b[0] == keyEscape && b[1] == '[' { - switch b[2] { - case 'A': - return keyUp, b[3:] - case 'B': - return keyDown, b[3:] - case 'C': - return keyRight, b[3:] - case 'D': - return keyLeft, b[3:] - } - } - - if len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' { - switch b[5] { - case 'C': - return keyAltRight, b[6:] - case 'D': - return keyAltLeft, b[6:] - } - } - - // If we get here then we have a key that we don't recognise, or a - // partial sequence. It's not clear how one should find the end of a - // sequence without knowing them all, but it seems that [a-zA-Z] only - // appears at the end of a sequence. - for i, c := range b[0:] { - if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' { - return keyUnknown, b[i+1:] - } - } - - return -1, b -} - -// queue appends data to the end of t.outBuf -func (t *Terminal) queue(data []byte) { - t.outBuf = append(t.outBuf, data...) -} - -var eraseUnderCursor = []byte{' ', keyEscape, '[', 'D'} -var space = []byte{' '} - -func isPrintable(key int) bool { - return key >= 32 && key < 127 -} - -// moveCursorToPos appends data to t.outBuf which will move the cursor to the -// given, logical position in the text. -func (t *Terminal) moveCursorToPos(pos int) { - if !t.echo { - return - } - - x := len(t.prompt) + pos - y := x / t.termWidth - x = x % t.termWidth - - up := 0 - if y < t.cursorY { - up = t.cursorY - y - } - - down := 0 - if y > t.cursorY { - down = y - t.cursorY - } - - left := 0 - if x < t.cursorX { - left = t.cursorX - x - } - - right := 0 - if x > t.cursorX { - right = x - t.cursorX - } - - t.cursorX = x - t.cursorY = y - t.move(up, down, left, right) -} - -func (t *Terminal) move(up, down, left, right int) { - movement := make([]byte, 3*(up+down+left+right)) - m := movement - for i := 0; i < up; i++ { - m[0] = keyEscape - m[1] = '[' - m[2] = 'A' - m = m[3:] - } - for i := 0; i < down; i++ { - m[0] = keyEscape - m[1] = '[' - m[2] = 'B' - m = m[3:] - } - for i := 0; i < left; i++ { - m[0] = keyEscape - m[1] = '[' - m[2] = 'D' - m = m[3:] - } - for i := 0; i < right; i++ { - m[0] = keyEscape - m[1] = '[' - m[2] = 'C' - m = m[3:] - } - - t.queue(movement) -} - -func (t *Terminal) clearLineToRight() { - op := []byte{keyEscape, '[', 'K'} - t.queue(op) -} - -const maxLineLength = 4096 - -// handleKey processes the given key and, optionally, returns a line of text -// that the user has entered. -func (t *Terminal) handleKey(key int) (line string, ok bool) { - switch key { - case keyBackspace: - if t.pos == 0 { - return - } - t.pos-- - t.moveCursorToPos(t.pos) - - copy(t.line[t.pos:], t.line[1+t.pos:]) - t.line = t.line[:len(t.line)-1] - if t.echo { - t.writeLine(t.line[t.pos:]) - } - t.queue(eraseUnderCursor) - t.moveCursorToPos(t.pos) - case keyAltLeft: - // move left by a word. - if t.pos == 0 { - return - } - t.pos-- - for t.pos > 0 { - if t.line[t.pos] != ' ' { - break - } - t.pos-- - } - for t.pos > 0 { - if t.line[t.pos] == ' ' { - t.pos++ - break - } - t.pos-- - } - t.moveCursorToPos(t.pos) - case keyAltRight: - // move right by a word. - for t.pos < len(t.line) { - if t.line[t.pos] == ' ' { - break - } - t.pos++ - } - for t.pos < len(t.line) { - if t.line[t.pos] != ' ' { - break - } - t.pos++ - } - t.moveCursorToPos(t.pos) - case keyLeft: - if t.pos == 0 { - return - } - t.pos-- - t.moveCursorToPos(t.pos) - case keyRight: - if t.pos == len(t.line) { - return - } - t.pos++ - t.moveCursorToPos(t.pos) - case keyEnter: - t.moveCursorToPos(len(t.line)) - t.queue([]byte("\r\n")) - line = string(t.line) - ok = true - t.line = t.line[:0] - t.pos = 0 - t.cursorX = 0 - t.cursorY = 0 - t.maxLine = 0 - default: - if t.AutoCompleteCallback != nil { - t.lock.Unlock() - newLine, newPos := t.AutoCompleteCallback(t.line, t.pos, key) - t.lock.Lock() - - if newLine != nil { - if t.echo { - t.moveCursorToPos(0) - t.writeLine(newLine) - for i := len(newLine); i < len(t.line); i++ { - t.writeLine(space) - } - t.moveCursorToPos(newPos) - } - t.line = newLine - t.pos = newPos - return - } - } - if !isPrintable(key) { - return - } - if len(t.line) == maxLineLength { - return - } - if len(t.line) == cap(t.line) { - newLine := make([]byte, len(t.line), 2*(1+len(t.line))) - copy(newLine, t.line) - t.line = newLine - } - t.line = t.line[:len(t.line)+1] - copy(t.line[t.pos+1:], t.line[t.pos:]) - t.line[t.pos] = byte(key) - if t.echo { - t.writeLine(t.line[t.pos:]) - } - t.pos++ - t.moveCursorToPos(t.pos) - } - return -} - -func (t *Terminal) writeLine(line []byte) { - for len(line) != 0 { - remainingOnLine := t.termWidth - t.cursorX - todo := len(line) - if todo > remainingOnLine { - todo = remainingOnLine - } - t.queue(line[:todo]) - t.cursorX += todo - line = line[todo:] - - if t.cursorX == t.termWidth { - t.cursorX = 0 - t.cursorY++ - if t.cursorY > t.maxLine { - t.maxLine = t.cursorY - } - } - } -} - -func (t *Terminal) Write(buf []byte) (n int, err error) { - t.lock.Lock() - defer t.lock.Unlock() - - if t.cursorX == 0 && t.cursorY == 0 { - // This is the easy case: there's nothing on the screen that we - // have to move out of the way. - return t.c.Write(buf) - } - - // We have a prompt and possibly user input on the screen. We - // have to clear it first. - t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */) - t.cursorX = 0 - t.clearLineToRight() - - for t.cursorY > 0 { - t.move(1 /* up */, 0, 0, 0) - t.cursorY-- - t.clearLineToRight() - } - - if _, err = t.c.Write(t.outBuf); err != nil { - return - } - t.outBuf = t.outBuf[:0] - - if n, err = t.c.Write(buf); err != nil { - return - } - - t.queue([]byte(t.prompt)) - chars := len(t.prompt) - if t.echo { - t.queue(t.line) - chars += len(t.line) - } - t.cursorX = chars % t.termWidth - t.cursorY = chars / t.termWidth - t.moveCursorToPos(t.pos) - - if _, err = t.c.Write(t.outBuf); err != nil { - return - } - t.outBuf = t.outBuf[:0] - return -} - -// ReadPassword temporarily changes the prompt and reads a password, without -// echo, from the terminal. -func (t *Terminal) ReadPassword(prompt string) (line string, err error) { - t.lock.Lock() - defer t.lock.Unlock() - - oldPrompt := t.prompt - t.prompt = prompt - t.echo = false - - line, err = t.readLine() - - t.prompt = oldPrompt - t.echo = true - - return -} - -// ReadLine returns a line of input from the terminal. -func (t *Terminal) ReadLine() (line string, err error) { - t.lock.Lock() - defer t.lock.Unlock() - - return t.readLine() -} - -func (t *Terminal) readLine() (line string, err error) { - // t.lock must be held at this point - - if t.cursorX == 0 && t.cursorY == 0 { - t.writeLine([]byte(t.prompt)) - t.c.Write(t.outBuf) - t.outBuf = t.outBuf[:0] - } - - for { - rest := t.remainder - lineOk := false - for !lineOk { - var key int - key, rest = bytesToKey(rest) - if key < 0 { - break - } - if key == keyCtrlD { - return "", io.EOF - } - line, lineOk = t.handleKey(key) - } - if len(rest) > 0 { - n := copy(t.inBuf[:], rest) - t.remainder = t.inBuf[:n] - } else { - t.remainder = nil - } - t.c.Write(t.outBuf) - t.outBuf = t.outBuf[:0] - if lineOk { - return - } - - // t.remainder is a slice at the beginning of t.inBuf - // containing a partial key sequence - readBuf := t.inBuf[len(t.remainder):] - var n int - - t.lock.Unlock() - n, err = t.c.Read(readBuf) - t.lock.Lock() - - if err != nil { - return - } - - t.remainder = t.inBuf[:n+len(t.remainder)] - } - panic("unreachable") -} - -// SetPrompt sets the prompt to be used when reading subsequent lines. -func (t *Terminal) SetPrompt(prompt string) { - t.lock.Lock() - defer t.lock.Unlock() - - t.prompt = prompt -} - -func (t *Terminal) SetSize(width, height int) { - t.lock.Lock() - defer t.lock.Unlock() - - t.termWidth, t.termHeight = width, height -} diff --git a/libgo/go/exp/terminal/terminal_test.go b/libgo/go/exp/terminal/terminal_test.go deleted file mode 100644 index a219721..0000000 --- a/libgo/go/exp/terminal/terminal_test.go +++ /dev/null @@ -1,110 +0,0 @@ -// 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 terminal - -import ( - "io" - "testing" -) - -type MockTerminal struct { - toSend []byte - bytesPerRead int - received []byte -} - -func (c *MockTerminal) Read(data []byte) (n int, err error) { - n = len(data) - if n == 0 { - return - } - if n > len(c.toSend) { - n = len(c.toSend) - } - if n == 0 { - return 0, io.EOF - } - if c.bytesPerRead > 0 && n > c.bytesPerRead { - n = c.bytesPerRead - } - copy(data, c.toSend[:n]) - c.toSend = c.toSend[n:] - return -} - -func (c *MockTerminal) Write(data []byte) (n int, err error) { - c.received = append(c.received, data...) - return len(data), nil -} - -func TestClose(t *testing.T) { - c := &MockTerminal{} - ss := NewTerminal(c, "> ") - line, err := ss.ReadLine() - if line != "" { - t.Errorf("Expected empty line but got: %s", line) - } - if err != io.EOF { - t.Errorf("Error should have been EOF but got: %s", err) - } -} - -var keyPressTests = []struct { - in string - line string - err error -}{ - { - "", - "", - io.EOF, - }, - { - "\r", - "", - nil, - }, - { - "foo\r", - "foo", - nil, - }, - { - "a\x1b[Cb\r", // right - "ab", - nil, - }, - { - "a\x1b[Db\r", // left - "ba", - nil, - }, - { - "a\177b\r", // backspace - "b", - nil, - }, -} - -func TestKeyPresses(t *testing.T) { - for i, test := range keyPressTests { - for j := 0; j < len(test.in); j++ { - c := &MockTerminal{ - toSend: []byte(test.in), - bytesPerRead: j, - } - ss := NewTerminal(c, "> ") - line, err := ss.ReadLine() - if line != test.line { - t.Errorf("Line resulting from test %d (%d bytes per read) was '%s', expected '%s'", i, j, line, test.line) - break - } - if err != test.err { - t.Errorf("Error resulting from test %d (%d bytes per read) was '%v', expected '%v'", i, j, err, test.err) - break - } - } - } -} diff --git a/libgo/go/exp/terminal/util.go b/libgo/go/exp/terminal/util.go deleted file mode 100644 index 211f41d..0000000 --- a/libgo/go/exp/terminal/util.go +++ /dev/null @@ -1,118 +0,0 @@ -// 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. - -// +build linux - -// Package terminal provides support functions for dealing with terminals, as -// commonly found on UNIX systems. -// -// Putting a terminal into raw mode is the most common requirement: -// -// oldState, err := terminal.MakeRaw(0) -// if err != nil { -// panic(err) -// } -// defer terminal.Restore(0, oldState) -package terminal - -import ( - "io" - "syscall" - "unsafe" -) - -// State contains the state of a terminal. -type State struct { - termios syscall.Termios -} - -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal(fd int) bool { - var termios syscall.Termios - err := syscall.Tcgetattr(fd, &termios) - return err == nil -} - -// MakeRaw put the terminal connected to the given file descriptor into raw -// mode and returns the previous state of the terminal so that it can be -// restored. -func MakeRaw(fd int) (*State, error) { - var oldState State - if err := syscall.Tcgetattr(fd, &oldState.termios); err != nil { - return nil, err - } - - newState := oldState.termios - newState.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | syscall.IGNCR | syscall.IXON | syscall.IXOFF - newState.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG - if err := syscall.Tcsetattr(fd, syscall.TCSANOW, &newState); err != nil { - return nil, err - } - - return &oldState, nil -} - -// Restore restores the terminal connected to the given file descriptor to a -// previous state. -func Restore(fd int, state *State) error { - err := syscall.Tcsetattr(fd, syscall.TCSANOW, &state.termios) - return err -} - -//extern ioctl -func ioctl(int, int, unsafe.Pointer) int - -// GetSize returns the dimensions of the given terminal. -func GetSize(fd int) (width, height int, err error) { - var dimensions [4]uint16 - - if ioctl(fd, syscall.TIOCGWINSZ, unsafe.Pointer(&dimensions)) < 0 { - return -1, -1, syscall.GetErrno() - } - return int(dimensions[1]), int(dimensions[0]), nil -} - -// ReadPassword reads a line of input from a terminal without local echo. This -// is commonly used for inputting passwords and other sensitive data. The slice -// returned does not include the \n. -func ReadPassword(fd int) ([]byte, error) { - var oldState syscall.Termios - if err := syscall.Tcgetattr(fd, &oldState); err != nil { - return nil, err - } - - newState := oldState - newState.Lflag &^= syscall.ECHO - if err := syscall.Tcsetattr(fd, syscall.TCSANOW, &newState); err != nil { - return nil, err - } - - defer func() { - syscall.Tcsetattr(fd, syscall.TCSANOW, &oldState) - }() - - var buf [16]byte - var ret []byte - for { - n, err := syscall.Read(fd, buf[:]) - if err != nil { - return nil, err - } - if n == 0 { - if len(ret) == 0 { - return nil, io.EOF - } - break - } - if buf[n-1] == '\n' { - n-- - } - ret = append(ret, buf[:n]...) - if n < len(buf) { - break - } - } - - return ret, nil -} |