From e9d4328fadaebc7192c4c98a5f692d95b5682f8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E8=8B=B1=E6=9D=B0?= Date: Fri, 19 Jul 2024 15:17:20 +0800 Subject: [PATCH] feat(c/libuv): Add tcp, udp, poll, core, stream, err features feat(c/io): add libuv async io with io, tcp, udp, timer, dns, loop feat(c/io): add libuv async io with stream, req, handle feat(c/libuv): rename c/io to c/libuv, and improve errro, net, handle, stream feat(c/libuv): Add a libuv demo: echo_server refactor(c/libuv): Adjust comments and file names to accommodate merge --- c/libuv/error.go | 198 ++++++++++++++++++++ c/libuv/libuv.go | 460 +++++++++++++++++++++++++++++++++++++++-------- c/libuv/net.go | 256 ++++++++++++++++++++++++++ c/libuv/timer.go | 42 +++++ c/net/net.go | 13 ++ 5 files changed, 895 insertions(+), 74 deletions(-) create mode 100644 c/libuv/error.go create mode 100644 c/libuv/net.go create mode 100644 c/libuv/timer.go diff --git a/c/libuv/error.go b/c/libuv/error.go new file mode 100644 index 00000000..95ee68dd --- /dev/null +++ b/c/libuv/error.go @@ -0,0 +1,198 @@ +package libuv + +import ( + "github.com/goplus/llgo/c" + _ "unsafe" +) + +const ( + E2BIG Errno = iota + EACCES + EADDRINUSE + EADDRNOTAVAIL + EAFNOSUPPORT + EAGAIN + EAI_ADDRFAMILY + EAI_AGAIN + EAI_BADFLAGS + EAI_BADHINTS + EAI_CANCELED + EAI_FAIL + EAI_FAMILY + EAI_MEMORY + EAI_NODATA + EAI_NONAME + EAI_OVERFLOW + EAI_PROTOCOL + EAI_SERVICE + EAI_SOCKTYPE + EALREADY + EBADF + EBUSY + ECANCELED + ECHARSET + ECONNABORTED + ECONNREFUSED + ECONNRESET + EDESTADDRREQ + EEXIST + EFAULT + EFBIG + EHOSTUNREACH + EINTR + EINVAL + EIO + EISCONN + EISDIR + ELOOP + EMFILE + EMSGSIZE + ENAMETOOLONG + ENETDOWN + ENETUNREACH + ENFILE + ENOBUFS + ENODEV + ENOENT + ENOMEM + ENONET + ENOPROTOOPT + ENOSPC + ENOSYS + ENOTCONN + ENOTDIR + ENOTEMPTY + ENOTSOCK + ENOTSUP + EOVERFLOW + EPERM + EPIPE + EPROTO + EPROTONOSUPPORT + EPROTOTYPE + ERANGE + EROFS + ESHUTDOWN + ESPIPE + ESRCH + ETIMEDOUT + ETXTBSY + EXDEV + UNKNOWN + EOF + ENXIO + EMLINK + EHOSTDOWN + EREMOTEIO + ENOTTY + EFTYPE + EILSEQ + ESOCKTNOSUPPORT + ENODATA + EUNATCH + ERRNO_MAX +) + +//var errnoDescriptions = map[Errno]string{ +// E2BIG: "argument list too long", +// EACCES: "permission denied", +// EADDRINUSE: "address already in use", +// EADDRNOTAVAIL: "address not available", +// EAFNOSUPPORT: "address family not supported", +// EAGAIN: "resource temporarily unavailable", +// EAI_ADDRFAMILY: "address family not supported", +// EAI_AGAIN: "temporary failure", +// EAI_BADFLAGS: "bad ai_flags value", +// EAI_BADHINTS: "invalid value for hints", +// EAI_CANCELED: "request canceled", +// EAI_FAIL: "permanent failure", +// EAI_FAMILY: "ai_family not supported", +// EAI_MEMORY: "out of memory", +// EAI_NODATA: "no address", +// EAI_NONAME: "unknown node or service", +// EAI_OVERFLOW: "argument buffer overflow", +// EAI_PROTOCOL: "resolved protocol is unknown", +// EAI_SERVICE: "service not available for socket type", +// EAI_SOCKTYPE: "socket type not supported", +// EALREADY: "connection already in progress", +// EBADF: "bad file descriptor", +// EBUSY: "resource busy or locked", +// ECANCELED: "operation canceled", +// ECHARSET: "invalid Unicode character", +// ECONNABORTED: "software caused connection abort", +// ECONNREFUSED: "connection refused", +// ECONNRESET: "connection reset by peer", +// EDESTADDRREQ: "destination address required", +// EEXIST: "file already exists", +// EFAULT: "bad address in system call argument", +// EFBIG: "file too large", +// EHOSTUNREACH: "host is unreachable", +// EINTR: "interrupted system call", +// EINVAL: "invalid argument", +// EIO: "i/o error", +// EISCONN: "socket is already connected", +// EISDIR: "illegal operation on a directory", +// ELOOP: "too many symbolic links encountered", +// EMFILE: "too many open files", +// EMSGSIZE: "message too long", +// ENAMETOOLONG: "name too long", +// ENETDOWN: "network is down", +// ENETUNREACH: "network is unreachable", +// ENFILE: "file table overflow", +// ENOBUFS: "no buffer space available", +// ENODEV: "no such device", +// ENOENT: "no such file or directory", +// ENOMEM: "not enough memory", +// ENONET: "machine is not on the network", +// ENOPROTOOPT: "protocol not available", +// ENOSPC: "no space left on device", +// ENOSYS: "function not implemented", +// ENOTCONN: "socket is not connected", +// ENOTDIR: "not a directory", +// ENOTEMPTY: "directory not empty", +// ENOTSOCK: "socket operation on non-socket", +// ENOTSUP: "operation not supported on socket", +// EOVERFLOW: "value too large for defined data type", +// EPERM: "operation not permitted", +// EPIPE: "broken pipe", +// EPROTO: "protocol error", +// EPROTONOSUPPORT: "protocol not supported", +// EPROTOTYPE: "protocol wrong type for socket", +// ERANGE: "result too large", +// EROFS: "read-only file system", +// ESHUTDOWN: "cannot send after transport endpoint shutdown", +// ESPIPE: "invalid seek", +// ESRCH: "no such process", +// ETIMEDOUT: "connection timed out", +// ETXTBSY: "text file is busy", +// EXDEV: "cross-device link not permitted", +// UNKNOWN: "unknown error", +// EOF: "end of file", +// ENXIO: "no such device or address", +// EMLINK: "too many links", +// EHOSTDOWN: "host is down", +// EREMOTEIO: "remote I/O error", +// ENOTTY: "inappropriate ioctl for device", +// EFTYPE: "inappropriate file type or format", +// EILSEQ: "illegal byte sequence", +// ESOCKTNOSUPPORT: "socket type not supported", +// ENODATA: "no data available", +// EUNATCH: "protocol driver not attached", +//} + +type Errno c.Int + +//go:linkname TranslateSysError C.uv_translate_sys_error +func TranslateSysError(sysErrno c.Int) c.Int + +//go:linkname Strerror C.uv_strerror +func Strerror(err c.Int) *c.Char + +//go:linkname StrerrorR C.uv_strerror_r +func StrerrorR(err c.Int, buf *c.Char, bufLen uintptr) *c.Char + +//go:linkname ErrName C.uv_err_name +func ErrName(err c.Int) *c.Char + +//go:linkname ErrNameR C.uv_err_name_r +func ErrNameR(err c.Int, buf *c.Char, bufLen uintptr) *c.Char diff --git a/c/libuv/libuv.go b/c/libuv/libuv.go index 7ca9e964..004b223d 100644 --- a/c/libuv/libuv.go +++ b/c/libuv/libuv.go @@ -2,6 +2,7 @@ package libuv import ( "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/net" _ "unsafe" ) @@ -11,22 +12,183 @@ const ( // ---------------------------------------------- +const ( + LOOP_BLOCK_SIGNAL LoopOption = iota + METRICS_IDLE_TIME +) + const ( RUN_DEFAULT RunMode = iota RUN_ONCE RUN_NOWAIT ) -type RunMode int +const ( + UV_LEAVE_GROUP Membership = iota + UV_JOIN_GROUP +) + +const ( + UNKNOWN_HANDLE HandleType = iota + ASYNC + CHECK + FS_EVENT + FS_POLL + HANDLE + IDLE + NAMED_PIPE + POLL + PREPARE + PROCESS + STREAM + TCP + TIMER + TTY + UDP + SIGNAL + FILE + HANDLE_TYPE_MAX +) + +const ( + UNKNOWN_REQ ReqType = iota + REQ + CONNECT + WRITE + SHUTDOWN + UDP_SEND + FS + WORK + GETADDRINFO + GETNAMEINFO + RANDOM + REQ_TYPE_PRIVATE + REQ_TYPE_MAX +) + +type LoopOption c.Int + +type RunMode c.Int + +type Membership c.Int + +type HandleType c.Int + +type ReqType c.Int + +type Uv_File c.Int + +type OsSock c.Int + +type OsFd c.Int // ---------------------------------------------- /* Handle types. */ - type Loop struct { Unused [0]byte } +type Handle struct { + Unused [0]byte +} + +type Dir struct { + Unused [0]byte +} + +type Stream struct { + Unused [0]byte +} + +type Tcp struct { + Unused [0]byte +} + +type Udp struct { + Unused [0]byte +} + +type Pipe struct { + Unused [0]byte +} + +type Tty struct { + Unused [0]byte +} + +type Poll struct { + Unused [0]byte +} + +type Timer struct { + Unused [0]byte +} + +type Prepare struct { + Unused [0]byte +} + +type Check struct { + Unused [0]byte +} + +type Idle struct { + Unused [0]byte +} + +type Async struct { + Unused [0]byte +} + +type Process struct { + Unused [0]byte +} + +type FsEvent struct { + Unused [0]byte +} + +type FsPoll struct { + Unused [0]byte +} + +type Signal struct { + Unused [0]byte +} + +/* Request types. */ + +type Req struct { + Unused [0]byte +} + +type GetAddrInfo struct { + Unused [0]byte +} + +type GetNameInfo struct { + Unused [0]byte +} + +type Shutdown struct { + Unused [0]byte +} + +type Write struct { + Unused [0]byte +} + +type Connect struct { + Unused [0]byte +} + +type UdpSend struct { + Unused [0]byte +} + +// ---------------------------------------------- + type Buf struct { Base *c.Char Len uintptr @@ -36,93 +198,243 @@ type Buf struct { /* Function type */ +// llgo:type C +type MallocFunc func(size uintptr) c.Pointer + +// llgo:type C +type ReallocFunc func(ptr c.Pointer, size uintptr) c.Pointer + +// llgo:type C +type CallocFunc func(count uintptr, size uintptr) c.Pointer + +// llgo:type C +type FreeFunc func(ptr c.Pointer) + +// llgo:type C +type AllocCb func(handle *Handle, suggestedSize uintptr, buf *Buf) + +// llgo:type C +type ReadCb func(stream *Stream, nread c.Long, buf *Buf) + +// llgo:type C +type WriteCb func(req *Write, status c.Int) + +// llgo:type C +type GetaddrinfoCb func(req *GetAddrInfo, status c.Int, res *net.AddrInfo) + +// llgo:type C +type GetnameinfoCb func(req *GetNameInfo, status c.Int, hostname *c.Char, service *c.Char) + +// llgo:type C +type ConnectionCb func(server *Stream, status c.Int) + +// llgo:type C +type ShutdownCb func(req *Shutdown, status c.Int) + // llgo:type C type WalkCb func(handle *Handle, arg c.Pointer) // ---------------------------------------------- -/* Loop related functions and method. */ +//go:linkname Version C.uv_version +func Version() c.Uint -//go:linkname LoopSize C.uv_loop_size -func LoopSize() uintptr +//go:linkname VersionString C.uv_version_string +func VersionString() *c.Char -// llgo:link (*Loop).Init C.uv_loop_init -func (loop *Loop) Init() c.Int { - return 0 -} +//go:linkname LibraryShutdown C.uv_library_shutdown +func LibraryShutdown() -// llgo:link (*Loop).Run C.uv_loop_run -func (l *Loop) Run(mode c.Int) c.Int { - return 0 -} +//go:linkname ReplaceAllocator C.uv_replace_allocator +func ReplaceAllocator(mallocFunc MallocFunc, reallocFunc ReallocFunc, callocFunc CallocFunc, freeFunc FreeFunc) c.Int -// llgo:link (*Loop).Stop C.uv_loop_stop -func (l *Loop) Stop() { - return -} +// ---------------------------------------------- -// llgo:link (*Loop).Default C.uv_default_loop -func (l *Loop) Default() *Loop { - return nil -} - -// llgo:link (*Loop).New C.uv_loop_new -func (l *Loop) New() *Loop { - return nil -} - -// Deprecated: use LoopClose instead. -// llgo:link (*Loop).Delete C.uv_loop_delete -func (l *Loop) Delete() { - return -} - -// llgo:link (*Loop).Alive C.uv_loop_alive -func (l *Loop) Alive() c.Int { - return 0 -} - -// llgo:link (*Loop).Close C.uv_loop_close -func (l *Loop) Close() c.Int { - return 0 -} - -// llgo:link (*Loop).Configure C.uv_loop_configure -func (l *Loop) Configure(loop *Loop, option c.Int, arg c.Int) c.Int { - return 0 -} - -// llgo:link (*Loop).Walk C.uv_walk -func (loop *Loop) Walk(walkCb WalkCb, arg c.Pointer) {} - -// llgo:link (*Loop).Fork C.uv_loop_fork -func (l *Loop) Fork(loop *Loop) int { - return 0 -} - -// llgo:link (*Loop).UpdateTime C.uv_update_time -func (l *Loop) UpdateTime() { - return -} - -// llgo:link (*Loop).Now C.uv_now -func (l *Loop) Now() uint64 { - return 0 -} - -// llgo:link (*Loop).BackendFd C.uv_backend_fd -func (l *Loop) BackendFd() int { - return 0 -} - -// llgo:link (*Loop).BackendTimeout C.uv_backend_timeout -func (l *Loop) BackendTimeout() int { +// llgo:link (*Shutdown).Shutdown C.uv_shutdown +func (shutdown *Shutdown) Shutdown(stream *Stream, shutdownCb ShutdownCb) c.Int { return 0 } // ---------------------------------------------- -/* Buf related functions and method. */ +/* HandleT related function and method */ + +// llgo:link (*Handle).Ref C.uv_ref +func (handle *Handle) Ref() {} + +// llgo:link (*Handle).Unref C.uv_unref +func (handle *Handle) Unref() {} + +// llgo:link (*Handle).HasRef C.uv_has_ref +func (handle *Handle) HasRef() c.Int { + return 0 +} + +//go:linkname HandleSize C.uv_handle_size +func HandleSize(handleType HandleType) uintptr + +// llgo:link (*Handle).GetType C.uv_handle_get_type +func (handle *Handle) GetType() HandleType { + return 0 +} + +//go:linkname HandleTypeName C.uv_handle_type_name +func HandleTypeName(handleType HandleType) *c.Char + +// llgo:link (*Handle).GetData C.uv_handle_get_data +func (handle *Handle) GetData() c.Pointer { + return nil +} + +// llgo:link (*Handle).GetLoop C.uv_handle_get_loop +func (handle *Handle) GetLoop() *Loop { + return nil +} + +// llgo:link (*Handle).SetData C.uv_handle_set_data +func (handle *Handle) SetData(data c.Pointer) {} + +// llgo:link (*Handle).IsActive C.uv_is_active +func (handle *Handle) IsActive() c.Int { + return 0 +} + +// llgo:link (*Handle).Close C.uv_close +func (handle *Handle) Close(closeCb CloseCb) {} + +// llgo:link (*Handle).SendBufferSize C.uv_send_buffer_size +func (handle *Handle) SendBufferSize(value *c.Int) c.Int { + return 0 +} + +// llgo:link (*Handle).RecvBufferSize C.uv_recv_buffer_size +func (handle *Handle) RecvBufferSize(value *c.Int) c.Int { + return 0 +} + +// llgo:link (*Handle).Fileno C.uv_fileno +func (handle *Handle) Fileno(fd *OsFd) c.Int { + return 0 +} //go:linkname InitBuf C.uv_buf_init func InitBuf(base *c.Char, len c.Uint) Buf + +//go:linkname UvPipe C.uv_pipe +func UvPipe(fds [2]Uv_File, readFlags c.Int, writeFlags c.Int) c.Int { + return 0 +} + +//go:linkname Socketpair C.uv_socketpair +func Socketpair(_type c.Int, protocol c.Int, socketVector [2]OsSock, flag0 c.Int, flag1 c.Int) c.Int { + return 0 +} + +// llgo:link (*Handle).IsClosing C.uv_is_closing +func (handle *Handle) IsClosing() c.Int { + return 0 +} + +// ---------------------------------------------- + +/* Req related function and method */ + +//go:linkname ReqSize C.uv_req_size +func ReqSize(reqType ReqType) uintptr + +// llgo:link (*Req).GetData C.uv_req_get_data +func (req *Req) GetData() c.Pointer { + return nil +} + +// llgo:link (*Req).SetData C.uv_handle_set_data +func (req *Req) SetData(data c.Pointer) {} + +// llgo:link (*Req).GetType C.uv_req_get_type +func (req *Req) GetType() ReqType { + return 0 +} + +//go:linkname TypeName C.uv_req_type_name +func TypeName(reqType ReqType) *c.Char + +// ---------------------------------------------- + +/* Stream related function and method */ + +// llgo:link (*Stream).GetWriteQueueSize C.uv_stream_get_write_queue_size +func (stream *Stream) GetWriteQueueSize() uintptr { + return 0 +} + +// llgo:link (*Stream).Listen C.uv_listen +func (stream *Stream) Listen(backlog c.Int, connectionCb ConnectionCb) c.Int { + return 0 +} + +// llgo:link (*Stream).Accept C.uv_accept +func (server *Stream) Accept(client *Stream) c.Int { + return 0 +} + +// llgo:link (*Stream).StartRead C.uv_read_start +func (stream *Stream) StartRead(allocCb AllocCb, readCb ReadCb) c.Int { + return 0 +} + +// llgo:link (*Stream).StopRead C.uv_read_stop +func (stream *Stream) StopRead() c.Int { + return 0 +} + +// llgo:link (*Write).Write C.uv_write +func (req *Write) Write(stream *Stream, bufs []Buf, nbufs c.Uint, writeCb WriteCb) c.Int { + return 0 +} + +// llgo:link (*Write).Write2 C.uv_write2 +func (req *Write) Write2(stream *Stream, bufs []Buf, nbufs c.Uint, sendStream *Stream, writeCb WriteCb) c.Int { + return 0 +} + +// llgo:link (*Stream).TryWrite C.uv_try_write +func (stream *Stream) TryWrite(bufs []Buf, nbufs c.Uint) c.Int { + return 0 +} + +// llgo:link (*Stream).TryWrite2 C.uv_try_write2 +func (stream *Stream) TryWrite2(bufs []Buf, nbufs c.Uint, sendStream *Stream) c.Int { + return 0 +} + +// llgo:link (*Stream).IsReadable C.uv_is_readable +func (stream *Stream) IsReadable() c.Int { + return 0 +} + +// llgo:link (*Stream).IsWritable C.uv_is_writable +func (stream *Stream) IsWritable() c.Int { + return 0 +} + +// llgo:link (*Stream).SetBlocking C.uv_stream_set_blocking +func (stream *Stream) SetBlocking(blocking c.Int) c.Int { + return 0 +} + +// ---------------------------------------------- + +/* Getaddrinfo related function and method */ + +//go:linkname Getaddrinfo C.uv_getaddrinfo +func Getaddrinfo(loop *Loop, req *GetAddrInfo, getaddrinfoCb GetaddrinfoCb, node *c.Char, service *c.Char, hints *net.AddrInfo) c.Int + +//go:linkname Freeaddrinfo C.uv_freeaddrinfo +func Freeaddrinfo(addrInfo *net.AddrInfo) + +// ---------------------------------------------- + +/* Getnameinfo related function and method */ + +//go:linkname Getnameinfo C.uv_getnameinfo +func Getnameinfo(loop *Loop, req *GetNameInfo, getnameinfoCb GetnameinfoCb, addr *net.SockAddr, flags c.Int) c.Int diff --git a/c/libuv/net.go b/c/libuv/net.go new file mode 100644 index 00000000..1e5f7590 --- /dev/null +++ b/c/libuv/net.go @@ -0,0 +1,256 @@ +package libuv + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/net" + _ "unsafe" +) + +const ( + /* Used with uv_tcp_bind, when an IPv6 address is used. */ + TCP_IPV6ONLY TcpFlags = 1 +) + +/* + * UDP support. + */ +const ( + /* Disables dual stack mode. */ + UDP_IPV6ONLY UdpFlags = 1 + /* + * Indicates message was truncated because read buffer was too small. The + * remainder was discarded by the OS. Used in uv_udp_recv_cb. + */ + UDP_PARTIAL UdpFlags = 2 + /* + * Indicates if SO_REUSEADDR will be set when binding the handle. + * This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other + * Unix platforms, it sets the SO_REUSEADDR flag. What that means is that + * multiple threads or processes can bind to the same address without error + * (provided they all set the flag) but only the last one to bind will receive + * any traffic, in effect "stealing" the port from the previous listener. + */ + UDP_REUSEADDR UdpFlags = 4 + /* + * Indicates that the message was received by recvmmsg, so the buffer provided + * must not be freed by the recv_cb callback. + */ + UDP_MMSG_CHUNK UdpFlags = 8 + /* + * Indicates that the buffer provided has been fully utilized by recvmmsg and + * that it should now be freed by the recv_cb callback. When this flag is set + * in uv_udp_recv_cb, nread will always be 0 and addr will always be NULL. + */ + UDP_MMSG_FREE UdpFlags = 16 + /* + * Indicates if IP_RECVERR/IPV6_RECVERR will be set when binding the handle. + * This sets IP_RECVERR for IPv4 and IPV6_RECVERR for IPv6 UDP sockets on + * Linux. This stops the Linux kernel from suppressing some ICMP error + * messages and enables full ICMP error reporting for faster failover. + * This flag is no-op on platforms other than Linux. + */ + UDP_LINUX_RECVERR UdpFlags = 32 + /* + * Indicates that recvmmsg should be used, if available. + */ + UDP_RECVMMSG UdpFlags = 256 +) + +type TcpFlags c.Int + +type UdpFlags c.Int + +// ---------------------------------------------- + +/* Function type */ + +// llgo:type C +type CloseCb func(handle *Handle) + +// llgo:type C +type ConnectCb func(req *Connect, status c.Int) + +// llgo:type C +type UdpSendCb func(req *UdpSend, status c.Int) + +// llgo:type C +type UdpRecvCb func(handle *Udp, nread c.Long, buf *Buf, addr *net.SockAddr, flags c.Uint) + +// ---------------------------------------------- + +/* TcpT related function and method */ + +//go:linkname InitTcp C.uv_tcp_init +func InitTcp(loop *Loop, tcp *Tcp) c.Int + +//go:linkname InitTcpEx C.uv_tcp_init_ex +func InitTcpEx(loop *Loop, tcp *Tcp, flags c.Uint) c.Int + +// llgo:link (*Tcp).Open C.uv_tcp_open +func (tcp *Tcp) Open(sock OsSock) c.Int { + return 0 +} + +// llgo:link (*Tcp).Nodelay C.uv_tcp_nodelay +func (tcp *Tcp) Nodelay(enable c.Int) c.Int { + return 0 +} + +// llgo:link (*Tcp).KeepAlive C.uv_tcp_keepalive +func (tcp *Tcp) KeepAlive(enable c.Int, delay c.Uint) c.Int { + return 0 +} + +// llgo:link (*Tcp).SimultaneousAccepts C.uv_tcp_simultaneous_accepts +func (tcp *Tcp) SimultaneousAccepts(enable c.Int) c.Int { + return 0 +} + +// llgo:link (*Tcp).Bind C.uv_tcp_bind +func (tcp *Tcp) Bind(addr *net.SockAddr, flags c.Uint) c.Int { + return 0 +} + +// llgo:link (*Tcp).Getsockname C.uv_tcp_getsockname +func (tcp *Tcp) Getsockname(name *net.SockAddr, nameLen *c.Int) c.Int { + return 0 +} + +// llgo:link (*Tcp).Getpeername C.uv_tcp_getpeername +func (tcp *Tcp) Getpeername(name *net.SockAddr, nameLen *c.Int) c.Int { + return 0 +} + +// llgo:link (*Tcp).CloseReset C.uv_tcp_close_reset +func (tcp *Tcp) CloseReset(closeCb CloseCb) c.Int { + return 0 +} + +//go:linkname TcpConnect C.uv_tcp_connect +func TcpConnect(req *Connect, tcp *Tcp, addr *net.SockAddr, connectCb ConnectCb) c.Int + +// ---------------------------------------------- + +/* UdpT related function and method */ + +//go:linkname InitUdp C.uv_udp_init +func InitUdp(loop *Loop, udp *Udp) c.Int + +//go:linkname InitUdpEx C.uv_udp_init_ex +func InitUdpEx(loop *Loop, udp *Udp, flags c.Uint) c.Int + +// llgo:link (*Udp).Open C.uv_udp_open +func (udp *Udp) Open(sock OsSock) c.Int { + return 0 +} + +// llgo:link (*Udp).Bind C.uv_udp_bind +func (udp *Udp) Bind(addr *net.SockAddr, flags c.Uint) c.Int { + return 0 +} + +// llgo:link (*Udp).Connect C.uv_udp_connect +func (udp *Udp) Connect(addr *net.SockAddr) c.Int { + return 0 +} + +// llgo:link (*Udp).Getpeername C.uv_udp_getpeername +func (udp *Udp) Getpeername(name *net.SockAddr, nameLen *c.Int) c.Int { + return 0 +} + +// llgo:link (*Udp).Getsockname C.uv_udp_getsockname +func (udp *Udp) Getsockname(name *net.SockAddr, nameLen *c.Int) c.Int { + return 0 +} + +// llgo:link (*Udp).SetMembership C.uv_udp_set_membership +func (udp *Udp) SetMembership(multicastAddr *c.Char, interfaceAddr *c.Char, membership Membership) c.Int { + return 0 +} + +// llgo:link (*Udp).SourceMembership C.uv_udp_set_source_membership +func (udp *Udp) SourceMembership(multicastAddr *c.Char, interfaceAddr *c.Char, sourceAddr *c.Char, membership Membership) c.Int { + return 0 +} + +// llgo:link (*Udp).SetMulticastLoop C.uv_udp_set_multicast_loop +func (udp *Udp) SetMulticastLoop(on c.Int) c.Int { + return 0 +} + +// llgo:link (*Udp).SetMulticastTTL C.uv_udp_set_multicast_ttl +func (udp *Udp) SetMulticastTTL(ttl c.Int) c.Int { + return 0 +} + +// llgo:link (*Udp).SetMulticastInterface C.uv_udp_set_multicast_interface +func (udp *Udp) SetMulticastInterface(interfaceAddr *c.Char) c.Int { + return 0 +} + +// llgo:link (*Udp).SAetBroadcast C.uv_udp_set_broadcast +func (udp *Udp) SAetBroadcast(on c.Int) c.Int { + return 0 +} + +// llgo:link (*Udp).SetTTL C.uv_udp_set_ttl +func (udp *Udp) SetTTL(ttl c.Int) c.Int { + return 0 +} + +//go:linkname Send C.uv_udp_send +func Send(req *UdpSend, udp *Udp, bufs []Buf, nbufs c.Uint, addr *net.SockAddr, sendCb UdpSendCb) c.Int + +// llgo:link (*Udp).TrySend C.uv_udp_try_send +func (udp *Udp) TrySend(bufs []Buf, nbufs c.Uint, addr *net.SockAddr) c.Int { + return 0 +} + +// llgo:link (*Udp).RecvStart C.uv_udp_recv_start +func (udp *Udp) RecvStart(allocCb AllocCb, recvCb UdpRecvCb) c.Int { + return 0 +} + +// llgo:link (*Udp).UsingRecvmmsg C.uv_udp_using_recvmmsg +func (udp *Udp) UsingRecvmmsg() c.Int { + return 0 +} + +// llgo:link (*Udp).RecvStop C.uv_udp_recv_stop +func (udp *Udp) RecvStop() c.Int { + return 0 +} + +// llgo:link (*Udp).GetSendQueueSize C.uv_udp_get_send_queue_size +func (udp *Udp) GetSendQueueSize() uintptr { + return 0 +} + +// llgo:link (*Udp).GetSendQueueCount C.uv_udp_get_send_queue_count +func (udp *Udp) GetSendQueueCount() uintptr { + return 0 +} + +// ---------------------------------------------- + +//go:linkname Ip4Addr C.uv_ip4_addr +func Ip4Addr(ip *c.Char, port c.Int, addr *net.SockaddrIn) c.Int + +//go:linkname Ip6Addr C.uv_ip6_addr +func Ip6Addr(ip *c.Char, port c.Int, addr *net.SockaddrIn6) c.Int + +//go:linkname Ip4Name C.uv_ip4_name +func Ip4Name(src *net.SockaddrIn, dst *c.Char, size uintptr) c.Int + +//go:linkname Ip6Name C.uv_ip6_name +func Ip6Name(src *net.SockaddrIn6, dst *c.Char, size uintptr) c.Int + +//go:linkname IpName C.uv_ip_name +func IpName(src *net.SockAddr, dst *c.Char, size uintptr) c.Int + +//go:linkname InetNtop C.uv_inet_ntop +func InetNtop(af c.Int, src c.Pointer, dst *c.Char, size uintptr) c.Int + +//go:linkname InetPton C.uv_inet_pton +func InetPton(af c.Int, src *c.Char, dst c.Pointer) c.Int diff --git a/c/libuv/timer.go b/c/libuv/timer.go new file mode 100644 index 00000000..615da48b --- /dev/null +++ b/c/libuv/timer.go @@ -0,0 +1,42 @@ +package libuv + +import ( + "github.com/goplus/llgo/c" + _ "unsafe" +) + +// llgo:type C +type TimerCb func(timer *Timer) + +/* TimerT related function and method */ + +//go:linkname InitTimer C.uv_timer_init +func InitTimer(loop *Loop, timer *Timer) c.Int + +// llgo:link (*Timer).Start C.uv_timer_start +func (timer *Timer) Start(cb TimerCb, timeout uint64, repeat uint64) c.Int { + return 0 +} + +// llgo:link (*Timer).Stop C.uv_timer_stop +func (timer *Timer) Stop() c.Int { + return 0 +} + +// llgo:link (*Timer).Again C.uv_timer_again +func (timer *Timer) Again() c.Int { + return 0 +} + +// llgo:link (*Timer).SetRepeat C.uv_timer_set_repeat +func (timer *Timer) SetRepeat(repeat uint64) {} + +// llgo:link (*Timer).GetRepeat C.uv_timer_get_repeat +func (timer *Timer) GetRepeat() uint64 { + return 0 +} + +// llgo:link (*Timer).GetDueIn C.uv_timer_get_due_in +func (timer *Timer) GetDueIn() uint64 { + return 0 +} diff --git a/c/net/net.go b/c/net/net.go index 7b2608aa..0b794084 100644 --- a/c/net/net.go +++ b/c/net/net.go @@ -91,10 +91,23 @@ type SockaddrIn struct { Zero [8]c.Char } +type SockaddrIn6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo c.Uint + Addr In6Addr + ScopeId c.Uint +} + type InAddr struct { Addr c.Uint } +type In6Addr struct { + U6Addr [16]uint8 +} + type SockAddr struct { Len uint8 Family uint8