diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-01-12 01:31:45 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-01-12 01:31:45 +0000 |
commit | 9a0e3259f44ad2de9c65f14f756dab01b3598391 (patch) | |
tree | 86a3b8019380d5fad53258c4baba3dd9e1e7c736 /libgo/go/exp | |
parent | c6135f063335419e4b5df0b4e1caf145882c8a4b (diff) | |
download | gcc-9a0e3259f44ad2de9c65f14f756dab01b3598391.tar.gz |
libgo: Update to weekly.2011-12-14.
From-SVN: r183118
Diffstat (limited to 'libgo/go/exp')
-rw-r--r-- | libgo/go/exp/inotify/inotify_linux_test.go | 6 | ||||
-rw-r--r-- | libgo/go/exp/norm/normregtest.go | 8 | ||||
-rw-r--r-- | libgo/go/exp/sql/convert.go | 15 | ||||
-rw-r--r-- | libgo/go/exp/sql/convert_test.go | 4 | ||||
-rw-r--r-- | libgo/go/exp/sql/sql.go | 1 | ||||
-rw-r--r-- | libgo/go/exp/sql/sql_test.go | 13 | ||||
-rw-r--r-- | libgo/go/exp/ssh/client.go | 92 | ||||
-rw-r--r-- | libgo/go/exp/ssh/client_func_test.go | 2 | ||||
-rw-r--r-- | libgo/go/exp/ssh/session.go | 134 | ||||
-rw-r--r-- | libgo/go/exp/ssh/session_test.go | 264 | ||||
-rw-r--r-- | libgo/go/exp/types/gcimporter.go | 42 | ||||
-rw-r--r-- | libgo/go/exp/winfsnotify/winfsnotify.go | 22 | ||||
-rw-r--r-- | libgo/go/exp/winfsnotify/winfsnotify_test.go | 4 | ||||
-rw-r--r-- | libgo/go/exp/wingui/gui.go | 27 | ||||
-rw-r--r-- | libgo/go/exp/wingui/winapi.go | 20 | ||||
-rw-r--r-- | libgo/go/exp/wingui/zwinapi.go | 80 |
16 files changed, 549 insertions, 185 deletions
diff --git a/libgo/go/exp/inotify/inotify_linux_test.go b/libgo/go/exp/inotify/inotify_linux_test.go index a6bb46fe77d..92384b69376 100644 --- a/libgo/go/exp/inotify/inotify_linux_test.go +++ b/libgo/go/exp/inotify/inotify_linux_test.go @@ -57,7 +57,7 @@ func TestInotifyEvents(t *testing.T) { } // We expect this event to be received almost immediately, but let's wait 1 s to be sure - time.Sleep(1000e6) // 1000 ms + time.Sleep(1 * time.Second) if eventsReceived == 0 { t.Fatal("inotify event hasn't been received after 1 second") } @@ -69,7 +69,7 @@ func TestInotifyEvents(t *testing.T) { select { case <-done: t.Log("event channel closed") - case <-time.After(1e9): + case <-time.After(1 * time.Second): t.Fatal("event stream was not closed after 1 second") } } @@ -84,7 +84,7 @@ func TestInotifyClose(t *testing.T) { done = true }() - time.Sleep(50e6) // 50 ms + time.Sleep(50 * time.Millisecond) if !done { t.Fatal("double Close() test failed: second Close() call didn't return") } diff --git a/libgo/go/exp/norm/normregtest.go b/libgo/go/exp/norm/normregtest.go index d214ce11bc2..57ba7032981 100644 --- a/libgo/go/exp/norm/normregtest.go +++ b/libgo/go/exp/norm/normregtest.go @@ -177,7 +177,7 @@ func loadTestData() { } if test.r == 0 { // save for CharacterByCharacterTests - test.r = int(r) + test.r = rune(r) } var buf [utf8.UTFMax]byte sz := utf8.EncodeRune(buf[:], rune(r)) @@ -242,9 +242,9 @@ func doConformanceTests(t *Test, partn int) { func CharacterByCharacterTests() { tests := part[1].tests - last := 0 + var last rune = 0 for i := 0; i <= len(tests); i++ { // last one is special case - var r int + var r rune if i == len(tests) { r = 0x2FA1E // Don't have to go to 0x10FFFF } else { @@ -285,7 +285,7 @@ func PerformanceTest() { norm.NFC.Append(nil, buf...) success <- true }() - timeout := time.After(1e9) + timeout := time.After(1 * time.Second) select { case <-success: // test completed before the timeout diff --git a/libgo/go/exp/sql/convert.go b/libgo/go/exp/sql/convert.go index 24315a0d351..feb79aeafe0 100644 --- a/libgo/go/exp/sql/convert.go +++ b/libgo/go/exp/sql/convert.go @@ -95,35 +95,26 @@ func convertAssign(dest, src interface{}) error { switch dv.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: s := asString(src) - i64, err := strconv.ParseInt(s, 10, 64) + i64, err := strconv.ParseInt(s, 10, dv.Type().Bits()) if err != nil { return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err) } - if dv.OverflowInt(i64) { - return fmt.Errorf("string %q overflows %s", s, dv.Kind()) - } dv.SetInt(i64) return nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: s := asString(src) - u64, err := strconv.ParseUint(s, 10, 64) + u64, err := strconv.ParseUint(s, 10, dv.Type().Bits()) if err != nil { return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err) } - if dv.OverflowUint(u64) { - return fmt.Errorf("string %q overflows %s", s, dv.Kind()) - } dv.SetUint(u64) return nil case reflect.Float32, reflect.Float64: s := asString(src) - f64, err := strconv.ParseFloat(s, 64) + f64, err := strconv.ParseFloat(s, dv.Type().Bits()) if err != nil { return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err) } - if dv.OverflowFloat(f64) { - return fmt.Errorf("value %q overflows %s", s, dv.Kind()) - } dv.SetFloat(f64) return nil } diff --git a/libgo/go/exp/sql/convert_test.go b/libgo/go/exp/sql/convert_test.go index 52cee927241..bed09ffb29d 100644 --- a/libgo/go/exp/sql/convert_test.go +++ b/libgo/go/exp/sql/convert_test.go @@ -55,10 +55,10 @@ var conversionTests = []conversionTest{ // Strings to integers {s: "255", d: &scanuint8, wantuint: 255}, - {s: "256", d: &scanuint8, wanterr: `string "256" overflows uint8`}, + {s: "256", d: &scanuint8, wanterr: `converting string "256" to a uint8: strconv.ParseUint: parsing "256": value out of range`}, {s: "256", d: &scanuint16, wantuint: 256}, {s: "-1", d: &scanint, wantint: -1}, - {s: "foo", d: &scanint, wanterr: `converting string "foo" to a int: parsing "foo": invalid syntax`}, + {s: "foo", d: &scanint, wanterr: `converting string "foo" to a int: strconv.ParseInt: parsing "foo": invalid syntax`}, // True bools {s: true, d: &scanbool, wantbool: true}, diff --git a/libgo/go/exp/sql/sql.go b/libgo/go/exp/sql/sql.go index f17d12eaa13..948b911f2e0 100644 --- a/libgo/go/exp/sql/sql.go +++ b/libgo/go/exp/sql/sql.go @@ -134,6 +134,7 @@ func (db *DB) maxIdleConns() int { func (db *DB) conn() (driver.Conn, error) { db.mu.Lock() if db.closed { + db.mu.Unlock() return nil, errors.New("sql: database is closed") } if n := len(db.freeConn); n > 0 { diff --git a/libgo/go/exp/sql/sql_test.go b/libgo/go/exp/sql/sql_test.go index 4f8318d26ef..f8ccf764e73 100644 --- a/libgo/go/exp/sql/sql_test.go +++ b/libgo/go/exp/sql/sql_test.go @@ -228,3 +228,16 @@ func TestTxStmt(t *testing.T) { t.Fatalf("Commit = %v", err) } } + +// Tests fix for issue 2542, that we release a lock when querying on +// a closed connection. +func TestIssue2542Deadlock(t *testing.T) { + db := newTestDB(t, "people") + closeDB(t, db) + for i := 0; i < 2; i++ { + _, err := db.Query("SELECT|people|age,name|") + if err == nil { + t.Fatalf("expected error") + } + } +} diff --git a/libgo/go/exp/ssh/client.go b/libgo/go/exp/ssh/client.go index d89b908cdcf..7c862078b7e 100644 --- a/libgo/go/exp/ssh/client.go +++ b/libgo/go/exp/ssh/client.go @@ -187,10 +187,10 @@ func (c *ClientConn) mainLoop() { if err != nil { break } - // TODO(dfc) A note on blocking channel use. - // The msg, win, data and dataExt channels of a clientChan can - // cause this loop to block indefinately if the consumer does - // not service them. + // TODO(dfc) A note on blocking channel use. + // The msg, win, data and dataExt channels of a clientChan can + // cause this loop to block indefinately if the consumer does + // not service them. switch packet[0] { case msgChannelData: if len(packet) < 9 { @@ -200,7 +200,7 @@ func (c *ClientConn) mainLoop() { peersId := uint32(packet[1])<<24 | uint32(packet[2])<<16 | uint32(packet[3])<<8 | uint32(packet[4]) if length := int(packet[5])<<24 | int(packet[6])<<16 | int(packet[7])<<8 | int(packet[8]); length > 0 { packet = packet[9:] - c.getChan(peersId).stdout.data <- packet[:length] + c.getChan(peersId).stdout.handleData(packet[:length]) } case msgChannelExtendedData: if len(packet) < 13 { @@ -211,11 +211,11 @@ func (c *ClientConn) mainLoop() { datatype := uint32(packet[5])<<24 | uint32(packet[6])<<16 | uint32(packet[7])<<8 | uint32(packet[8]) if length := int(packet[9])<<24 | int(packet[10])<<16 | int(packet[11])<<8 | int(packet[12]); length > 0 { packet = packet[13:] - // RFC 4254 5.2 defines data_type_code 1 to be data destined + // RFC 4254 5.2 defines data_type_code 1 to be data destined // for stderr on interactive sessions. Other data types are // silently discarded. if datatype == 1 { - c.getChan(peersId).stderr.data <- packet[:length] + c.getChan(peersId).stderr.handleData(packet[:length]) } } default: @@ -228,12 +228,22 @@ func (c *ClientConn) mainLoop() { c.getChan(msg.PeersId).msg <- msg case *channelCloseMsg: ch := c.getChan(msg.PeersId) + ch.theyClosed = true close(ch.stdin.win) - close(ch.stdout.data) - close(ch.stderr.data) + ch.stdout.eof() + ch.stderr.eof() + close(ch.msg) + if !ch.weClosed { + ch.weClosed = true + ch.sendClose() + } c.chanlist.remove(msg.PeersId) case *channelEOFMsg: - c.getChan(msg.PeersId).msg <- msg + ch := c.getChan(msg.PeersId) + ch.stdout.eof() + // RFC 4254 is mute on how EOF affects dataExt messages but + // it is logical to signal EOF at the same time. + ch.stderr.eof() case *channelRequestSuccessMsg: c.getChan(msg.PeersId).msg <- msg case *channelRequestFailureMsg: @@ -242,6 +252,8 @@ func (c *ClientConn) mainLoop() { c.getChan(msg.PeersId).msg <- msg case *windowAdjustMsg: c.getChan(msg.PeersId).stdin.win <- int(msg.AdditionalBytes) + case *disconnectMsg: + break default: fmt.Printf("mainLoop: unhandled message %T: %v\n", msg, msg) } @@ -249,7 +261,7 @@ func (c *ClientConn) mainLoop() { } } -// Dial connects to the given network address using net.Dial and +// Dial connects to the given network address using net.Dial and // then initiates a SSH handshake, returning the resulting client connection. func Dial(network, addr string, config *ClientConfig) (*ClientConn, error) { conn, err := net.Dial(network, addr) @@ -259,18 +271,18 @@ func Dial(network, addr string, config *ClientConfig) (*ClientConn, error) { return Client(conn, config) } -// A ClientConfig structure is used to configure a ClientConn. After one has +// A ClientConfig structure is used to configure a ClientConn. After one has // been passed to an SSH function it must not be modified. type ClientConfig struct { - // Rand provides the source of entropy for key exchange. If Rand is - // nil, the cryptographic random reader in package crypto/rand will + // Rand provides the source of entropy for key exchange. If Rand is + // nil, the cryptographic random reader in package crypto/rand will // be used. Rand io.Reader // The username to authenticate. User string - // A slice of ClientAuth methods. Only the first instance + // A slice of ClientAuth methods. Only the first instance // of a particular RFC 4252 method will be used during authentication. Auth []ClientAuth @@ -285,7 +297,7 @@ func (c *ClientConfig) rand() io.Reader { return c.Rand } -// A clientChan represents a single RFC 4254 channel that is multiplexed +// A clientChan represents a single RFC 4254 channel that is multiplexed // over a single SSH connection. type clientChan struct { packetWriter @@ -294,10 +306,13 @@ type clientChan struct { stdout *chanReader // receives the payload of channelData messages stderr *chanReader // receives the payload of channelExtendedData messages msg chan interface{} // incoming messages + + theyClosed bool // indicates the close msg has been received from the remote side + weClosed bool // incidates the close msg has been sent from our side } // newClientChan returns a partially constructed *clientChan -// using the local id provided. To be usable clientChan.peersId +// using the local id provided. To be usable clientChan.peersId // needs to be assigned once known. func newClientChan(t *transport, id uint32) *clientChan { c := &clientChan{ @@ -320,8 +335,8 @@ func newClientChan(t *transport, id uint32) *clientChan { return c } -// waitForChannelOpenResponse, if successful, fills out -// the peerId and records any initial window advertisement. +// waitForChannelOpenResponse, if successful, fills out +// the peerId and records any initial window advertisement. func (c *clientChan) waitForChannelOpenResponse() error { switch msg := (<-c.msg).(type) { case *channelOpenConfirmMsg: @@ -335,13 +350,29 @@ func (c *clientChan) waitForChannelOpenResponse() error { return errors.New("unexpected packet") } -// Close closes the channel. This does not close the underlying connection. -func (c *clientChan) Close() error { +// sendEOF sends EOF to the server. RFC 4254 Section 5.3 +func (c *clientChan) sendEOF() error { + return c.writePacket(marshal(msgChannelEOF, channelEOFMsg{ + PeersId: c.peersId, + })) +} + +// sendClose signals the intent to close the channel. +func (c *clientChan) sendClose() error { return c.writePacket(marshal(msgChannelClose, channelCloseMsg{ PeersId: c.peersId, })) } +// Close closes the channel. This does not close the underlying connection. +func (c *clientChan) Close() error { + if !c.weClosed { + c.weClosed = true + return c.sendClose() + } + return nil +} + // Thread safe channel list. type chanlist struct { // protects concurrent access to chans @@ -413,7 +444,7 @@ func (w *chanWriter) Write(data []byte) (n int, err error) { } func (w *chanWriter) Close() error { - return w.clientChan.writePacket(marshal(msgChannelEOF, channelEOFMsg{w.clientChan.peersId})) + return w.clientChan.sendEOF() } // A chanReader represents stdout or stderr of a remote process. @@ -422,10 +453,27 @@ type chanReader struct { // If writes to this channel block, they will block mainLoop, making // it unable to receive new messages from the remote side. data chan []byte // receives data from remote + dataClosed bool // protects data from being closed twice clientChan *clientChan // the channel backing this reader buf []byte } +// eof signals to the consumer that there is no more data to be received. +func (r *chanReader) eof() { + if !r.dataClosed { + r.dataClosed = true + close(r.data) + } +} + +// handleData sends buf to the reader's consumer. If r.data is closed +// the data will be silently discarded +func (r *chanReader) handleData(buf []byte) { + if !r.dataClosed { + r.data <- buf + } +} + // Read reads data from the remote process's stdout or stderr. func (r *chanReader) Read(data []byte) (int, error) { var ok bool diff --git a/libgo/go/exp/ssh/client_func_test.go b/libgo/go/exp/ssh/client_func_test.go index 137456095a0..24e3a6334e5 100644 --- a/libgo/go/exp/ssh/client_func_test.go +++ b/libgo/go/exp/ssh/client_func_test.go @@ -6,7 +6,7 @@ package ssh // ClientConn functional tests. // These tests require a running ssh server listening on port 22 -// on the local host. Functional tests will be skipped unless +// on the local host. Functional tests will be skipped unless // -ssh.user and -ssh.pass must be passed to gotest. import ( diff --git a/libgo/go/exp/ssh/session.go b/libgo/go/exp/ssh/session.go index 23ea18c29ae..bf9a88e97ef 100644 --- a/libgo/go/exp/ssh/session.go +++ b/libgo/go/exp/ssh/session.go @@ -34,6 +34,20 @@ const ( SIGUSR2 Signal = "USR2" ) +var signals = map[Signal]int{ + SIGABRT: 6, + SIGALRM: 14, + SIGFPE: 8, + SIGHUP: 1, + SIGILL: 4, + SIGINT: 2, + SIGKILL: 9, + SIGPIPE: 13, + SIGQUIT: 3, + SIGSEGV: 11, + SIGTERM: 15, +} + // A Session represents a connection to a remote command or shell. type Session struct { // Stdin specifies the remote process's standard input. @@ -170,10 +184,17 @@ func (s *Session) Start(cmd string) error { return s.start() } -// Run runs cmd on the remote host and waits for it to terminate. -// Typically, the remote server passes cmd to the shell for -// interpretation. A Session only accepts one call to Run, -// Start or Shell. +// Run runs cmd on the remote host. Typically, the remote +// server passes cmd to the shell for interpretation. +// A Session only accepts one call to Run, Start or Shell. +// +// The returned error is nil if the command runs, has no problems +// copying stdin, stdout, and stderr, and exits with a zero exit +// status. +// +// If the command fails to run or doesn't complete successfully, the +// error is of type *ExitError. Other error types may be +// returned for I/O problems. func (s *Session) Run(cmd string) error { err := s.Start(cmd) if err != nil { @@ -233,6 +254,14 @@ func (s *Session) start() error { } // Wait waits for the remote command to exit. +// +// The returned error is nil if the command runs, has no problems +// copying stdin, stdout, and stderr, and exits with a zero exit +// status. +// +// If the command fails to run or doesn't complete successfully, the +// error is of type *ExitError. Other error types may be +// returned for I/O problems. func (s *Session) Wait() error { if !s.started { return errors.New("ssh: session not started") @@ -255,21 +284,40 @@ func (s *Session) Wait() error { } func (s *Session) wait() error { - for { - switch msg := (<-s.msg).(type) { + wm := Waitmsg{status: -1} + + // Wait for msg channel to be closed before returning. + for msg := range s.msg { + switch msg := msg.(type) { case *channelRequestMsg: - // TODO(dfc) improve this behavior to match os.Waitmsg switch msg.Request { case "exit-status": d := msg.RequestSpecificData - status := int(d[0])<<24 | int(d[1])<<16 | int(d[2])<<8 | int(d[3]) - if status > 0 { - return fmt.Errorf("remote process exited with %d", status) - } - return nil + wm.status = int(d[0])<<24 | int(d[1])<<16 | int(d[2])<<8 | int(d[3]) case "exit-signal": - // TODO(dfc) make a more readable error message - return fmt.Errorf("%v", msg.RequestSpecificData) + signal, rest, ok := parseString(msg.RequestSpecificData) + if !ok { + return fmt.Errorf("wait: could not parse request data: %v", msg.RequestSpecificData) + } + wm.signal = safeString(string(signal)) + + // skip coreDumped bool + if len(rest) == 0 { + return fmt.Errorf("wait: could not parse request data: %v", msg.RequestSpecificData) + } + rest = rest[1:] + + errmsg, rest, ok := parseString(rest) + if !ok { + return fmt.Errorf("wait: could not parse request data: %v", msg.RequestSpecificData) + } + wm.msg = safeString(string(errmsg)) + + lang, _, ok := parseString(rest) + if !ok { + return fmt.Errorf("wait: could not parse request data: %v", msg.RequestSpecificData) + } + wm.lang = safeString(string(lang)) default: return fmt.Errorf("wait: unexpected channel request: %v", msg) } @@ -277,7 +325,20 @@ func (s *Session) wait() error { return fmt.Errorf("wait: unexpected packet %T received: %v", msg, msg) } } - panic("unreachable") + if wm.status == 0 { + return nil + } + if wm.status == -1 { + // exit-status was never sent from server + if wm.signal == "" { + return errors.New("wait: remote command exited without exit status or exit signal") + } + wm.status = 128 + if _, ok := signals[Signal(wm.signal)]; ok { + wm.status += signals[Signal(wm.signal)] + } + } + return &ExitError{wm} } func (s *Session) stdin() error { @@ -391,3 +452,46 @@ func (c *ClientConn) NewSession() (*Session, error) { clientChan: ch, }, nil } + +// An ExitError reports unsuccessful completion of a remote command. +type ExitError struct { + Waitmsg +} + +func (e *ExitError) Error() string { + return e.Waitmsg.String() +} + +// Waitmsg stores the information about an exited remote command +// as reported by Wait. +type Waitmsg struct { + status int + signal string + msg string + lang string +} + +// ExitStatus returns the exit status of the remote command. +func (w Waitmsg) ExitStatus() int { + return w.status +} + +// Signal returns the exit signal of the remote command if +// it was terminated violently. +func (w Waitmsg) Signal() string { + return w.signal +} + +// Msg returns the exit message given by the remote command +func (w Waitmsg) Msg() string { + return w.msg +} + +// Lang returns the language tag. See RFC 3066 +func (w Waitmsg) Lang() string { + return w.lang +} + +func (w Waitmsg) String() string { + return fmt.Sprintf("Process exited with: %v. Reason was: %v (%v)", w.status, w.msg, w.signal) +} diff --git a/libgo/go/exp/ssh/session_test.go b/libgo/go/exp/ssh/session_test.go index d4818c29f70..a28ead08736 100644 --- a/libgo/go/exp/ssh/session_test.go +++ b/libgo/go/exp/ssh/session_test.go @@ -12,8 +12,10 @@ import ( "testing" ) +type serverType func(*channel) + // dial constructs a new test server and returns a *ClientConn. -func dial(t *testing.T) *ClientConn { +func dial(handler serverType, t *testing.T) *ClientConn { pw := password("tiger") serverConfig.PasswordCallback = func(user, pass string) bool { return user == "testuser" && pass == string(pw) @@ -50,27 +52,7 @@ func dial(t *testing.T) *ClientConn { continue } ch.Accept() - go func() { - defer ch.Close() - // this string is returned to stdout - shell := NewServerShell(ch, "golang") - shell.ReadLine() - type exitMsg struct { - PeersId uint32 - Request string - WantReply bool - Status uint32 - } - // TODO(dfc) converting to the concrete type should not be - // necessary to send a packet. - msg := exitMsg{ - PeersId: ch.(*channel).theirId, - Request: "exit-status", - WantReply: false, - Status: 0, - } - ch.(*channel).serverConn.writePacket(marshal(msgChannelRequest, msg)) - }() + go handler(ch.(*channel)) } t.Log("done") }() @@ -91,7 +73,7 @@ func dial(t *testing.T) *ClientConn { // Test a simple string is returned to session.Stdout. func TestSessionShell(t *testing.T) { - conn := dial(t) + conn := dial(shellHandler, t) defer conn.Close() session, err := conn.NewSession() if err != nil { @@ -116,7 +98,7 @@ func TestSessionShell(t *testing.T) { // Test a simple string is returned via StdoutPipe. func TestSessionStdoutPipe(t *testing.T) { - conn := dial(t) + conn := dial(shellHandler, t) defer conn.Close() session, err := conn.NewSession() if err != nil { @@ -147,3 +129,237 @@ func TestSessionStdoutPipe(t *testing.T) { t.Fatalf("Remote shell did not return expected string: expected=golang, actual=%s", actual) } } + +// Test non-0 exit status is returned correctly. +func TestExitStatusNonZero(t *testing.T) { + conn := dial(exitStatusNonZeroHandler, t) + defer conn.Close() + session, err := conn.NewSession() + if err != nil { + t.Fatalf("Unable to request new session: %s", err) + } + defer session.Close() + if err := session.Shell(); err != nil { + t.Fatalf("Unable to execute command: %s", err) + } + err = session.Wait() + if err == nil { + t.Fatalf("expected command to fail but it didn't") + } + e, ok := err.(*ExitError) + if !ok { + t.Fatalf("expected *ExitError but got %T", err) + } + if e.ExitStatus() != 15 { + t.Fatalf("expected command to exit with 15 but got %s", e.ExitStatus()) + } +} + +// Test 0 exit status is returned correctly. +func TestExitStatusZero(t *testing.T) { + conn := dial(exitStatusZeroHandler, t) + defer conn.Close() + session, err := conn.NewSession() + if err != nil { + t.Fatalf("Unable to request new session: %s", err) + } + defer session.Close() + + if err := session.Shell(); err != nil { + t.Fatalf("Unable to execute command: %s", err) + } + err = session.Wait() + if err != nil { + t.Fatalf("expected nil but got %s", err) + } +} + +// Test exit signal and status are both returned correctly. +func TestExitSignalAndStatus(t *testing.T) { + conn := dial(exitSignalAndStatusHandler, t) + defer conn.Close() + session, err := conn.NewSession() + if err != nil { + t.Fatalf("Unable to request new session: %s", err) + } + defer session.Close() + if err := session.Shell(); err != nil { + t.Fatalf("Unable to execute command: %s", err) + } + err = session.Wait() + if err == nil { + t.Fatalf("expected command to fail but it didn't") + } + e, ok := err.(*ExitError) + if !ok { + t.Fatalf("expected *ExitError but got %T", err) + } + if e.Signal() != "TERM" || e.ExitStatus() != 15 { + t.Fatalf("expected command to exit with signal TERM and status 15 but got signal %s and status %v", e.Signal(), e.ExitStatus()) + } +} + +// Test exit signal and status are both returned correctly. +func TestKnownExitSignalOnly(t *testing.T) { + conn := dial(exitSignalHandler, t) + defer conn.Close() + session, err := conn.NewSession() + if err != nil { + t.Fatalf("Unable to request new session: %s", err) + } + defer session.Close() + if err := session.Shell(); err != nil { + t.Fatalf("Unable to execute command: %s", err) + } + err = session.Wait() + if err == nil { + t.Fatalf("expected command to fail but it didn't") + } + e, ok := err.(*ExitError) + if !ok { + t.Fatalf("expected *ExitError but got %T", err) + } + if e.Signal() != "TERM" || e.ExitStatus() != 143 { + t.Fatalf("expected command to exit with signal TERM and status 143 but got signal %s and status %v", e.Signal(), e.ExitStatus()) + } +} + +// Test exit signal and status are both returned correctly. +func TestUnknownExitSignal(t *testing.T) { + conn := dial(exitSignalUnknownHandler, t) + defer conn.Close() + session, err := conn.NewSession() + if err != nil { + t.Fatalf("Unable to request new session: %s", err) + } + defer session.Close() + if err := session.Shell(); err != nil { + t.Fatalf("Unable to execute command: %s", err) + } + err = session.Wait() + if err == nil { + t.Fatalf("expected command to fail but it didn't") + } + e, ok := err.(*ExitError) + if !ok { + t.Fatalf("expected *ExitError but got %T", err) + } + if e.Signal() != "SYS" || e.ExitStatus() != 128 { + t.Fatalf("expected command to exit with signal SYS and status 128 but got signal %s and status %v", e.Signal(), e.ExitStatus()) + } +} + +// Test WaitMsg is not returned if the channel closes abruptly. +func TestExitWithoutStatusOrSignal(t *testing.T) { + conn := dial(exitWithoutSignalOrStatus, t) + defer conn.Close() + session, err := conn.NewSession() + if err != nil { + t.Fatalf("Unable to request new session: %s", err) + } + defer session.Close() + if err := session.Shell(); err != nil { + t.Fatalf("Unable to execute command: %s", err) + } + err = session.Wait() + if err == nil { + t.Fatalf("expected command to fail but it didn't") + } + _, ok := err.(*ExitError) + if ok { + // you can't actually test for errors.errorString + // because it's not exported. + t.Fatalf("expected *errorString but got %T", err) + } +} + +type exitStatusMsg struct { + PeersId uint32 + Request string + WantReply bool + Status uint32 +} + +type exitSignalMsg struct { + PeersId uint32 + Request string + WantReply bool + Signal string + CoreDumped bool + Errmsg string + Lang string +} + +func exitStatusZeroHandler(ch *channel) { + defer ch.Close() + // this string is returned to stdout + shell := NewServerShell(ch, "> ") + shell.ReadLine() + sendStatus(0, ch) +} + +func exitStatusNonZeroHandler(ch *channel) { + defer ch.Close() + shell := NewServerShell(ch, "> ") + shell.ReadLine() + sendStatus(15, ch) +} + +func exitSignalAndStatusHandler(ch *channel) { + defer ch.Close() + shell := NewServerShell(ch, "> ") + shell.ReadLine() + sendStatus(15, ch) + sendSignal("TERM", ch) +} + +func exitSignalHandler(ch *channel) { + defer ch.Close() + shell := NewServerShell(ch, "> ") + shell.ReadLine() + sendSignal("TERM", ch) +} + +func exitSignalUnknownHandler(ch *channel) { + defer ch.Close() + shell := NewServerShell(ch, "> ") + shell.ReadLine() + sendSignal("SYS", ch) +} + +func exitWithoutSignalOrStatus(ch *channel) { + defer ch.Close() + shell := NewServerShell(ch, "> ") + shell.ReadLine() +} + +func shellHandler(ch *channel) { + defer ch.Close() + // this string is returned to stdout + shell := NewServerShell(ch, "golang") + shell.ReadLine() + sendStatus(0, ch) +} + +func sendStatus(status uint32, ch *channel) { + msg := exitStatusMsg{ + PeersId: ch.theirId, + Request: "exit-status", + WantReply: false, + Status: status, + } + ch.serverConn.writePacket(marshal(msgChannelRequest, msg)) +} + +func sendSignal(signal string, ch *channel) { + sig := exitSignalMsg{ + PeersId: ch.theirId, + Request: "exit-signal", + WantReply: false, + Signal: signal, + CoreDumped: false, + Errmsg: "Process terminated", + Lang: "en-GB-oed", + } + ch.serverConn.writePacket(marshal(msgChannelRequest, sig)) +} diff --git a/libgo/go/exp/types/gcimporter.go b/libgo/go/exp/types/gcimporter.go index 6adcc2a9ad2..10c56db21ff 100644 --- a/libgo/go/exp/types/gcimporter.go +++ b/libgo/go/exp/types/gcimporter.go @@ -81,7 +81,7 @@ type gcParser struct { func (p *gcParser) init(filename, id string, src io.Reader, imports map[string]*ast.Object) { p.scanner.Init(src) p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) } - p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments + p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanChars | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments p.scanner.Whitespace = 1<<'\t' | 1<<' ' p.scanner.Filename = filename // for good error messages p.next() @@ -145,18 +145,14 @@ func GcImporter(imports map[string]*ast.Object, path string) (pkg *ast.Object, e // Declare inserts a named object of the given kind in scope. func (p *gcParser) declare(scope *ast.Scope, kind ast.ObjKind, name string) *ast.Object { - // a type may have been declared before - if it exists - // already in the respective package scope, return that - // type - if kind == ast.Typ { - if obj := scope.Lookup(name); obj != nil { - assert(obj.Kind == ast.Typ) - return obj - } + // the object may have been imported before - if it exists + // already in the respective package scope, return that object + if obj := scope.Lookup(name); obj != nil { + assert(obj.Kind == kind) + return obj } - // any other object must be a newly declared object - - // create it and insert it into the package scope + // otherwise create a new object and insert it into the package scope obj := ast.NewObj(kind, name) if scope.Insert(obj) != nil { p.errorf("already declared: %v %s", kind, obj.Name) @@ -199,14 +195,15 @@ func (p *gcParser) errorf(format string, args ...interface{}) { func (p *gcParser) expect(tok rune) string { lit := p.lit if p.tok != tok { - p.errorf("expected %q, got %q (%q)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit) + panic(1) + p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit) } p.next() return lit } func (p *gcParser) expectSpecial(tok string) { - sep := rune('x') // not white space + sep := 'x' // not white space i := 0 for i < len(tok) && p.tok == rune(tok[i]) && sep > ' ' { sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token @@ -261,7 +258,7 @@ func (p *gcParser) parsePkgId() *ast.Object { func (p *gcParser) parseDotIdent() string { ident := "" if p.tok != scanner.Int { - sep := rune('x') // not white space + sep := 'x' // not white space for (p.tok == scanner.Ident || p.tok == scanner.Int || p.tok == 'ยท') && sep > ' ' { ident += p.lit sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token @@ -645,6 +642,7 @@ func (p *gcParser) parseNumber() Const { // Literal = bool_lit | int_lit | float_lit | complex_lit | string_lit . // bool_lit = "true" | "false" . // complex_lit = "(" float_lit "+" float_lit ")" . +// rune_lit = "(" int_lit "+" int_lit ")" . // string_lit = `"` { unicode_char } `"` . // func (p *gcParser) parseConstDecl() { @@ -674,21 +672,33 @@ func (p *gcParser) parseConstDecl() { typ = Float64.Underlying } case '(': - // complex_lit + // complex_lit or rune_lit p.next() + if p.tok == scanner.Char { + p.next() + p.expect('+') + p.parseNumber() + p.expect(')') + // TODO: x = ... + break + } re := p.parseNumber() p.expect('+') im := p.parseNumber() p.expect(')') x = Const{cmplx{re.val.(*big.Rat), im.val.(*big.Rat)}} typ = Complex128.Underlying + case scanner.Char: + // TODO: x = ... + p.next() case scanner.String: // string_lit x = MakeConst(token.STRING, p.lit) p.next() typ = String.Underlying default: - p.error("expected literal") + println(p.tok) + p.errorf("expected literal got %s", scanner.TokenString(p.tok)) } if obj.Type == nil { obj.Type = typ diff --git a/libgo/go/exp/winfsnotify/winfsnotify.go b/libgo/go/exp/winfsnotify/winfsnotify.go index d133740304b..d47ffd13921 100644 --- a/libgo/go/exp/winfsnotify/winfsnotify.go +++ b/libgo/go/exp/winfsnotify/winfsnotify.go @@ -75,7 +75,7 @@ type Watcher struct { // NewWatcher creates and returns a Watcher. func NewWatcher() (*Watcher, error) { port, e := syscall.CreateIoCompletionPort(syscall.InvalidHandle, 0, 0, 0) - if e != 0 { + if e != nil { return nil, os.NewSyscallError("CreateIoCompletionPort", e) } w := &Watcher{ @@ -147,7 +147,7 @@ func (w *Watcher) RemoveWatch(path string) error { func (w *Watcher) wakeupReader() error { e := syscall.PostQueuedCompletionStatus(w.port, 0, 0, nil) - if e != 0 { + if e != nil { return os.NewSyscallError("PostQueuedCompletionStatus", e) } return nil @@ -155,7 +155,7 @@ func (w *Watcher) wakeupReader() error { func getDir(pathname string) (dir string, err error) { attr, e := syscall.GetFileAttributes(syscall.StringToUTF16Ptr(pathname)) - if e != 0 { + if e != nil { return "", os.NewSyscallError("GetFileAttributes", e) } if attr&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 { @@ -173,11 +173,11 @@ func getIno(path string) (ino *inode, err error) { syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OVERLAPPED, 0) - if e != 0 { + if e != nil { return nil, os.NewSyscallError("CreateFile", e) } var fi syscall.ByHandleFileInformation - if e = syscall.GetFileInformationByHandle(h, &fi); e != 0 { + if e = syscall.GetFileInformationByHandle(h, &fi); e != nil { syscall.CloseHandle(h) return nil, os.NewSyscallError("GetFileInformationByHandle", e) } @@ -222,7 +222,7 @@ func (w *Watcher) addWatch(pathname string, flags uint64) error { } watchEntry := w.watches.get(ino) if watchEntry == nil { - if _, e := syscall.CreateIoCompletionPort(ino.handle, w.port, 0, 0); e != 0 { + if _, e := syscall.CreateIoCompletionPort(ino.handle, w.port, 0, 0); e != nil { syscall.CloseHandle(ino.handle) return os.NewSyscallError("CreateIoCompletionPort", e) } @@ -295,7 +295,7 @@ func (w *Watcher) deleteWatch(watch *watch) { // Must run within the I/O thread. func (w *Watcher) startRead(watch *watch) error { - if e := syscall.CancelIo(watch.ino.handle); e != 0 { + if e := syscall.CancelIo(watch.ino.handle); e != nil { w.Error <- os.NewSyscallError("CancelIo", e) w.deleteWatch(watch) } @@ -304,7 +304,7 @@ func (w *Watcher) startRead(watch *watch) error { mask |= toWindowsFlags(m) } if mask == 0 { - if e := syscall.CloseHandle(watch.ino.handle); e != 0 { + if e := syscall.CloseHandle(watch.ino.handle); e != nil { w.Error <- os.NewSyscallError("CloseHandle", e) } delete(w.watches[watch.ino.volume], watch.ino.index) @@ -312,7 +312,7 @@ func (w *Watcher) startRead(watch *watch) error { } e := syscall.ReadDirectoryChanges(watch.ino.handle, &watch.buf[0], uint32(unsafe.Sizeof(watch.buf)), false, mask, nil, &watch.ov, 0) - if e != 0 { + if e != nil { err := os.NewSyscallError("ReadDirectoryChanges", e) if e == syscall.ERROR_ACCESS_DENIED && watch.mask&provisional == 0 { // Watched directory was probably removed @@ -354,7 +354,7 @@ func (w *Watcher) readEvents() { } } var err error - if e := syscall.CloseHandle(w.port); e != 0 { + if e := syscall.CloseHandle(w.port); e != nil { err = os.NewSyscallError("CloseHandle", e) } close(w.Event) @@ -386,7 +386,7 @@ func (w *Watcher) readEvents() { default: w.Error <- os.NewSyscallError("GetQueuedCompletionPort", e) continue - case 0: + case nil: } var offset uint32 diff --git a/libgo/go/exp/winfsnotify/winfsnotify_test.go b/libgo/go/exp/winfsnotify/winfsnotify_test.go index fb2b825e68e..b9c43d9c006 100644 --- a/libgo/go/exp/winfsnotify/winfsnotify_test.go +++ b/libgo/go/exp/winfsnotify/winfsnotify_test.go @@ -21,7 +21,7 @@ func expect(t *testing.T, eventstream <-chan *Event, name string, mask uint32) { if event.Name != name || event.Mask != mask { t.Fatal("did not receive expected event") } - case <-time.After(1e9): + case <-time.After(1 * time.Second): t.Fatal("timed out waiting for event") } } @@ -108,7 +108,7 @@ func TestNotifyClose(t *testing.T) { done = true }() - time.Sleep(50e6) // 50 ms + time.Sleep(50 * time.Millisecond) if !done { t.Fatal("double Close() test failed: second Close() call didn't return") } diff --git a/libgo/go/exp/wingui/gui.go b/libgo/go/exp/wingui/gui.go index 5df2ee0faa1..d58421bcfa7 100644 --- a/libgo/go/exp/wingui/gui.go +++ b/libgo/go/exp/wingui/gui.go @@ -18,8 +18,9 @@ func abortf(format string, a ...interface{}) { os.Exit(1) } -func abortErrNo(funcname string, err int) { - abortf("%s failed: %d %s\n", funcname, err, syscall.Errstr(err)) +func abortErrNo(funcname string, err error) { + errno, _ := err.(syscall.Errno) + abortf("%s failed: %d %s\n", funcname, uint32(errno), err) } // global vars @@ -33,7 +34,7 @@ var ( func WndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintptr) { switch msg { case WM_CREATE: - var e int + var e error // CreateWindowEx bh, e = CreateWindowEx( 0, @@ -42,7 +43,7 @@ func WndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintpt WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON, 75, 70, 140, 25, hwnd, 1, mh, 0) - if e != 0 { + if e != nil { abortErrNo("CreateWindowEx", e) } fmt.Printf("button handle is %x\n", bh) @@ -51,7 +52,7 @@ func WndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintpt switch syscall.Handle(lparam) { case bh: e := PostMessage(hwnd, WM_CLOSE, 0, 0) - if e != 0 { + if e != nil { abortErrNo("PostMessage", e) } default: @@ -69,23 +70,23 @@ func WndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintpt } func rungui() int { - var e int + var e error // GetModuleHandle mh, e = GetModuleHandle(nil) - if e != 0 { + if e != nil { abortErrNo("GetModuleHandle", e) } // Get icon we're going to use. myicon, e := LoadIcon(0, IDI_APPLICATION) - if e != 0 { + if e != nil { abortErrNo("LoadIcon", e) } // Get cursor we're going to use. mycursor, e := LoadCursor(0, IDC_ARROW) - if e != 0 { + if e != nil { abortErrNo("LoadCursor", e) } @@ -104,7 +105,7 @@ func rungui() int { wc.MenuName = nil wc.ClassName = wcname wc.IconSm = myicon - if _, e := RegisterClassEx(&wc); e != 0 { + if _, e := RegisterClassEx(&wc); e != nil { abortErrNo("RegisterClassEx", e) } @@ -116,7 +117,7 @@ func rungui() int { WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 200, 0, 0, mh, 0) - if e != 0 { + if e != nil { abortErrNo("CreateWindowEx", e) } fmt.Printf("main window handle is %x\n", wh) @@ -125,7 +126,7 @@ func rungui() int { ShowWindow(wh, SW_SHOWDEFAULT) // UpdateWindow - if e := UpdateWindow(wh); e != 0 { + if e := UpdateWindow(wh); e != nil { abortErrNo("UpdateWindow", e) } @@ -133,7 +134,7 @@ func rungui() int { var m Msg for { r, e := GetMessage(&m, 0, 0, 0) - if e != 0 { + if e != nil { abortErrNo("GetMessage", e) } if r == 0 { diff --git a/libgo/go/exp/wingui/winapi.go b/libgo/go/exp/wingui/winapi.go index 08059df2b9d..24f3dd4d723 100644 --- a/libgo/go/exp/wingui/winapi.go +++ b/libgo/go/exp/wingui/winapi.go @@ -110,22 +110,22 @@ var ( IDI_INFORMATION = IDI_ASTERISK ) -//sys GetModuleHandle(modname *uint16) (handle syscall.Handle, errno int) = GetModuleHandleW -//sys RegisterClassEx(wndclass *Wndclassex) (atom uint16, errno int) = user32.RegisterClassExW -//sys CreateWindowEx(exstyle uint32, classname *uint16, windowname *uint16, style uint32, x int32, y int32, width int32, height int32, wndparent syscall.Handle, menu syscall.Handle, instance syscall.Handle, param uintptr) (hwnd syscall.Handle, errno int) = user32.CreateWindowExW +//sys GetModuleHandle(modname *uint16) (handle syscall.Handle, err error) = GetModuleHandleW +//sys RegisterClassEx(wndclass *Wndclassex) (atom uint16, err error) = user32.RegisterClassExW +//sys CreateWindowEx(exstyle uint32, classname *uint16, windowname *uint16, style uint32, x int32, y int32, width int32, height int32, wndparent syscall.Handle, menu syscall.Handle, instance syscall.Handle, param uintptr) (hwnd syscall.Handle, err error) = user32.CreateWindowExW //sys DefWindowProc(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (lresult uintptr) = user32.DefWindowProcW -//sys DestroyWindow(hwnd syscall.Handle) (errno int) = user32.DestroyWindow +//sys DestroyWindow(hwnd syscall.Handle) (err error) = user32.DestroyWindow //sys PostQuitMessage(exitcode int32) = user32.PostQuitMessage //sys ShowWindow(hwnd syscall.Handle, cmdshow int32) (wasvisible bool) = user32.ShowWindow -//sys UpdateWindow(hwnd syscall.Handle) (errno int) = user32.UpdateWindow -//sys GetMessage(msg *Msg, hwnd syscall.Handle, MsgFilterMin uint32, MsgFilterMax uint32) (ret int32, errno int) [failretval==-1] = user32.GetMessageW +//sys UpdateWindow(hwnd syscall.Handle) (err error) = user32.UpdateWindow +//sys GetMessage(msg *Msg, hwnd syscall.Handle, MsgFilterMin uint32, MsgFilterMax uint32) (ret int32, err error) [failretval==-1] = user32.GetMessageW //sys TranslateMessage(msg *Msg) (done bool) = user32.TranslateMessage //sys DispatchMessage(msg *Msg) (ret int32) = user32.DispatchMessageW -//sys LoadIcon(instance syscall.Handle, iconname *uint16) (icon syscall.Handle, errno int) = user32.LoadIconW -//sys LoadCursor(instance syscall.Handle, cursorname *uint16) (cursor syscall.Handle, errno int) = user32.LoadCursorW -//sys SetCursor(cursor syscall.Handle) (precursor syscall.Handle, errno int) = user32.SetCursor +//sys LoadIcon(instance syscall.Handle, iconname *uint16) (icon syscall.Handle, err error) = user32.LoadIconW +//sys LoadCursor(instance syscall.Handle, cursorname *uint16) (cursor syscall.Handle, err error) = user32.LoadCursorW +//sys SetCursor(cursor syscall.Handle) (precursor syscall.Handle, err error) = user32.SetCursor //sys SendMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (lresult uintptr) = user32.SendMessageW -//sys PostMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (errno int) = user32.PostMessageW +//sys PostMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (err error) = user32.PostMessageW func MakeIntResource(id uint16) *uint16 { return (*uint16)(unsafe.Pointer(uintptr(id))) diff --git a/libgo/go/exp/wingui/zwinapi.go b/libgo/go/exp/wingui/zwinapi.go index 38e93eea717..b062ca3372e 100644 --- a/libgo/go/exp/wingui/zwinapi.go +++ b/libgo/go/exp/wingui/zwinapi.go @@ -28,47 +28,41 @@ var ( procPostMessageW = moduser32.NewProc("PostMessageW") ) -func GetModuleHandle(modname *uint16) (handle syscall.Handle, errno int) { +func GetModuleHandle(modname *uint16) (handle syscall.Handle, err error) { r0, _, e1 := syscall.Syscall(procGetModuleHandleW.Addr(), 1, uintptr(unsafe.Pointer(modname)), 0, 0) handle = syscall.Handle(r0) if handle == 0 { if e1 != 0 { - errno = int(e1) + err = error(e1) } else { - errno = syscall.EINVAL + err = syscall.EINVAL } - } else { - errno = 0 } return } -func RegisterClassEx(wndclass *Wndclassex) (atom uint16, errno int) { +func RegisterClassEx(wndclass *Wndclassex) (atom uint16, err error) { r0, _, e1 := syscall.Syscall(procRegisterClassExW.Addr(), 1, uintptr(unsafe.Pointer(wndclass)), 0, 0) atom = uint16(r0) if atom == 0 { if e1 != 0 { - errno = int(e1) + err = error(e1) } else { - errno = syscall.EINVAL + err = syscall.EINVAL } - } else { - errno = 0 } return } -func CreateWindowEx(exstyle uint32, classname *uint16, windowname *uint16, style uint32, x int32, y int32, width int32, height int32, wndparent syscall.Handle, menu syscall.Handle, instance syscall.Handle, param uintptr) (hwnd syscall.Handle, errno int) { +func CreateWindowEx(exstyle uint32, classname *uint16, windowname *uint16, style uint32, x int32, y int32, width int32, height int32, wndparent syscall.Handle, menu syscall.Handle, instance syscall.Handle, param uintptr) (hwnd syscall.Handle, err error) { r0, _, e1 := syscall.Syscall12(procCreateWindowExW.Addr(), 12, uintptr(exstyle), uintptr(unsafe.Pointer(classname)), uintptr(unsafe.Pointer(windowname)), uintptr(style), uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(wndparent), uintptr(menu), uintptr(instance), uintptr(param)) hwnd = syscall.Handle(r0) if hwnd == 0 { if e1 != 0 { - errno = int(e1) + err = error(e1) } else { - errno = syscall.EINVAL + err = syscall.EINVAL } - } else { - errno = 0 } return } @@ -79,16 +73,14 @@ func DefWindowProc(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintp return } -func DestroyWindow(hwnd syscall.Handle) (errno int) { +func DestroyWindow(hwnd syscall.Handle) (err error) { r1, _, e1 := syscall.Syscall(procDestroyWindow.Addr(), 1, uintptr(hwnd), 0, 0) if int(r1) == 0 { if e1 != 0 { - errno = int(e1) + err = error(e1) } else { - errno = syscall.EINVAL + err = syscall.EINVAL } - } else { - errno = 0 } return } @@ -104,31 +96,27 @@ func ShowWindow(hwnd syscall.Handle, cmdshow int32) (wasvisible bool) { return } -func UpdateWindow(hwnd syscall.Handle) (errno int) { +func UpdateWindow(hwnd syscall.Handle) (err error) { r1, _, e1 := syscall.Syscall(procUpdateWindow.Addr(), 1, uintptr(hwnd), 0, 0) if int(r1) == 0 { if e1 != 0 { - errno = int(e1) + err = error(e1) } else { - errno = syscall.EINVAL + err = syscall.EINVAL } - } else { - errno = 0 } return } -func GetMessage(msg *Msg, hwnd syscall.Handle, MsgFilterMin uint32, MsgFilterMax uint32) (ret int32, errno int) { +func GetMessage(msg *Msg, hwnd syscall.Handle, MsgFilterMin uint32, MsgFilterMax uint32) (ret int32, err error) { r0, _, e1 := syscall.Syscall6(procGetMessageW.Addr(), 4, uintptr(unsafe.Pointer(msg)), uintptr(hwnd), uintptr(MsgFilterMin), uintptr(MsgFilterMax), 0, 0) ret = int32(r0) if ret == -1 { if e1 != 0 { - errno = int(e1) + err = error(e1) } else { - errno = syscall.EINVAL + err = syscall.EINVAL } - } else { - errno = 0 } return } @@ -145,47 +133,41 @@ func DispatchMessage(msg *Msg) (ret int32) { return } -func LoadIcon(instance syscall.Handle, iconname *uint16) (icon syscall.Handle, errno int) { +func LoadIcon(instance syscall.Handle, iconname *uint16) (icon syscall.Handle, err error) { r0, _, e1 := syscall.Syscall(procLoadIconW.Addr(), 2, uintptr(instance), uintptr(unsafe.Pointer(iconname)), 0) icon = syscall.Handle(r0) if icon == 0 { if e1 != 0 { - errno = int(e1) + err = error(e1) } else { - errno = syscall.EINVAL + err = syscall.EINVAL } - } else { - errno = 0 } return } -func LoadCursor(instance syscall.Handle, cursorname *uint16) (cursor syscall.Handle, errno int) { +func LoadCursor(instance syscall.Handle, cursorname *uint16) (cursor syscall.Handle, err error) { r0, _, e1 := syscall.Syscall(procLoadCursorW.Addr(), 2, uintptr(instance), uintptr(unsafe.Pointer(cursorname)), 0) cursor = syscall.Handle(r0) if cursor == 0 { if e1 != 0 { - errno = int(e1) + err = error(e1) } else { - errno = syscall.EINVAL + err = syscall.EINVAL } - } else { - errno = 0 } return } -func SetCursor(cursor syscall.Handle) (precursor syscall.Handle, errno int) { +func SetCursor(cursor syscall.Handle) (precursor syscall.Handle, err error) { r0, _, e1 := syscall.Syscall(procSetCursor.Addr(), 1, uintptr(cursor), 0, 0) precursor = syscall.Handle(r0) if precursor == 0 { if e1 != 0 { - errno = int(e1) + err = error(e1) } else { - errno = syscall.EINVAL + err = syscall.EINVAL } - } else { - errno = 0 } return } @@ -196,16 +178,14 @@ func SendMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr return } -func PostMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (errno int) { +func PostMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (err error) { r1, _, e1 := syscall.Syscall6(procPostMessageW.Addr(), 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0) if int(r1) == 0 { if e1 != 0 { - errno = int(e1) + err = error(e1) } else { - errno = syscall.EINVAL + err = syscall.EINVAL } - } else { - errno = 0 } return } |