From 50e5951374bfea2c363c2181198980ca152bcf36 Mon Sep 17 00:00:00 2001 From: Alex Brainman Date: Wed, 23 May 2012 13:05:05 +1000 Subject: [PATCH] syscall: implement SetsockoptLinger for windows R=rsc CC=golang-dev https://golang.org/cl/6225048 --- api/next.txt | 2 ++ src/pkg/syscall/syscall_windows.go | 22 ++++++++++++++++-- src/pkg/syscall/zsyscall_windows_386.go | 27 +++++++++++++++++------ src/pkg/syscall/zsyscall_windows_amd64.go | 27 +++++++++++++++++------ 4 files changed, 62 insertions(+), 16 deletions(-) diff --git a/api/next.txt b/api/next.txt index 506f088616e..1279a7ace90 100644 --- a/api/next.txt +++ b/api/next.txt @@ -420,9 +420,11 @@ pkg syscall (windows-386), const CREATE_NEW_PROCESS_GROUP ideal-int pkg syscall (windows-386), const CTRL_BREAK_EVENT ideal-int pkg syscall (windows-386), const CTRL_C_EVENT ideal-int pkg syscall (windows-386), func GetCurrentProcessId() uint32 +pkg syscall (windows-386), func Getsockopt(Handle, int32, int32, *byte, *int32) error pkg syscall (windows-386), type SysProcAttr struct, CreationFlags uint32 pkg syscall (windows-amd64), const CREATE_NEW_PROCESS_GROUP ideal-int pkg syscall (windows-amd64), const CTRL_BREAK_EVENT ideal-int pkg syscall (windows-amd64), const CTRL_C_EVENT ideal-int pkg syscall (windows-amd64), func GetCurrentProcessId() uint32 +pkg syscall (windows-amd64), func Getsockopt(Handle, int32, int32, *byte, *int32) error pkg syscall (windows-amd64), type SysProcAttr struct, CreationFlags uint32 diff --git a/src/pkg/syscall/syscall_windows.go b/src/pkg/syscall/syscall_windows.go index 978da92ec2e..5074237eaec 100644 --- a/src/pkg/syscall/syscall_windows.go +++ b/src/pkg/syscall/syscall_windows.go @@ -441,6 +441,7 @@ func Chmod(path string, mode uint32) (err error) { //sys WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) [failretval==-1] = ws2_32.WSAIoctl //sys socket(af int32, typ int32, protocol int32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.socket //sys Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) [failretval==-1] = ws2_32.setsockopt +//sys Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) [failretval==-1] = ws2_32.getsockopt //sys bind(s Handle, name uintptr, namelen int32) (err error) [failretval==-1] = ws2_32.bind //sys connect(s Handle, name uintptr, namelen int32) (err error) [failretval==-1] = ws2_32.connect //sys getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==-1] = ws2_32.getsockname @@ -657,11 +658,23 @@ func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) func Sendto(fd Handle, p []byte, flags int, to Sockaddr) (err error) { return EWINDOWS } func SetsockoptTimeval(fd Handle, level, opt int, tv *Timeval) (err error) { return EWINDOWS } +// The Linger struct is wrong but we only noticed after Go 1. +// sysLinger is the real system call structure. + +// BUG(brainman): The definition of Linger is not appropriate for direct use +// with Setsockopt and Getsockopt. +// Use SetsockoptLinger instead. + type Linger struct { Onoff int32 Linger int32 } +type sysLinger struct { + Onoff uint16 + Linger uint16 +} + type IPMreq struct { Multiaddr [4]byte /* in_addr */ Interface [4]byte /* in_addr */ @@ -672,8 +685,13 @@ type IPv6Mreq struct { Interface uint32 } -func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, EWINDOWS } -func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) { return EWINDOWS } +func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, EWINDOWS } + +func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) { + sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)} + return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&sys)), int32(unsafe.Sizeof(sys))) +} + func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) { return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4) } diff --git a/src/pkg/syscall/zsyscall_windows_386.go b/src/pkg/syscall/zsyscall_windows_386.go index dd97f7fcd2f..6563e16b670 100644 --- a/src/pkg/syscall/zsyscall_windows_386.go +++ b/src/pkg/syscall/zsyscall_windows_386.go @@ -103,11 +103,13 @@ var ( procRegQueryInfoKeyW = modadvapi32.NewProc("RegQueryInfoKeyW") procRegEnumKeyExW = modadvapi32.NewProc("RegEnumKeyExW") procRegQueryValueExW = modadvapi32.NewProc("RegQueryValueExW") + procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId") procWSAStartup = modws2_32.NewProc("WSAStartup") procWSACleanup = modws2_32.NewProc("WSACleanup") procWSAIoctl = modws2_32.NewProc("WSAIoctl") procsocket = modws2_32.NewProc("socket") procsetsockopt = modws2_32.NewProc("setsockopt") + procgetsockopt = modws2_32.NewProc("getsockopt") procbind = modws2_32.NewProc("bind") procconnect = modws2_32.NewProc("connect") procgetsockname = modws2_32.NewProc("getsockname") @@ -142,7 +144,6 @@ var ( procOpenProcessToken = modadvapi32.NewProc("OpenProcessToken") procGetTokenInformation = modadvapi32.NewProc("GetTokenInformation") procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW") - procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId") ) func GetLastError() (lasterr error) { @@ -1180,6 +1181,12 @@ func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32 return } +func GetCurrentProcessId() (pid uint32) { + r0, _, _ := Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0) + pid = uint32(r0) + return +} + func WSAStartup(verreq uint32, data *WSAData) (sockerr error) { r0, _, _ := Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0) if r0 != 0 { @@ -1237,6 +1244,18 @@ func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32 return } +func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) { + r1, _, e1 := Syscall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen)), 0) + if int(r1) == -1 { + if e1 != 0 { + err = error(e1) + } else { + err = EINVAL + } + } + return +} + func bind(s Handle, name uintptr, namelen int32) (err error) { r1, _, e1 := Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) if int(r1) == -1 { @@ -1601,9 +1620,3 @@ func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) { } return } - -func GetCurrentProcessId() (pid uint32) { - r0, _, _ := Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0) - pid = uint32(r0) - return -} diff --git a/src/pkg/syscall/zsyscall_windows_amd64.go b/src/pkg/syscall/zsyscall_windows_amd64.go index a45c61defd1..13066305bad 100644 --- a/src/pkg/syscall/zsyscall_windows_amd64.go +++ b/src/pkg/syscall/zsyscall_windows_amd64.go @@ -103,11 +103,13 @@ var ( procRegQueryInfoKeyW = modadvapi32.NewProc("RegQueryInfoKeyW") procRegEnumKeyExW = modadvapi32.NewProc("RegEnumKeyExW") procRegQueryValueExW = modadvapi32.NewProc("RegQueryValueExW") + procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId") procWSAStartup = modws2_32.NewProc("WSAStartup") procWSACleanup = modws2_32.NewProc("WSACleanup") procWSAIoctl = modws2_32.NewProc("WSAIoctl") procsocket = modws2_32.NewProc("socket") procsetsockopt = modws2_32.NewProc("setsockopt") + procgetsockopt = modws2_32.NewProc("getsockopt") procbind = modws2_32.NewProc("bind") procconnect = modws2_32.NewProc("connect") procgetsockname = modws2_32.NewProc("getsockname") @@ -142,7 +144,6 @@ var ( procOpenProcessToken = modadvapi32.NewProc("OpenProcessToken") procGetTokenInformation = modadvapi32.NewProc("GetTokenInformation") procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW") - procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId") ) func GetLastError() (lasterr error) { @@ -1180,6 +1181,12 @@ func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32 return } +func GetCurrentProcessId() (pid uint32) { + r0, _, _ := Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0) + pid = uint32(r0) + return +} + func WSAStartup(verreq uint32, data *WSAData) (sockerr error) { r0, _, _ := Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0) if r0 != 0 { @@ -1237,6 +1244,18 @@ func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32 return } +func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) { + r1, _, e1 := Syscall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen)), 0) + if int(r1) == -1 { + if e1 != 0 { + err = error(e1) + } else { + err = EINVAL + } + } + return +} + func bind(s Handle, name uintptr, namelen int32) (err error) { r1, _, e1 := Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) if int(r1) == -1 { @@ -1601,9 +1620,3 @@ func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) { } return } - -func GetCurrentProcessId() (pid uint32) { - r0, _, _ := Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0) - pid = uint32(r0) - return -}