]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: implement SetsockoptLinger for windows
authorAlex Brainman <alex.brainman@gmail.com>
Wed, 23 May 2012 03:05:05 +0000 (13:05 +1000)
committerAlex Brainman <alex.brainman@gmail.com>
Wed, 23 May 2012 03:05:05 +0000 (13:05 +1000)
R=rsc
CC=golang-dev
https://golang.org/cl/6225048

api/next.txt
src/pkg/syscall/syscall_windows.go
src/pkg/syscall/zsyscall_windows_386.go
src/pkg/syscall/zsyscall_windows_amd64.go

index 506f088616e13c72181481d321048451ae9f2292..1279a7ace902abf4a79738bbd4737b0ce01ea113 100644 (file)
@@ -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
index 978da92ec2e2c63d01835cc6bbd2b1f87a222e33..5074237eaecd1669c3de4f008cf531c94a8d8ef9 100644 (file)
@@ -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)
 }
index dd97f7fcd2fc3ff18935ecbb99ec016bdc603d57..6563e16b670d414e50542c83ad78d4b8618b583c 100644 (file)
@@ -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
-}
index a45c61defd1178378702b966a208bbf09072667f..13066305bada4ae8615a335cab07648d5663a16a 100644 (file)
@@ -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
-}