sijms / go-ora

Pure go oracle client
MIT License
806 stars 175 forks source link

v2.7.5 is failing when building for windows #362

Closed elgs closed 1 year ago

elgs commented 1 year ago
~/code/go/gosqlapi$ GOOS="windows" GOARCH="arm64" go build
# github.com/sijms/go-ora/v2/network
../../../go/pkg/mod/github.com/sijms/go-ora/v2@v2.7.5/network/session.go:390:19: undefined: syscall.Sendmsg
../../../go/pkg/mod/github.com/sijms/go-ora/v2@v2.7.5/network/session.go:390:72: undefined: syscall.MSG_OOB
../../../go/pkg/mod/github.com/sijms/go-ora/v2@v2.7.5/network/session.go:395:29: cannot use int(file.Fd()) (value of type int) as syscall.Handle value in argument to syscall.SetNonblock
~/code/go/gosqlapi$ 
~/code/go/gosqlapi$ 
~/code/go/gosqlapi$ GOOS="windows" GOARCH="amd64" go build
# github.com/sijms/go-ora/v2/network
../../../go/pkg/mod/github.com/sijms/go-ora/v2@v2.7.5/network/session.go:390:19: undefined: syscall.Sendmsg
../../../go/pkg/mod/github.com/sijms/go-ora/v2@v2.7.5/network/session.go:390:72: undefined: syscall.MSG_OOB
../../../go/pkg/mod/github.com/sijms/go-ora/v2@v2.7.5/network/session.go:395:29: cannot use int(file.Fd()) (value of type int) as syscall.Handle value in argument to syscall.SetNonblock
sijms commented 1 year ago

ok I seem to be value conversion from int to handle can you change at you local environment and test?

elgs commented 1 year ago

Change from what to what at my local environment?

sijms commented 1 year ago

no problem I will test on a windows machine and fix in next release

elgs commented 1 year ago

You don't have to test it on a Windows machine. I got these errors on both macOS and Linux.

sijms commented 1 year ago

yes I know you can build windows on macOS and linux but I want to debug and see what is the cause of error. Any way I find the source of issue. the problem is related to send MSG_OOB the code that work with linux will fail to build with windows and I try to write a code for windows

if tcpConn, ok := conn.(*net.TCPConn); ok {
    if remoteAddr, ok := tcpConn.RemoteAddr().(*net.TCPAddr); ok {
        var to syscall.Sockaddr
        if len(remoteAddr.IP) == 4 {
            temp := (*[4]byte)(remoteAddr.IP)
            to = &syscall.SockaddrInet4{
                Port: remoteAddr.Port,
                Addr: *temp,
            }
        } else {
            temp := (*[16]byte)(remoteAddr.IP)
            to = &syscall.SockaddrInet6{
                Port:   remoteAddr.Port,
                ZoneId: 0,
                Addr:   *temp,
            }
        }
                // try to get a copy of internal socket object to send MSG_OOB
        var file *os.File
        file, err = tcpConn.File()
        if err != nil {
            return   // <----------------- return error not supported by windows
        }
        defer func(file *os.File) {
            _ = file.Close()
        }(file)
        var sent uint32
        var buf = syscall.WSABuf{Len: 1, Buf: &[]byte{33}[0]}

        err = syscall.WSASendto(syscall.Handle(file.Fd()), &buf, 1, &sent, 1, to, nil, nil)
        if err != nil {
            return
        }
        done = true
        err = syscall.SetNonblock(syscall.Handle(file.Fd()), true)
    }
} else {
    err = errors.New("not a tcp connection")
}
return

after debugging I find the source of error file net/fd_windows.go

func (fd *netFD) dup() (*os.File, error) {
    // TODO: Implement this

    return nil, syscall.EWINDOWS
}

so I return to old way for cancelling operation (windows version) fixed in v2.7.6

elgs commented 1 year ago

Thank you it works!