Merge pull request #657 from hackerchai/fix/c-libuv-missing-func

feat(c/libuv): Add libuv missing funcs & refactor go func style
This commit is contained in:
xushiwei
2024-08-07 15:04:52 +08:00
committed by GitHub
7 changed files with 231 additions and 131 deletions

View File

@@ -31,7 +31,7 @@ func main() {
libuv.FsOpen(loop, &openReq, c.Str("example.txt"), os.O_RDONLY, 0, onOpen)
// Run the loop
result := libuv.Run(loop, libuv.RUN_DEFAULT)
result := loop.Run(libuv.RUN_DEFAULT)
if result != 0 {
c.Fprintf(c.Stderr, c.Str("Error in Run: %s\n"), libuv.Strerror(libuv.Errno(result)))
@@ -43,14 +43,14 @@ func main() {
func onOpen(req *libuv.Fs) {
// Check for errors
if libuv.FsGetResult(req) < 0 {
c.Fprintf(c.Stderr, c.Str("Error opening file: %s\n"), libuv.Strerror(libuv.Errno(libuv.FsGetResult(req))))
libuv.LoopClose(loop)
if req.GetResult() < 0 {
c.Fprintf(c.Stderr, c.Str("Error opening file: %s\n"), libuv.Strerror(libuv.Errno(req.GetResult())))
loop.Close()
return
}
// Store the file descriptor
file = libuv.File(libuv.FsGetResult(req))
file = libuv.File(req.GetResult())
// Init buffer
iov = libuv.InitBuf((*c.Char)(unsafe.Pointer(&buffer[0])), c.Uint(unsafe.Sizeof(buffer)))
@@ -68,28 +68,28 @@ func readFile() {
readRes := libuv.FsRead(loop, &readReq, file, &iov, 1, -1, onRead)
if readRes != 0 {
c.Printf(c.Str("Error in FsRead: %s (code: %d)\n"), libuv.Strerror(libuv.Errno(readRes)), readRes)
libuv.FsReqCleanup(&readReq)
libuv.LoopClose(loop)
readReq.ReqCleanup()
loop.Close()
}
}
func onRead(req *libuv.Fs) {
// Cleanup the request
defer libuv.FsReqCleanup(req)
defer req.ReqCleanup()
// Check for errors
if libuv.FsGetResult(req) < 0 {
c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(libuv.Errno(libuv.FsGetResult(req))))
} else if libuv.FsGetResult(req) == 0 {
if req.GetResult() < 0 {
c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(libuv.Errno(req.GetResult())))
} else if req.GetResult() == 0 {
// Close the file
closeRes := libuv.FsClose(loop, &closeReq, libuv.File(libuv.FsGetResult(&openReq)), onClose)
closeRes := libuv.FsClose(loop, &closeReq, libuv.File(openReq.GetResult()), onClose)
if closeRes != 0 {
c.Printf(c.Str("Error in FsClose: %s (code: %d)\n"), libuv.Strerror(libuv.Errno(closeRes)), closeRes)
libuv.LoopClose(loop)
loop.Close()
return
}
} else {
c.Printf(c.Str("Read %d bytes\n"), libuv.FsGetResult(req))
c.Printf(c.Str("Read content: %.*s\n"), libuv.FsGetResult(req), (*c.Char)(unsafe.Pointer(&buffer[0])))
c.Printf(c.Str("Read %d bytes\n"), req.GetResult())
c.Printf(c.Str("Read content: %.*s\n"), req.GetResult(), (*c.Char)(unsafe.Pointer(&buffer[0])))
// Read the file again
readFile()
}
@@ -97,8 +97,8 @@ func onRead(req *libuv.Fs) {
func onClose(req *libuv.Fs) {
// Check for errors
if libuv.FsGetResult(req) < 0 {
c.Fprintf(c.Stderr, c.Str("Error closing file: %s\n"), libuv.Strerror(libuv.Errno(libuv.FsGetResult(req))))
if req.GetResult() < 0 {
c.Fprintf(c.Stderr, c.Str("Error closing file: %s\n"), libuv.Strerror(libuv.Errno(req.GetResult())))
} else {
c.Printf(c.Str("\nFile closed successfully.\n"))
}
@@ -106,10 +106,10 @@ func onClose(req *libuv.Fs) {
func cleanup() {
// Cleanup the requests
libuv.FsReqCleanup(&openReq)
libuv.FsReqCleanup(&closeReq)
openReq.ReqCleanup()
closeReq.ReqCleanup()
// Close the loop
result := libuv.LoopClose(loop)
result := loop.Close()
if result != 0 {
c.Fprintf(c.Stderr, c.Str("Error in LoopClose: %s\n"), libuv.Strerror(libuv.Errno(result)))
}

View File

@@ -31,14 +31,14 @@ func main() {
// Bind the server to the specified address and port
(&server).Bind((*net.SockAddr)(c.Pointer(&addr)), 0)
res := (*libuv.Stream)(&server).Listen(DEFAULT_BACKLOG, OnNewConnection)
res := (*libuv.Stream)(unsafe.Pointer(&server)).Listen(DEFAULT_BACKLOG, OnNewConnection)
if res != 0 {
c.Fprintf(c.Stderr, c.Str("Listen error: %s\n"), libuv.Strerror((libuv.Errno(res))))
c.Fprintf(c.Stderr, c.Str("Listen error: %s\n"), libuv.Strerror(libuv.Errno(res)))
return
}
// Start listening for incoming connections
libuv.Run(loop, libuv.RUN_DEFAULT)
loop.Run(libuv.RUN_DEFAULT)
}
func FreeWriteReq(req *libuv.Write) {
@@ -56,7 +56,7 @@ func AllocBuffer(handle *libuv.Handle, suggestedSize uintptr, buf *libuv.Buf) {
func EchoWrite(req *libuv.Write, status c.Int) {
if status != 0 {
c.Fprintf(c.Stderr, c.Str("Write error: %s\n"), libuv.Strerror((libuv.Errno(status))))
c.Fprintf(c.Stderr, c.Str("Write error: %s\n"), libuv.Strerror(libuv.Errno(status)))
}
FreeWriteReq(req)
}
@@ -77,8 +77,8 @@ func EchoRead(client *libuv.Stream, nread c.Long, buf *libuv.Buf) {
}
if nread < 0 {
// Handle read errors and EOF.
if (libuv.Errno)(nread) != libuv.EOF {
c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror((libuv.Errno)(nread)))
if libuv.Errno(nread) != libuv.EOF {
c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(libuv.Errno(nread)))
}
(*libuv.Handle)(c.Pointer(client)).Close(nil)
}
@@ -110,9 +110,9 @@ func OnNewConnection(server *libuv.Stream, status c.Int) {
}
// Accept the new connection and start reading data.
if server.Accept((*libuv.Stream)(client)) == 0 {
(*libuv.Stream)(client).StartRead(AllocBuffer, EchoRead)
if server.Accept((*libuv.Stream)(unsafe.Pointer(client))) == 0 {
(*libuv.Stream)(unsafe.Pointer(client)).StartRead(AllocBuffer, EchoRead)
} else {
(*libuv.Handle)(c.Pointer(client)).Close(nil)
(*libuv.Handle)(unsafe.Pointer(client)).Close(nil)
}
}

5
c/libuv/_wrap/libuv.c Normal file
View File

@@ -0,0 +1,5 @@
#include <uv.h>
int uv_tcp_get_io_watcher_fd (uv_tcp_t* handle) {
return handle->io_watcher.fd;
}

View File

@@ -106,29 +106,40 @@ type FsPollCb func(handle *FsPoll, status c.Int, events c.Int)
/* Fs related function and method */
//go:linkname FsGetType C.uv_fs_get_type
func FsGetType(req *Fs) FsType
// llgo:link (*Fs).GetType C.uv_fs_get_type
func (req *Fs) GetType() FsType {
return 0
}
//go:linkname FsGetPath C.uv_fs_get_path
func FsGetPath(req *Fs) *c.Char
// llgo:link (*Fs).GetPath C.uv_fs_get_path
func (req *Fs) GetPath() *c.Char {
return nil
}
//go:linkname FsGetResult C.uv_fs_get_result
func FsGetResult(req *Fs) c.Int
// llgo:link (*Fs).GetResult C.uv_fs_get_result
func (req *Fs) GetResult() c.Int {
return 0
}
//go:linkname FsGetPtr C.uv_fs_get_ptr
func FsGetPtr(req *Fs) c.Pointer
// llgo:link (*Fs).GetPtr C.uv_fs_get_ptr
func (req *Fs) GetPtr() c.Pointer {
return nil
}
//go:linkname FsGetSystemError C.uv_fs_get_system_error
func FsGetSystemError(req *Fs) c.Int
// llgo:link (*Fs).GetSystemError C.uv_fs_get_system_error
func (req *Fs) GetSystemError() c.Int {
return 0
}
//go:linkname FsGetStatBuf C.uv_fs_get_statbuf
func FsGetStatBuf(req *Fs) *Stat
// llgo:link (*Fs).GetStatBuf C.uv_fs_get_statbuf
func (req *Fs) GetStatBuf() *Stat {
return nil
}
//go:linkname FsReqCleanup C.uv_fs_req_cleanup
func FsReqCleanup(req *Fs)
//go:linkname DefaultLoop C.uv_default_loop
func DefaultLoop() *Loop
// llgo:link (*Fs).ReqCleanup C.uv_fs_req_cleanup
func (req *Fs) ReqCleanup() {
// No return value needed for this method
}
//go:linkname FsOpen C.uv_fs_open
func FsOpen(loop *Loop, req *Fs, path *c.Char, flags c.Int, mode c.Int, cb FsCb) c.Int
@@ -241,32 +252,56 @@ func FsLchown(loop *Loop, req *Fs, path *c.Char, uid c.Int, gid c.Int, cb FsCb)
//go:linkname FsLstat C.uv_fs_lstat
func FsLstat(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int
// ----------------------------------------------
/* FsEvent related function and method */
//go:linkname FsEventInit C.uv_fs_event_init
func FsEventInit(loop *Loop, handle *FsEvent) c.Int
//go:linkname FsEventStart C.uv_fs_event_start
func FsEventStart(handle *FsEvent, cb FsEventCb, path *c.Char, flags c.Int) c.Int
// llgo:link (*FsEvent).Start C.uv_fs_event_start
func (handle *FsEvent) Start(cb FsEventCb, path *c.Char, flags c.Int) c.Int {
return 0
}
//go:linkname FsEventStop C.uv_fs_event_stop
func FsEventStop(handle *FsEvent) c.Int
// llgo:link (*FsEvent).Stop C.uv_fs_event_stop
func (handle *FsEvent) Stop() c.Int {
return 0
}
//go:linkname FsEventClose C.uv_fs_event_close
func FsEventClose(handle *FsEvent) c.Int
// llgo:link (*FsEvent).Close C.uv_fs_event_close
func (handle *FsEvent) Close() c.Int {
return 0
}
//go:linkname FsEventGetpath C.uv_fs_event_getpath
func FsEventGetpath(handle *FsEvent) *c.Char
// llgo:link (*FsEvent).Getpath C.uv_fs_event_getpath
func (handle *FsEvent) Getpath() *c.Char {
return nil
}
// ----------------------------------------------
/* FsPoll related function and method */
//go:linkname FsPollInit C.uv_fs_poll_init
func FsPollInit(loop *Loop, handle *FsPoll) c.Int
//go:linkname FsPollStart C.uv_fs_poll_start
func FsPollStart(handle *FsPoll, cb FsPollCb, path *c.Char, interval uint) c.Int
// llgo:link (*FsPoll).Start C.uv_fs_poll_start
func (handle *FsPoll) Start(cb FsPollCb, path *c.Char, interval uint) c.Int {
return 0
}
//go:linkname FsPollStop C.uv_fs_poll_stop
func FsPollStop(handle *FsPoll) c.Int
// llgo:link (*FsPoll).Stop C.uv_fs_poll_stop
func (handle *FsPoll) Stop() c.Int {
return 0
}
//go:linkname FsPollClose C.uv_fs_poll_close
func FsPollClose(handle *FsPoll) c.Int
// llgo:link (*FsPoll).Close C.uv_fs_poll_close
func (handle *FsPoll) Close() c.Int {
return 0
}
//go:linkname FsPollGetPath C.uv_fs_poll_getpath
func FsPollGetPath(handle *FsPoll) *c.Char
// llgo:link (*FsPoll).GetPath C.uv_fs_poll_getpath
func (handle *FsPoll) GetPath() *c.Char {
return nil
}

View File

@@ -9,6 +9,7 @@ import (
const (
LLGoPackage = "link: $(pkg-config --libs libuv); -luv"
LLGoFiles = "$(pkg-config --cflags libuv): _wrap/libuv.c"
)
// ----------------------------------------------
@@ -103,10 +104,6 @@ type Poll struct {
/* Request types. */
type Shutdown struct {
Unused [0]byte
}
type Buf struct {
Base *c.Char
Len uintptr
@@ -135,9 +132,6 @@ 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 ShutdownCb func(req *Shutdown, status c.Int)
// llgo:type C
type WalkCb func(handle *Handle, arg c.Pointer)
@@ -160,59 +154,83 @@ func ReplaceAllocator(mallocFunc MallocFunc, reallocFunc ReallocFunc, callocFunc
// ----------------------------------------------
// llgo:link (*Shutdown).Shutdown C.uv_shutdown
func (shutdown *Shutdown) Shutdown(stream *Stream, shutdownCb ShutdownCb) c.Int {
return 0
}
// ----------------------------------------------
/* Loop related functions and method. */
//go:linkname DefaultLoop C.uv_default_loop
func DefaultLoop() *Loop
//go:linkname LoopSize C.uv_loop_size
func LoopSize() uintptr
//go:linkname Run C.uv_run
func Run(loop *Loop, mode RunMode) c.Int
// llgo:link (*Loop).Run C.uv_run
func (loop *Loop) Run(mode RunMode) c.Int {
return 0
}
//go:linkname LoopAlive C.uv_loop_alive
func LoopAlive(loop *Loop) c.Int
// llgo:link (*Loop).Alive C.uv_loop_alive
func (loop *Loop) Alive() c.Int {
return 0
}
//go:linkname LoopClose C.uv_loop_close
func LoopClose(loop *Loop) c.Int
// llgo:link (*Loop).Close C.uv_loop_close
func (loop *Loop) Close() c.Int {
return 0
}
//go:linkname LoopConfigure C.uv_loop_configure
func LoopConfigure(loop *Loop, option LoopOption, arg c.Int) c.Int
// llgo:link (*Loop).Configure C.uv_loop_configure
func (loop *Loop) Configure(option LoopOption, arg c.Int) c.Int {
return 0
}
//go:linkname LoopDefault C.uv_default_loop
func LoopDefault() *Loop
// llgo:link LoopDefault C.uv_default_loop
func LoopDefault() *Loop {
return nil
}
//go:linkname LoopDelete C.uv_loop_delete
func LoopDelete(loop *Loop) c.Int
// llgo:link (*Loop).Delete C.uv_loop_delete
func (loop *Loop) Delete() c.Int {
return 0
}
//go:linkname LoopFork C.uv_loop_fork
func LoopFork(loop *Loop) c.Int
// llgo:link (*Loop).Fork C.uv_loop_fork
func (loop *Loop) Fork() c.Int {
return 0
}
//go:linkname LoopInit C.uv_loop_init
func LoopInit(loop *Loop) c.Int
// llgo:link (*Loop).Init C.uv_loop_init
func (loop *Loop) Init() c.Int {
return 0
}
//go:linkname LoopNew C.uv_loop_new
func LoopNew() *Loop
// llgo:link LoopNew C.uv_loop_new
func LoopNew() *Loop {
return nil
}
//go:linkname LoopNow C.uv_now
func LoopNow(loop *Loop) c.UlongLong
// llgo:link (*Loop).Now C.uv_now
func (loop *Loop) Now() c.UlongLong {
return 0
}
//go:linkname LoopUpdateTime C.uv_update_time
func LoopUpdateTime(loop *Loop)
// llgo:link (*Loop).UpdateTime C.uv_update_time
func (loop *Loop) UpdateTime() {
// No return value needed for this method
}
//go:linkname LoopBackendFd C.uv_backend_fd
func LoopBackendFd(loop *Loop) c.Int
// llgo:link (*Loop).BackendFd C.uv_backend_fd
func (loop *Loop) BackendFd() c.Int {
return 0
}
//go:linkname LoopBackendTimeout C.uv_backend_timeout
func LoopBackendTimeout(loop *Loop) c.Int
// llgo:link (*Loop).BackendTimeout C.uv_backend_timeout
func (loop *Loop) BackendTimeout() c.Int {
return 0
}
//go:linkname LoopWalk C.uv_walk
func LoopWalk(loop *Loop, walkCb WalkCb, arg c.Pointer)
// llgo:link (*Loop).Walk C.uv_walk
func (loop *Loop) Walk(walkCb WalkCb, arg c.Pointer) {
// No return value needed for this method
}
// ----------------------------------------------
@@ -228,11 +246,15 @@ func InitBuf(base *c.Char, len c.Uint) Buf
//go:linkname PollInit C.uv_poll_init
func PollInit(loop *Loop, handle *Poll, fd OsFd) c.Int
//go:linkname PollStart C.uv_poll_start
func PollStart(handle *Poll, events c.Int, cb PollCb) c.Int
//go:linkname PollStop C.uv_poll_stop
func PollStop(handle *Poll) c.Int
//go:linkname PollInitSocket C.uv_poll_init_socket
func PollInitSocket(loop *Loop, handle *Poll, socket c.Int) c.Int
// llgo:link (*Poll).Start C.uv_poll_start
func (handle *Poll) Start(events c.Int, cb PollCb) c.Int {
return 0
}
// llgo:link (*Poll).Stop C.uv_poll_stop
func (handle *Poll) Stop() c.Int {
return 0
}

View File

@@ -117,6 +117,10 @@ type GetNameInfo struct {
Unused [0]byte
}
type Shutdown struct {
Unused [0]byte
}
// ----------------------------------------------
/* Function type */
@@ -142,10 +146,19 @@ type WriteCb func(req *Write, status c.Int)
// llgo:type C
type ConnectionCb func(server *Stream, status c.Int)
// llgo:type C
type ShutdownCb func(req *Shutdown, status c.Int)
// ----------------------------------------------
/* Handle related function and method */
//go:linkname HandleSize C.uv_handle_size
func HandleSize(handleType HandleType) uintptr
//go:linkname HandleTypeName C.uv_handle_type_name
func HandleTypeName(handleType HandleType) *c.Char
// llgo:link (*Handle).Ref C.uv_ref
func (handle *Handle) Ref() {}
@@ -157,17 +170,11 @@ 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
@@ -204,6 +211,21 @@ func (handle *Handle) Fileno(fd *OsFd) c.Int {
return 0
}
// llgo:link (*Handle).IsClosing C.uv_is_closing
func (handle *Handle) IsClosing() c.Int {
return 0
}
// llgo:link (*Handle).IsReadable C.uv_is_readable
func (handle *Handle) IsReadable() c.Int {
return 0
}
// llgo:link (*Handle).IsWritable C.uv_is_writable
func (handle *Handle) IsWritable() c.Int {
return 0
}
//go:linkname Pipe C.uv_pipe
func Pipe(fds [2]File, readFlags c.Int, writeFlags c.Int) c.Int {
return 0
@@ -214,11 +236,6 @@ func Socketpair(_type c.Int, protocol c.Int, socketVector [2]OsSock, flag0 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 */
@@ -226,6 +243,9 @@ func (handle *Handle) IsClosing() c.Int {
//go:linkname ReqSize C.uv_req_size
func ReqSize(reqType ReqType) uintptr
//go:linkname TypeName C.uv_req_type_name
func TypeName(reqType ReqType) *c.Char
// llgo:link (*Req).GetData C.uv_req_get_data
func (req *Req) GetData() c.Pointer {
return nil
@@ -239,9 +259,6 @@ 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 */
@@ -306,6 +323,11 @@ func (stream *Stream) SetBlocking(blocking c.Int) c.Int {
return 0
}
//go:linkname StreamShutdown C.uv_shutdown
func StreamShutdown(shutdown *Shutdown, stream *Stream, shutdownCb ShutdownCb) c.Int {
return 0
}
// ----------------------------------------------
/* Tcp related function and method */
@@ -356,6 +378,11 @@ func (tcp *Tcp) CloseReset(closeCb CloseCb) c.Int {
return 0
}
// llgo:link (*Tcp).GetIoWatcherFd C.uv_tcp_get_io_watcher_fd
func (tcp *Tcp) GetIoWatcherFd() c.Int {
return 0
}
//go:linkname TcpConnect C.uv_tcp_connect
func TcpConnect(req *Connect, tcp *Tcp, addr *net.SockAddr, connectCb ConnectCb) c.Int
@@ -429,9 +456,6 @@ 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
@@ -462,8 +486,13 @@ func (udp *Udp) GetSendQueueCount() uintptr {
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
// ----------------------------------------------
/* DNS related function and method */
//go:linkname Ip4Addr C.uv_ip4_addr
func Ip4Addr(ip *c.Char, port c.Int, addr *net.SockaddrIn) c.Int

View File

@@ -26,8 +26,17 @@ type SignalCb func(handle *Signal, sigNum c.Int)
//go:linkname SignalInit C.uv_signal_init
func SignalInit(loop *Loop, handle *Signal) c.Int
//go:linkname SignalStart C.uv_signal_start
func SignalStart(handle *Signal, cb SignalCb, signum c.Int) c.Int
// llgo:link (*Signal).Start C.uv_signal_start
func (handle *Signal) Start(cb SignalCb, signum c.Int) c.Int {
return 0
}
//go:linkname SignalStartOneshot C.uv_signal_start_oneshot
func SignalStartOneshot(handle *Signal, cb SignalCb, signum c.Int) c.Int
// llgo:link (*Signal).StartOneshot C.uv_signal_start_oneshot
func (handle *Signal) StartOneshot(cb SignalCb, signum c.Int) c.Int {
return 0
}
// llgo:link (*Signal).Stop C.uv_signal_stop
func (handle *Signal) Stop() c.Int {
return 0
}