refactor(c/libuv): general fixes & optimize code
Signed-off-by: hackerchai <i@hackerchai.com> refactor(c/libuv): optimize functions Signed-off-by: hackerchai <i@hackerchai.com> refactor(c/libuv): mv name Signed-off-by: hackerchai <i@hackerchai.com> refactor(c/libuv): modify libs Signed-off-by: hackerchai <i@hackerchai.com> refactor(c/libuv): use new buffer arg Signed-off-by: hackerchai <i@hackerchai.com> refactor(c/libuv/demo): optimize code style with go style Signed-off-by: hackerchai <i@hackerchai.com> refactor(c/libuv): optimize code and add comment Signed-off-by: hackerchai <i@hackerchai.com> fix(c/libuv): fix TranslateSysError Signed-off-by: hackerchai <i@hackerchai.com> refactor(c/libuv): remove go wrapper Signed-off-by: hackerchai <i@hackerchai.com> refactor(c/libuv/demo): refactor c style Signed-off-by: hackerchai <i@hackerchai.com> refactor(c/liobuv/demo): Some adjustments after removing go wrapper refactor(c/libuv/demo): add print in echo_server Signed-off-by: hackerchai <i@hackerchai.com> doc(c/libuv): add README.md for c/libuv Signed-off-by: hackerchai <i@hackerchai.com> feat(c/libuv): implement poll_init_socket Signed-off-by: hackerchai <i@hackerchai.com> refactor(c/libuv): mv poll_init_socket function Signed-off-by: hackerchai <i@hackerchai.com> refactor(demo): remove libuv demo Signed-off-by: hackerchai <i@hackerchai.com>
This commit is contained in:
@@ -1,109 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/libuv"
|
|
||||||
"github.com/goplus/llgo/c/net"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var DEFAULT_PORT c.Int = 8080
|
|
||||||
var DEFAULT_BACKLOG c.Int = 128
|
|
||||||
|
|
||||||
var loop *libuv.Loop
|
|
||||||
|
|
||||||
type WriteReq struct {
|
|
||||||
req libuv.Write
|
|
||||||
buf libuv.Buf
|
|
||||||
}
|
|
||||||
|
|
||||||
func FreeWriteReq(req *libuv.Write) {
|
|
||||||
wr := (*WriteReq)(c.Pointer(req))
|
|
||||||
c.Free(c.Pointer(wr.buf.Base))
|
|
||||||
c.Free(c.Pointer(wr))
|
|
||||||
}
|
|
||||||
|
|
||||||
func AllocBuffer(handle *libuv.Handle, suggestedSize uintptr, buf *libuv.Buf) {
|
|
||||||
buf.Base = (*c.Char)(c.Malloc(suggestedSize))
|
|
||||||
buf.Len = suggestedSize
|
|
||||||
}
|
|
||||||
|
|
||||||
func EchoWrite(req *libuv.Write, status c.Int) {
|
|
||||||
if status != 0 {
|
|
||||||
c.Fprintf(c.Stderr, c.Str("write error: %s\n"), libuv.Strerror(status))
|
|
||||||
}
|
|
||||||
defer FreeWriteReq(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func EchoRead(client *libuv.Stream, nread c.Long, buf *libuv.Buf) {
|
|
||||||
if nread > 0 {
|
|
||||||
req := (*WriteReq)(c.Malloc(unsafe.Sizeof(WriteReq{})))
|
|
||||||
if req == nil {
|
|
||||||
c.Fprintf(c.Stderr, c.Str("Failed to allocate memory for write request\n"))
|
|
||||||
defer c.Free(c.Pointer(buf.Base))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
req.buf = libuv.InitBuf(buf.Base, c.Uint(nread))
|
|
||||||
(*libuv.Write)(c.Pointer(req)).Write(client, []libuv.Buf{req.buf}, 1, EchoWrite)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if nread < 0 {
|
|
||||||
if (libuv.Errno)(nread) != libuv.EOF {
|
|
||||||
c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(c.Int(nread)))
|
|
||||||
}
|
|
||||||
(*libuv.Handle)(client).Close(nil)
|
|
||||||
}
|
|
||||||
if buf.Base != nil {
|
|
||||||
c.Free(c.Pointer(buf.Base))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func OnNewConnection(server *libuv.Stream, status c.Int) {
|
|
||||||
if status < 0 {
|
|
||||||
c.Fprintf(c.Stderr, c.Str("New connection error: %s\n"), libuv.Strerror(status))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
client := (*libuv.Tcp)(c.Malloc(unsafe.Sizeof(libuv.Tcp{})))
|
|
||||||
|
|
||||||
if client == nil {
|
|
||||||
c.Fprintf(c.Stderr, c.Str("Failed to allocate memory for client\n"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if libuv.InitTcp(loop, client) < 0 {
|
|
||||||
c.Fprintf(c.Stderr, c.Str("Failed to initialize client\n"))
|
|
||||||
c.Free(c.Pointer(client))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if server.Accept((*libuv.Stream)(client)) == 0 {
|
|
||||||
(*libuv.Stream)(client).StartRead(AllocBuffer, EchoRead)
|
|
||||||
} else {
|
|
||||||
(*libuv.Handle)(client).Close(nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// Initialize the default event loop
|
|
||||||
loop = libuv.DefaultLoop()
|
|
||||||
|
|
||||||
// Initialize a TCP server
|
|
||||||
var server libuv.Tcp
|
|
||||||
libuv.InitTcp(loop, &server)
|
|
||||||
|
|
||||||
// Set up the address to bind the server to
|
|
||||||
var addr net.SockaddrIn
|
|
||||||
libuv.Ip4Addr(c.Str("0.0.0.0"), DEFAULT_PORT, &addr)
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
if res != 0 {
|
|
||||||
c.Fprintf(c.Stderr, c.Str("Listen error: %s\n"), libuv.Strerror(res))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start listening for incoming connections
|
|
||||||
loop.Run(libuv.RUN_DEFAULT)
|
|
||||||
}
|
|
||||||
44
c/libuv/README.md
Normal file
44
c/libuv/README.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
LLGo wrapper of libuv
|
||||||
|
=====
|
||||||
|
|
||||||
|
## How to install
|
||||||
|
|
||||||
|
### on macOS (Homebrew)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
brew install libuv
|
||||||
|
```
|
||||||
|
|
||||||
|
### on Linux (Debian/Ubuntu)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
apt-get install -y libuv1-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### on Linux (CentOS/RHEL)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
yum install -y libuv-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
### on Linux (Arch Linux)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pacman -S libuv
|
||||||
|
```
|
||||||
|
|
||||||
|
## Demos
|
||||||
|
|
||||||
|
The `_demo` directory contains our demos (it start with `_` to prevent the `go` command from compiling it):
|
||||||
|
|
||||||
|
* [async_fs](_demo/async_fs/async_fs.go): a simple async file read demo
|
||||||
|
* [echo_server](_demo/echo_server/echo_server.go): a basic async tcp echo server
|
||||||
|
|
||||||
|
### How to run demos
|
||||||
|
|
||||||
|
To run the demos in directory `_demo`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd <demo-directory> # eg. cd _demo/sqlitedemo
|
||||||
|
llgo run .
|
||||||
|
```
|
||||||
97
c/libuv/_demo/async_fs/async_fs.go
Normal file
97
c/libuv/_demo/async_fs/async_fs.go
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/libuv"
|
||||||
|
"github.com/goplus/llgo/c/os"
|
||||||
|
)
|
||||||
|
|
||||||
|
const BUFFER_SIZE = 1024
|
||||||
|
|
||||||
|
var (
|
||||||
|
loop *libuv.Loop
|
||||||
|
openReq libuv.Fs
|
||||||
|
readReq libuv.Fs
|
||||||
|
closeReq libuv.Fs
|
||||||
|
|
||||||
|
buffer [BUFFER_SIZE]c.Char
|
||||||
|
iov libuv.Buf
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Print the libuv version
|
||||||
|
c.Printf(c.Str("libuv version: %d\n"), libuv.Version())
|
||||||
|
|
||||||
|
// Initialize the loop
|
||||||
|
loop = libuv.DefaultLoop()
|
||||||
|
|
||||||
|
// Open the file
|
||||||
|
libuv.FsOpen(loop, &openReq, c.Str("example.txt"), os.O_RDONLY, 0, onOpen)
|
||||||
|
|
||||||
|
// Run the loop
|
||||||
|
libuv.Run(loop, libuv.RUN_DEFAULT)
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
defer cleanup()
|
||||||
|
}
|
||||||
|
|
||||||
|
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.LoopClose(loop)))
|
||||||
|
libuv.LoopClose(loop)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Init buffer
|
||||||
|
iov = libuv.InitBuf((*c.Char)(unsafe.Pointer(&buffer[0])), c.Uint(unsafe.Sizeof(buffer)))
|
||||||
|
// Read the file
|
||||||
|
readRes := libuv.FsRead(loop, &readReq, libuv.UvFile(libuv.FsGetResult(req)), &iov, 1, -1, onRead)
|
||||||
|
if readRes != 0 {
|
||||||
|
c.Printf(c.Str("Error in FsRead: %s (code: %d)\n"), libuv.Strerror(c.Int(readRes)), readRes)
|
||||||
|
libuv.LoopClose(loop)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func onRead(req *libuv.Fs) {
|
||||||
|
// Check for errors
|
||||||
|
if libuv.FsGetResult(req) < 0 {
|
||||||
|
c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(libuv.FsGetResult(req)))
|
||||||
|
libuv.LoopClose(loop)
|
||||||
|
} else if libuv.FsGetResult(req) == 0 {
|
||||||
|
c.Printf(c.Str("EOF\n"))
|
||||||
|
// Close the file
|
||||||
|
closeRes := libuv.FsClose(loop, &closeReq, libuv.UvFile(libuv.FsGetResult(&openReq)), onClose)
|
||||||
|
if closeRes != 0 {
|
||||||
|
// Print the content
|
||||||
|
c.Printf(c.Str("Error in FsClose: %s (code: %d)\n"), libuv.Strerror(c.Int(closeRes)), closeRes)
|
||||||
|
libuv.LoopClose(loop)
|
||||||
|
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])))
|
||||||
|
libuv.LoopClose(loop)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.FsGetResult(req)))
|
||||||
|
} else {
|
||||||
|
c.Printf(c.Str("\nFile closed successfully.\n"))
|
||||||
|
}
|
||||||
|
libuv.LoopClose(loop)
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanup() {
|
||||||
|
// Cleanup the requests
|
||||||
|
libuv.FsReqCleanup(&openReq)
|
||||||
|
libuv.FsReqCleanup(&readReq)
|
||||||
|
libuv.FsReqCleanup(&closeReq)
|
||||||
|
// Close the loop
|
||||||
|
libuv.LoopClose(loop)
|
||||||
|
}
|
||||||
1
c/libuv/_demo/async_fs/example.txt
Executable file
1
c/libuv/_demo/async_fs/example.txt
Executable file
@@ -0,0 +1 @@
|
|||||||
|
123
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
"github.com/goplus/llgo/c"
|
||||||
"github.com/goplus/llgo/c/libuv"
|
"github.com/goplus/llgo/c/libuv"
|
||||||
"github.com/goplus/llgo/c/net"
|
"github.com/goplus/llgo/c/net"
|
||||||
"unsafe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var DEFAULT_PORT c.Int = 8080
|
var DEFAULT_PORT c.Int = 8080
|
||||||
@@ -13,75 +14,8 @@ var DEFAULT_BACKLOG c.Int = 128
|
|||||||
var loop *libuv.Loop
|
var loop *libuv.Loop
|
||||||
|
|
||||||
type WriteReq struct {
|
type WriteReq struct {
|
||||||
req libuv.Write
|
Req libuv.Write
|
||||||
buf libuv.Buf
|
Buf libuv.Buf
|
||||||
}
|
|
||||||
|
|
||||||
func FreeWriteReq(req *libuv.Write) {
|
|
||||||
wr := (*WriteReq)(c.Pointer(req))
|
|
||||||
c.Free(c.Pointer(wr.buf.Base))
|
|
||||||
c.Free(c.Pointer(wr))
|
|
||||||
}
|
|
||||||
|
|
||||||
func AllocBuffer(handle *libuv.Handle, suggestedSize uintptr, buf *libuv.Buf) {
|
|
||||||
buf.Base = (*c.Char)(c.Malloc(suggestedSize))
|
|
||||||
buf.Len = suggestedSize
|
|
||||||
}
|
|
||||||
|
|
||||||
func EchoWrite(req *libuv.Write, status c.Int) {
|
|
||||||
if status != 0 {
|
|
||||||
c.Fprintf(c.Stderr, c.Str("write error: %s\n"), libuv.Strerror(status))
|
|
||||||
}
|
|
||||||
defer FreeWriteReq(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func EchoRead(client *libuv.Stream, nread c.Long, buf *libuv.Buf) {
|
|
||||||
if nread > 0 {
|
|
||||||
req := (*WriteReq)(c.Malloc(unsafe.Sizeof(WriteReq{})))
|
|
||||||
if req == nil {
|
|
||||||
c.Fprintf(c.Stderr, c.Str("Failed to allocate memory for write request\n"))
|
|
||||||
defer c.Free(c.Pointer(buf.Base))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
req.buf = libuv.InitBuf(buf.Base, c.Uint(nread))
|
|
||||||
(*libuv.Write)(c.Pointer(req)).Write(client, []libuv.Buf{req.buf}, 1, EchoWrite)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if nread < 0 {
|
|
||||||
if (libuv.Errno)(nread) != libuv.EOF {
|
|
||||||
c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(c.Int(nread)))
|
|
||||||
}
|
|
||||||
(*libuv.Handle)(client).Close(nil)
|
|
||||||
}
|
|
||||||
if buf.Base != nil {
|
|
||||||
c.Free(c.Pointer(buf.Base))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func OnNewConnection(server *libuv.Stream, status c.Int) {
|
|
||||||
if status < 0 {
|
|
||||||
c.Fprintf(c.Stderr, c.Str("New connection error: %s\n"), libuv.Strerror(status))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
client := (*libuv.Tcp)(c.Malloc(unsafe.Sizeof(libuv.Tcp{})))
|
|
||||||
|
|
||||||
if client == nil {
|
|
||||||
c.Fprintf(c.Stderr, c.Str("Failed to allocate memory for client\n"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if libuv.InitTcp(loop, client) < 0 {
|
|
||||||
c.Fprintf(c.Stderr, c.Str("Failed to initialize client\n"))
|
|
||||||
c.Free(c.Pointer(client))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if server.Accept((*libuv.Stream)(client)) == 0 {
|
|
||||||
(*libuv.Stream)(client).StartRead(AllocBuffer, EchoRead)
|
|
||||||
} else {
|
|
||||||
(*libuv.Handle)(client).Close(nil)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -95,6 +29,7 @@ func main() {
|
|||||||
// Set up the address to bind the server to
|
// Set up the address to bind the server to
|
||||||
var addr net.SockaddrIn
|
var addr net.SockaddrIn
|
||||||
libuv.Ip4Addr(c.Str("0.0.0.0"), DEFAULT_PORT, &addr)
|
libuv.Ip4Addr(c.Str("0.0.0.0"), DEFAULT_PORT, &addr)
|
||||||
|
c.Printf(c.Str("Listening on %s:%d\n"), c.Str("0.0.0.0"), DEFAULT_PORT)
|
||||||
|
|
||||||
// Bind the server to the specified address and port
|
// Bind the server to the specified address and port
|
||||||
(&server).Bind((*net.SockAddr)(c.Pointer(&addr)), 0)
|
(&server).Bind((*net.SockAddr)(c.Pointer(&addr)), 0)
|
||||||
@@ -105,5 +40,81 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start listening for incoming connections
|
// Start listening for incoming connections
|
||||||
loop.Run(libuv.RUN_DEFAULT)
|
libuv.Run(loop, libuv.RUN_DEFAULT)
|
||||||
|
}
|
||||||
|
|
||||||
|
func FreeWriteReq(req *libuv.Write) {
|
||||||
|
wr := (*WriteReq)(c.Pointer(req))
|
||||||
|
// Free the buffer base and the WriteReq itself.
|
||||||
|
c.Free(c.Pointer(wr.Buf.Base))
|
||||||
|
c.Free(c.Pointer(wr))
|
||||||
|
}
|
||||||
|
|
||||||
|
func AllocBuffer(handle *libuv.Handle, suggestedSize uintptr, buf *libuv.Buf) {
|
||||||
|
// Allocate memory for the buffer based on the suggested size.
|
||||||
|
buf.Base = (*c.Char)(c.Malloc(suggestedSize))
|
||||||
|
buf.Len = suggestedSize
|
||||||
|
}
|
||||||
|
|
||||||
|
func EchoWrite(req *libuv.Write, status c.Int) {
|
||||||
|
if status != 0 {
|
||||||
|
c.Fprintf(c.Stderr, c.Str("Write error: %s\n"), libuv.Strerror(status))
|
||||||
|
}
|
||||||
|
FreeWriteReq(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
func EchoRead(client *libuv.Stream, nread c.Long, buf *libuv.Buf) {
|
||||||
|
if nread > 0 {
|
||||||
|
req := (*WriteReq)(c.Malloc(unsafe.Sizeof(WriteReq{})))
|
||||||
|
if req == nil {
|
||||||
|
c.Fprintf(c.Stderr, c.Str("Failed to allocate memory for write request\n"))
|
||||||
|
c.Free(c.Pointer(buf.Base))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Initialize the buffer with the data read.
|
||||||
|
req.Buf = libuv.InitBuf(buf.Base, c.Uint(nread))
|
||||||
|
// Write the data back to the client.
|
||||||
|
(&req.Req).Write(client, &req.Buf, 1, EchoWrite)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
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(c.Int(nread)))
|
||||||
|
}
|
||||||
|
(*libuv.Handle)(c.Pointer(client)).Close(nil)
|
||||||
|
}
|
||||||
|
// Free the buffer if it's no longer needed.
|
||||||
|
if buf.Base != nil {
|
||||||
|
c.Free(c.Pointer(buf.Base))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func OnNewConnection(server *libuv.Stream, status c.Int) {
|
||||||
|
if status < 0 {
|
||||||
|
c.Fprintf(c.Stderr, c.Str("New connection error: %s\n"), libuv.Strerror(status))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate memory for a new client.
|
||||||
|
client := (*libuv.Tcp)(c.Malloc(unsafe.Sizeof(libuv.Tcp{})))
|
||||||
|
|
||||||
|
if client == nil {
|
||||||
|
c.Fprintf(c.Stderr, c.Str("Failed to allocate memory for client\n"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the client TCP handle.
|
||||||
|
if libuv.InitTcp(loop, client) < 0 {
|
||||||
|
c.Fprintf(c.Stderr, c.Str("Failed to initialize client\n"))
|
||||||
|
c.Free(c.Pointer(client))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accept the new connection and start reading data.
|
||||||
|
if server.Accept((*libuv.Stream)(client)) == 0 {
|
||||||
|
(*libuv.Stream)(client).StartRead(AllocBuffer, EchoRead)
|
||||||
|
} else {
|
||||||
|
(*libuv.Handle)(c.Pointer(client)).Close(nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/libuv"
|
|
||||||
"github.com/goplus/llgo/c/os"
|
|
||||||
"golang.org/x/tools/container/intsets"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const bufferSize = 1024
|
|
||||||
|
|
||||||
var buffer []c.Char
|
|
||||||
var iov libuv.Buf
|
|
||||||
|
|
||||||
var loop *libuv.Loop
|
|
||||||
var readReq *libuv.Fs
|
|
||||||
var closeReq *libuv.Fs
|
|
||||||
var openReq *libuv.Fs
|
|
||||||
|
|
||||||
func initBuffer() {
|
|
||||||
buffer = make([]c.Char, bufferSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
loop = libuv.DefaultLoop()
|
|
||||||
initBuffer()
|
|
||||||
|
|
||||||
file := libuv.NewFile(loop, openReq)
|
|
||||||
|
|
||||||
path := c.Str("example.txt")
|
|
||||||
|
|
||||||
file.Open(path, os.O_RDONLY, 0, onOpen)
|
|
||||||
|
|
||||||
loop.Run(libuv.RUN_DEFAULT)
|
|
||||||
|
|
||||||
libuv.FsReqCleanup(openReq)
|
|
||||||
loop.Close()
|
|
||||||
c.Free(unsafe.Pointer(loop))
|
|
||||||
}
|
|
||||||
|
|
||||||
func onOpen(req *libuv.Fs) {
|
|
||||||
if req.GetResult() < 0 {
|
|
||||||
c.Fprintf(c.Stderr, c.Str("Error opening file: %s\n"), libuv.Strerror(req.GetResult()))
|
|
||||||
} else {
|
|
||||||
iov = libuv.InitBuf(unsafe.SliceData(buffer), c.Uint(unsafe.Sizeof(buffer)))
|
|
||||||
libuv.FsRead(loop, readReq, req.GetResult(), []libuv.Buf{iov}, 1, -1, onRead)
|
|
||||||
}
|
|
||||||
libuv.FsReqCleanup(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func onRead(req *libuv.Fs) {
|
|
||||||
if req.GetResult() < 0 {
|
|
||||||
c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(req.GetResult()))
|
|
||||||
} else if req.GetResult() == 0 {
|
|
||||||
libuv.FsClose(loop, closeReq, req.GetResult(), onClose)
|
|
||||||
} else {
|
|
||||||
if req.GetResult() > intsets.MaxInt {
|
|
||||||
c.Fprintf(c.Stderr, c.Str("Too big file.\n"))
|
|
||||||
}
|
|
||||||
c.Printf(c.Str("%.*s"), c.Int(req.GetResult()), buffer)
|
|
||||||
libuv.FsRead(loop, req, req.GetResult(), []libuv.Buf{iov}, 1, -1, onRead)
|
|
||||||
}
|
|
||||||
libuv.FsReqCleanup(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func onClose(req *libuv.Fs) {
|
|
||||||
c.Printf(c.Str("\nFile closed.\n"))
|
|
||||||
libuv.FsReqCleanup(req)
|
|
||||||
}
|
|
||||||
308
c/libuv/fs.go
308
c/libuv/fs.go
@@ -57,9 +57,11 @@ const (
|
|||||||
DirentBlock
|
DirentBlock
|
||||||
)
|
)
|
||||||
|
|
||||||
type FsType int
|
type FsType c.Int
|
||||||
|
|
||||||
type DirentType int
|
type DirentType c.Int
|
||||||
|
|
||||||
|
type UvFile c.Int
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|
||||||
@@ -108,35 +110,23 @@ type FsPollCb func(handle *FsPoll, status c.Int, events c.Int)
|
|||||||
|
|
||||||
/* Fs related function and method */
|
/* Fs related function and method */
|
||||||
|
|
||||||
// llgo:link (*Fs).GetType C.uv_fs_get_type
|
//go:linkname FsGetType C.uv_fs_get_type
|
||||||
func (f *Fs) GetType() *FsType {
|
func FsGetType(req *Fs) *FsType
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Fs).GetPath C.uv_fs_get_path
|
//go:linkname FsGetPath C.uv_fs_get_path
|
||||||
func (f *Fs) GetPath() *c.Char {
|
func FsGetPath(req *Fs) *c.Char
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Fs).GetResult C.uv_fs_get_result
|
//go:linkname FsGetResult C.uv_fs_get_result
|
||||||
func (f *Fs) GetResult() c.Int {
|
func FsGetResult(req *Fs) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Fs).GetPtr C.uv_fs_get_ptr
|
//go:linkname FsGetPtr C.uv_fs_get_ptr
|
||||||
func (f *Fs) GetPtr() c.Pointer {
|
func FsGetPtr(req *Fs) c.Pointer
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Fs).GetSystemError C.uv_fs_get_system_error
|
//go:linkname FsGetSystemError C.uv_fs_get_system_error
|
||||||
func (f *Fs) GetSystemError() c.Int {
|
func FsGetSystemError(req *Fs) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Fs).GetStatBuf C.uv_fs_get_statbuf
|
//go:linkname FsGetStatBuf C.uv_fs_get_statbuf
|
||||||
func (f *Fs) GetStatBuf() *Stat {
|
func FsGetStatBuf(req *Fs) *Stat
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//go:linkname FsReqCleanup C.uv_fs_req_cleanup
|
//go:linkname FsReqCleanup C.uv_fs_req_cleanup
|
||||||
func FsReqCleanup(req *Fs)
|
func FsReqCleanup(req *Fs)
|
||||||
@@ -148,13 +138,13 @@ func DefaultLoop() *Loop
|
|||||||
func FsOpen(loop *Loop, req *Fs, path *c.Char, flags c.Int, mode c.Int, cb FsCb) c.Int
|
func FsOpen(loop *Loop, req *Fs, path *c.Char, flags c.Int, mode c.Int, cb FsCb) c.Int
|
||||||
|
|
||||||
//go:linkname FsClose C.uv_fs_close
|
//go:linkname FsClose C.uv_fs_close
|
||||||
func FsClose(loop *Loop, req *Fs, file c.Int, cb FsCb) c.Int
|
func FsClose(loop *Loop, req *Fs, file UvFile, cb FsCb) c.Int
|
||||||
|
|
||||||
//go:linkname FsRead C.uv_fs_read
|
//go:linkname FsRead C.uv_fs_read
|
||||||
func FsRead(loop *Loop, req *Fs, file c.Int, bufs []Buf, nbufs c.Uint, offset c.Int, cb FsCb) c.Int
|
func FsRead(loop *Loop, req *Fs, file UvFile, bufs *Buf, nbufs c.Uint, offset c.LongLong, cb FsCb) c.Int
|
||||||
|
|
||||||
//go:linkname FsWrite C.uv_fs_write
|
//go:linkname FsWrite C.uv_fs_write
|
||||||
func FsWrite(loop *Loop, req *Fs, file c.Int, bufs []Buf, nbufs c.Uint, offset c.Int, cb FsCb) c.Int
|
func FsWrite(loop *Loop, req *Fs, file UvFile, bufs *Buf, nbufs c.Uint, offset c.LongLong, cb FsCb) c.Int
|
||||||
|
|
||||||
//go:linkname FsUnlink C.uv_fs_unlink
|
//go:linkname FsUnlink C.uv_fs_unlink
|
||||||
func FsUnlink(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int
|
func FsUnlink(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int
|
||||||
@@ -175,22 +165,22 @@ func FsRmdir(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int
|
|||||||
func FsStat(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int
|
func FsStat(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int
|
||||||
|
|
||||||
//go:linkname FsFstat C.uv_fs_fstat
|
//go:linkname FsFstat C.uv_fs_fstat
|
||||||
func FsFstat(loop *Loop, req *Fs, file c.Int, cb FsCb) c.Int
|
func FsFstat(loop *Loop, req *Fs, file UvFile, cb FsCb) c.Int
|
||||||
|
|
||||||
//go:linkname FsRename C.uv_fs_rename
|
//go:linkname FsRename C.uv_fs_rename
|
||||||
func FsRename(loop *Loop, req *Fs, path *c.Char, newPath *c.Char, cb FsCb) c.Int
|
func FsRename(loop *Loop, req *Fs, path *c.Char, newPath *c.Char, cb FsCb) c.Int
|
||||||
|
|
||||||
//go:linkname FsFsync C.uv_fs_fsync
|
//go:linkname FsFsync C.uv_fs_fsync
|
||||||
func FsFsync(loop *Loop, req *Fs, file c.Int, cb FsCb) c.Int
|
func FsFsync(loop *Loop, req *Fs, file UvFile, cb FsCb) c.Int
|
||||||
|
|
||||||
//go:linkname FsFdatasync C.uv_fs_fdatasync
|
//go:linkname FsFdatasync C.uv_fs_fdatasync
|
||||||
func FsFdatasync(loop *Loop, req *Fs, file c.Int, cb FsCb) c.Int
|
func FsFdatasync(loop *Loop, req *Fs, file UvFile, cb FsCb) c.Int
|
||||||
|
|
||||||
//go:linkname FsFtruncate C.uv_fs_ftruncate
|
//go:linkname FsFtruncate C.uv_fs_ftruncate
|
||||||
func FsFtruncate(loop *Loop, req *Fs, file c.Int, offset c.Int, cb FsCb) c.Int
|
func FsFtruncate(loop *Loop, req *Fs, file UvFile, offset c.LongLong, cb FsCb) c.Int
|
||||||
|
|
||||||
//go:linkname FsSendfile C.uv_fs_sendfile
|
//go:linkname FsSendfile C.uv_fs_sendfile
|
||||||
func FsSendfile(loop *Loop, req *Fs, outFd c.Int, inFd c.Int, inOffset c.Int, length c.Int, cb FsCb) c.Int
|
func FsSendfile(loop *Loop, req *Fs, outFd c.Int, inFd c.Int, inOffset c.LongLong, length c.Int, cb FsCb) c.Int
|
||||||
|
|
||||||
//go:linkname FsAccess C.uv_fs_access
|
//go:linkname FsAccess C.uv_fs_access
|
||||||
func FsAccess(loop *Loop, req *Fs, path *c.Char, flags c.Int, cb FsCb) c.Int
|
func FsAccess(loop *Loop, req *Fs, path *c.Char, flags c.Int, cb FsCb) c.Int
|
||||||
@@ -199,13 +189,13 @@ func FsAccess(loop *Loop, req *Fs, path *c.Char, flags c.Int, cb FsCb) c.Int
|
|||||||
func FsChmod(loop *Loop, req *Fs, path *c.Char, mode c.Int, cb FsCb) c.Int
|
func FsChmod(loop *Loop, req *Fs, path *c.Char, mode c.Int, cb FsCb) c.Int
|
||||||
|
|
||||||
//go:linkname FsFchmod C.uv_fs_fchmod
|
//go:linkname FsFchmod C.uv_fs_fchmod
|
||||||
func FsFchmod(loop *Loop, req *Fs, file c.Int, mode c.Int, cb FsCb) c.Int
|
func FsFchmod(loop *Loop, req *Fs, file UvFile, mode c.Int, cb FsCb) c.Int
|
||||||
|
|
||||||
//go:linkname FsUtime C.uv_fs_utime
|
//go:linkname FsUtime C.uv_fs_utime
|
||||||
func FsUtime(loop *Loop, req *Fs, path *c.Char, atime c.Int, mtime c.Int, cb FsCb) c.Int
|
func FsUtime(loop *Loop, req *Fs, path *c.Char, atime c.Int, mtime c.Int, cb FsCb) c.Int
|
||||||
|
|
||||||
//go:linkname FsFutime C.uv_fs_futime
|
//go:linkname FsFutime C.uv_fs_futime
|
||||||
func FsFutime(loop *Loop, req *Fs, file c.Int, atime c.Int, mtime c.Int, cb FsCb) c.Int
|
func FsFutime(loop *Loop, req *Fs, file UvFile, atime c.Int, mtime c.Int, cb FsCb) c.Int
|
||||||
|
|
||||||
//go:linkname FsLutime C.uv_fs_lutime
|
//go:linkname FsLutime C.uv_fs_lutime
|
||||||
func FsLutime(loop *Loop, req *Fs, path *c.Char, atime c.Int, mtime c.Int, cb FsCb) c.Int
|
func FsLutime(loop *Loop, req *Fs, path *c.Char, atime c.Int, mtime c.Int, cb FsCb) c.Int
|
||||||
@@ -247,7 +237,7 @@ func FsStatfs(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int
|
|||||||
func FsChown(loop *Loop, req *Fs, path *c.Char, uid c.Int, gid c.Int, cb FsCb) c.Int
|
func FsChown(loop *Loop, req *Fs, path *c.Char, uid c.Int, gid c.Int, cb FsCb) c.Int
|
||||||
|
|
||||||
//go:linkname FsFchown C.uv_fs_fchown
|
//go:linkname FsFchown C.uv_fs_fchown
|
||||||
func FsFchown(loop *Loop, req *Fs, file c.Int, uid c.Int, gid c.Int, cb FsCb) c.Int
|
func FsFchown(loop *Loop, req *Fs, file UvFile, uid c.Int, gid c.Int, cb FsCb) c.Int
|
||||||
|
|
||||||
//go:linkname FsLchown C.uv_fs_lchown
|
//go:linkname FsLchown C.uv_fs_lchown
|
||||||
func FsLchown(loop *Loop, req *Fs, path *c.Char, uid c.Int, gid c.Int, cb FsCb) c.Int
|
func FsLchown(loop *Loop, req *Fs, path *c.Char, uid c.Int, gid c.Int, cb FsCb) c.Int
|
||||||
@@ -284,247 +274,3 @@ func FsPollClose(handle *FsPoll) c.Int
|
|||||||
|
|
||||||
//go:linkname FsPollGetPath C.uv_fs_poll_getpath
|
//go:linkname FsPollGetPath C.uv_fs_poll_getpath
|
||||||
func FsPollGetPath(handle *FsPoll) *c.Char
|
func FsPollGetPath(handle *FsPoll) *c.Char
|
||||||
|
|
||||||
//TODO: Implemnt uv_poll_init_socket
|
|
||||||
|
|
||||||
// Cleanup cleans up the file system request.
|
|
||||||
func (f *File) Cleanup() {
|
|
||||||
FsReqCleanup(f.Req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFile(loop *Loop, req *Fs) *File {
|
|
||||||
return &File{
|
|
||||||
Loop: loop,
|
|
||||||
Req: req,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open opens a file specified by the path with given flags and mode, and returns a file descriptor.
|
|
||||||
func (f *File) Open(path *c.Char, flags int, mode int, cb FsCb) int {
|
|
||||||
return FsOpen(f.Loop, f.Req, path, flags, mode, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes a file descriptor.
|
|
||||||
func (f *File) Close(file int, cb FsCb) int {
|
|
||||||
return FsClose(f.Loop, f.Req, file, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads data from a file descriptor into a buffer at a specified offset.
|
|
||||||
func (f *File) Read(file c.Int, bufs []Buf, nbufs c.Uint, offset c.Int, cb FsCb) int {
|
|
||||||
return FsRead(f.Loop, f.Req, file, bufs, nbufs, offset, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write writes data to a file descriptor from a buffer at a specified offset.
|
|
||||||
func (f *File) Write(file c.Int, bufs []Buf, nbufs c.Uint, offset c.Int, cb FsCb) int {
|
|
||||||
return FsWrite(f.Loop, f.Req, file, bufs, nbufs, offset, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unlink deletes a file specified by the path.
|
|
||||||
func (f *File) Unlink(path *c.Char, cb FsCb) int {
|
|
||||||
return FsUnlink(f.Loop, f.Req, path, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdir creates a new directory at the specified path with a specified mode.
|
|
||||||
func (f *File) Mkdir(path *c.Char, mode int, cb FsCb) int {
|
|
||||||
return FsMkdir(f.Loop, f.Req, path, mode, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdtemp creates a temporary directory with a template path.
|
|
||||||
func (f *File) Mkdtemp(tpl *c.Char, cb FsCb) int {
|
|
||||||
return FsMkdtemp(f.Loop, f.Req, tpl, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MkStemp creates a temporary file from a template path.
|
|
||||||
func (f *File) MkStemp(tpl *c.Char, cb FsCb) int {
|
|
||||||
return FsMkStemp(f.Loop, f.Req, tpl, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rmdir removes a directory specified by the path.
|
|
||||||
func (f *File) Rmdir(path *c.Char, cb FsCb) int {
|
|
||||||
return FsRmdir(f.Loop, f.Req, path, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stat retrieves status information about the file specified by the path.
|
|
||||||
func (f *File) Stat(path *c.Char, cb FsCb) int {
|
|
||||||
return FsStat(f.Loop, f.Req, path, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fstat retrieves status information about a file descriptor.
|
|
||||||
func (f *File) Fstat(file int, cb FsCb) int {
|
|
||||||
return FsFstat(f.Loop, f.Req, file, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rename renames a file from the old path to the new path.
|
|
||||||
func (f *File) Rename(path *c.Char, newPath *c.Char, cb FsCb) int {
|
|
||||||
return FsRename(f.Loop, f.Req, path, newPath, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fsync synchronizes a file descriptor's state with storage device.
|
|
||||||
func (f *File) Fsync(file int, cb FsCb) int {
|
|
||||||
return FsFsync(f.Loop, f.Req, file, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fdatasync synchronizes a file descriptor's data with storage device.
|
|
||||||
func (f *File) Fdatasync(file int, cb FsCb) int {
|
|
||||||
return FsFdatasync(f.Loop, f.Req, file, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ftruncate truncates a file to a specified length.
|
|
||||||
func (f *File) Ftruncate(file int, offset int, cb FsCb) int {
|
|
||||||
return FsFtruncate(f.Loop, f.Req, file, offset, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sendfile sends data from one file descriptor to another.
|
|
||||||
func (f *File) Sendfile(outFd int, inFd int, inOffset int, length int, cb FsCb) int {
|
|
||||||
return FsSendfile(f.Loop, f.Req, outFd, inFd, inOffset, length, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Access checks the access permissions of a file specified by the path.
|
|
||||||
func (f *File) Access(path *c.Char, flags int, cb FsCb) int {
|
|
||||||
return FsAccess(f.Loop, f.Req, path, flags, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Chmod changes the permissions of a file specified by the path.
|
|
||||||
func (f *File) Chmod(path *c.Char, mode int, cb FsCb) int {
|
|
||||||
return FsChmod(f.Loop, f.Req, path, mode, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fchmod changes the permissions of a file descriptor.
|
|
||||||
func (f *File) Fchmod(file int, mode int, cb FsCb) int {
|
|
||||||
return FsFchmod(f.Loop, f.Req, file, mode, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utime updates the access and modification times of a file specified by the path.
|
|
||||||
func (f *File) Utime(path *c.Char, atime int, mtime int, cb FsCb) int {
|
|
||||||
return FsUtime(f.Loop, f.Req, path, atime, mtime, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Futime updates the access and modification times of a file descriptor.
|
|
||||||
func (f *File) Futime(file int, atime int, mtime int, cb FsCb) int {
|
|
||||||
return FsFutime(f.Loop, f.Req, file, atime, mtime, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lutime updates the access and modification times of a file specified by the path, even if the path is a symbolic link.
|
|
||||||
func (f *File) Lutime(path *c.Char, atime int, mtime int, cb FsCb) int {
|
|
||||||
return FsLutime(f.Loop, f.Req, path, atime, mtime, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Link creates a new link to an existing file.
|
|
||||||
func (f *File) Link(path *c.Char, newPath *c.Char, cb FsCb) int {
|
|
||||||
return FsLink(f.Loop, f.Req, path, newPath, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Symlink creates a symbolic link from the path to the new path.
|
|
||||||
func (f *File) Symlink(path *c.Char, newPath *c.Char, flags int, cb FsCb) int {
|
|
||||||
return FsSymlink(f.Loop, f.Req, path, newPath, flags, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Readlink reads the target of a symbolic link.
|
|
||||||
func (f *File) Readlink(path *c.Char, cb FsCb) int {
|
|
||||||
return FsReadlink(f.Loop, f.Req, path, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Realpath resolves the absolute path of a file.
|
|
||||||
func (f *File) Realpath(path *c.Char, cb FsCb) int {
|
|
||||||
return FsRealpath(f.Loop, f.Req, path, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copyfile copies a file from the source path to the destination path.
|
|
||||||
func (f *File) Copyfile(path *c.Char, newPath *c.Char, flags int, cb FsCb) int {
|
|
||||||
return FsCopyfile(f.Loop, f.Req, path, newPath, flags, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scandir scans a directory for entries.
|
|
||||||
func (f *File) Scandir(path *c.Char, flags int, cb FsCb) int {
|
|
||||||
return FsScandir(f.Loop, f.Req, path, flags, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenDir opens a directory specified by the path.
|
|
||||||
func (f *File) OpenDir(path *c.Char, cb FsCb) int {
|
|
||||||
return FsOpenDir(f.Loop, f.Req, path, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Readdir reads entries from an open directory.
|
|
||||||
func (f *File) Readdir(dir int, cb FsCb) int {
|
|
||||||
return FsReaddir(f.Loop, f.Req, dir, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CloseDir closes an open directory.
|
|
||||||
func (f *File) CloseDir() int {
|
|
||||||
return FsCloseDir(f.Loop, f.Req)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Statfs retrieves file system status information.
|
|
||||||
func (f *File) Statfs(path *c.Char, cb FsCb) int {
|
|
||||||
return FsStatfs(f.Loop, f.Req, path, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Chown Change file ownership
|
|
||||||
func (f *File) Chown(path *c.Char, uid int, gid int, cb FsCb) int {
|
|
||||||
return FsChown(f.Loop, f.Req, path, uid, gid, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fchown Change file ownership by file descriptor
|
|
||||||
func (f *File) Fchown(file int, uid int, gid int, cb FsCb) int {
|
|
||||||
return FsFchown(f.Loop, f.Req, file, uid, gid, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lchown Change file ownership (symlink)
|
|
||||||
func (f *File) Lchown(path *c.Char, uid int, gid int, cb FsCb) int {
|
|
||||||
return FsLchown(f.Loop, f.Req, path, uid, gid, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lstat Get file status (symlink)
|
|
||||||
func (f *File) Lstat(path *c.Char, cb FsCb) int {
|
|
||||||
return FsLstat(f.Loop, f.Req, path, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init Initialize a file event handle
|
|
||||||
func (e *FsEvent) Init(loop *Loop) int {
|
|
||||||
return FsEventInit(loop, e)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start listening for file events
|
|
||||||
func (e *FsEvent) Start(cb FsEventCb, path *c.Char, flags int) int {
|
|
||||||
return FsEventStart(e, cb, path, flags)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop listening for file events
|
|
||||||
func (e *FsEvent) Stop() int {
|
|
||||||
return FsEventStop(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close the file event handle
|
|
||||||
func (e *FsEvent) Close() int {
|
|
||||||
return FsEventClose(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPath Get the path of the file event
|
|
||||||
func (e *FsEvent) GetPath() *c.Char {
|
|
||||||
return FsEventGetpath(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init Initialize a file poll handle
|
|
||||||
func (p *FsPoll) Init(loop *Loop) int {
|
|
||||||
return FsPollInit(loop, p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start polling for file changes
|
|
||||||
func (p *FsPoll) Start(cb FsPollCb, path *c.Char, interval uint) int {
|
|
||||||
return FsPollStart(p, cb, path, interval)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop polling for file changes
|
|
||||||
func (p *FsPoll) Stop() int {
|
|
||||||
return FsPollStop(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close the file poll handle
|
|
||||||
func (p *FsPoll) Close() int {
|
|
||||||
return FsPollClose(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPath Get the path of the file poll
|
|
||||||
func (p *FsPoll) GetPath() *c.Char {
|
|
||||||
return FsPollGetPath(p)
|
|
||||||
}
|
|
||||||
|
|||||||
130
c/libuv/libuv.go
130
c/libuv/libuv.go
@@ -11,6 +11,11 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
const (
|
||||||
|
RUN_DEFAULT RunMode = iota
|
||||||
|
RUN_ONCE
|
||||||
|
RUN_NOWAIT
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LOOP_BLOCK_SIGNAL LoopOption = iota
|
LOOP_BLOCK_SIGNAL LoopOption = iota
|
||||||
@@ -60,6 +65,15 @@ const (
|
|||||||
REQ_TYPE_MAX
|
REQ_TYPE_MAX
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
READABLE PollEvent = 1 << iota
|
||||||
|
WRITABLE
|
||||||
|
DISCONNECT
|
||||||
|
PRIPRIORITIZED
|
||||||
|
)
|
||||||
|
|
||||||
|
type RunMode c.Int
|
||||||
|
|
||||||
type LoopOption c.Int
|
type LoopOption c.Int
|
||||||
|
|
||||||
type Membership c.Int
|
type Membership c.Int
|
||||||
@@ -68,26 +82,30 @@ type HandleType c.Int
|
|||||||
|
|
||||||
type ReqType c.Int
|
type ReqType c.Int
|
||||||
|
|
||||||
type Uv_File c.Int
|
|
||||||
|
|
||||||
type OsSock c.Int
|
type OsSock c.Int
|
||||||
|
|
||||||
type OsFd c.Int
|
type OsFd c.Int
|
||||||
|
|
||||||
|
type PollEvent c.Int
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|
||||||
/* Handle types. */
|
/* Handle types. */
|
||||||
|
|
||||||
type Handle struct {
|
type Loop struct {
|
||||||
Unused [0]byte
|
Unused [0]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Handle struct {
|
||||||
|
Unused [96]byte
|
||||||
|
}
|
||||||
|
|
||||||
type Dir struct {
|
type Dir struct {
|
||||||
Unused [0]byte
|
Unused [0]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type Stream struct {
|
type Stream struct {
|
||||||
Unused [0]byte
|
Unused [264]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type Pipe struct {
|
type Pipe struct {
|
||||||
@@ -122,18 +140,6 @@ type Process struct {
|
|||||||
Unused [0]byte
|
Unused [0]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type FsEvent struct {
|
|
||||||
Unused [0]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type FsPoll struct {
|
|
||||||
Unused [0]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type Signal struct {
|
|
||||||
Unused [0]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Request types. */
|
/* Request types. */
|
||||||
|
|
||||||
type Req struct {
|
type Req struct {
|
||||||
@@ -153,14 +159,17 @@ type Shutdown struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Write struct {
|
type Write struct {
|
||||||
Unused [0]byte
|
Unused [192]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type Connect struct {
|
type Connect struct {
|
||||||
Unused [0]byte
|
Unused [0]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------
|
type Buf struct {
|
||||||
|
Base *c.Char
|
||||||
|
Len uintptr
|
||||||
|
} // ----------------------------------------------
|
||||||
|
|
||||||
/* Function type */
|
/* Function type */
|
||||||
|
|
||||||
@@ -200,6 +209,9 @@ type ShutdownCb func(req *Shutdown, status c.Int)
|
|||||||
// llgo:type C
|
// llgo:type C
|
||||||
type WalkCb func(handle *Handle, arg c.Pointer)
|
type WalkCb func(handle *Handle, arg c.Pointer)
|
||||||
|
|
||||||
|
// llgo:type C
|
||||||
|
type PollCb func(handle *Poll, status c.Int, events c.Int)
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|
||||||
//go:linkname Version C.uv_version
|
//go:linkname Version C.uv_version
|
||||||
@@ -284,7 +296,7 @@ func (handle *Handle) Fileno(fd *OsFd) c.Int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname UvPipe C.uv_pipe
|
//go:linkname UvPipe C.uv_pipe
|
||||||
func UvPipe(fds [2]Uv_File, readFlags c.Int, writeFlags c.Int) c.Int {
|
func UvPipe(fds [2]UvFile, readFlags c.Int, writeFlags c.Int) c.Int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,22 +363,22 @@ func (stream *Stream) StopRead() c.Int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// llgo:link (*Write).Write C.uv_write
|
// llgo:link (*Write).Write C.uv_write
|
||||||
func (req *Write) Write(stream *Stream, bufs []Buf, nbufs c.Uint, writeCb WriteCb) c.Int {
|
func (req *Write) Write(stream *Stream, bufs *Buf, nbufs c.Uint, writeCb WriteCb) c.Int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// llgo:link (*Write).Write2 C.uv_write2
|
// llgo:link (*Write).Write2 C.uv_write2
|
||||||
func (req *Write) Write2(stream *Stream, bufs []Buf, nbufs c.Uint, sendStream *Stream, writeCb WriteCb) c.Int {
|
func (req *Write) Write2(stream *Stream, bufs *Buf, nbufs c.Uint, sendStream *Stream, writeCb WriteCb) c.Int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// llgo:link (*Stream).TryWrite C.uv_try_write
|
// llgo:link (*Stream).TryWrite C.uv_try_write
|
||||||
func (stream *Stream) TryWrite(bufs []Buf, nbufs c.Uint) c.Int {
|
func (stream *Stream) TryWrite(bufs *Buf, nbufs c.Uint) c.Int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// llgo:link (*Stream).TryWrite2 C.uv_try_write2
|
// llgo:link (*Stream).TryWrite2 C.uv_try_write2
|
||||||
func (stream *Stream) TryWrite2(bufs []Buf, nbufs c.Uint, sendStream *Stream) c.Int {
|
func (stream *Stream) TryWrite2(bufs *Buf, nbufs c.Uint, sendStream *Stream) c.Int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,6 +399,78 @@ func (stream *Stream) SetBlocking(blocking c.Int) c.Int {
|
|||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|
||||||
|
/* Loop related functions and method. */
|
||||||
|
|
||||||
|
//go:linkname LoopSize C.uv_loop_size
|
||||||
|
func LoopSize() uintptr
|
||||||
|
|
||||||
|
//go:linkname Run C.uv_run
|
||||||
|
func Run(loop *Loop, mode RunMode) c.Int
|
||||||
|
|
||||||
|
//go:linkname LoopAlive C.uv_loop_alive
|
||||||
|
func LoopAlive(loop *Loop) c.Int
|
||||||
|
|
||||||
|
//go:linkname LoopClose C.uv_loop_close
|
||||||
|
func LoopClose(loop *Loop) c.Int
|
||||||
|
|
||||||
|
//go:linkname LoopConfigure C.uv_loop_configure
|
||||||
|
func LoopConfigure(loop *Loop, option LoopOption, arg c.Int) c.Int
|
||||||
|
|
||||||
|
//go:linkname LoopDefault C.uv_default_loop
|
||||||
|
func LoopDefault() *Loop
|
||||||
|
|
||||||
|
//go:linkname LoopDelete C.uv_loop_delete
|
||||||
|
func LoopDelete(loop *Loop) c.Int
|
||||||
|
|
||||||
|
//go:linkname LoopFork C.uv_loop_fork
|
||||||
|
func LoopFork(loop *Loop) c.Int
|
||||||
|
|
||||||
|
//go:linkname LoopInit C.uv_loop_init
|
||||||
|
func LoopInit(loop *Loop) c.Int
|
||||||
|
|
||||||
|
//go:linkname LoopNew C.uv_loop_new
|
||||||
|
func LoopNew() *Loop
|
||||||
|
|
||||||
|
//go:linkname LoopNow C.uv_now
|
||||||
|
func LoopNow(loop *Loop) c.UlongLong
|
||||||
|
|
||||||
|
//go:linkname LoopUpdateTime C.uv_update_time
|
||||||
|
func LoopUpdateTime(loop *Loop)
|
||||||
|
|
||||||
|
//go:linkname LoopBackendFd C.uv_backend_fd
|
||||||
|
func LoopBackendFd(loop *Loop) c.Int
|
||||||
|
|
||||||
|
//go:linkname LoopBackendTimeout C.uv_backend_timeout
|
||||||
|
func LoopBackendTimeout(loop *Loop) c.Int
|
||||||
|
|
||||||
|
//go:linkname LoopWalk C.uv_walk
|
||||||
|
func LoopWalk(loop *Loop, walkCb WalkCb, arg c.Pointer)
|
||||||
|
|
||||||
|
// ----------------------------------------------
|
||||||
|
|
||||||
|
/* Buf related functions and method. */
|
||||||
|
|
||||||
|
//go:linkname InitBuf C.uv_buf_init
|
||||||
|
func InitBuf(base *c.Char, len c.Uint) Buf
|
||||||
|
|
||||||
|
// ----------------------------------------------
|
||||||
|
|
||||||
|
/* Poll related function and method */
|
||||||
|
|
||||||
|
//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
|
||||||
|
|
||||||
|
// ----------------------------------------------
|
||||||
|
|
||||||
/* Getaddrinfo related function and method */
|
/* Getaddrinfo related function and method */
|
||||||
|
|
||||||
//go:linkname Getaddrinfo C.uv_getaddrinfo
|
//go:linkname Getaddrinfo C.uv_getaddrinfo
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ type UdpFlags c.Int
|
|||||||
/* Handle types. */
|
/* Handle types. */
|
||||||
|
|
||||||
type Tcp struct {
|
type Tcp struct {
|
||||||
Unused [0]byte
|
Unused [264]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type Udp struct {
|
type Udp struct {
|
||||||
@@ -207,8 +207,8 @@ func (udp *Udp) SetMulticastInterface(interfaceAddr *c.Char) c.Int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// llgo:link (*Udp).SAetBroadcast C.uv_udp_set_broadcast
|
// llgo:link (*Udp).SetBroadcast C.uv_udp_set_broadcast
|
||||||
func (udp *Udp) SAetBroadcast(on c.Int) c.Int {
|
func (udp *Udp) SetBroadcast(on c.Int) c.Int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,15 +218,15 @@ func (udp *Udp) SetTTL(ttl c.Int) c.Int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname Send C.uv_udp_send
|
//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
|
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
|
// llgo:link (*Udp).TrySend C.uv_udp_try_send
|
||||||
func (udp *Udp) TrySend(bufs []Buf, nbufs c.Uint, addr *net.SockAddr) c.Int {
|
func (udp *Udp) TrySend(bufs *Buf, nbufs c.Uint, addr *net.SockAddr) c.Int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// llgo:link (*Udp).RecvStart C.uv_udp_recv_start
|
// llgo:link (*Udp).StartRecv C.uv_udp_recv_start
|
||||||
func (udp *Udp) RecvStart(allocCb AllocCb, recvCb UdpRecvCb) c.Int {
|
func (udp *Udp) StartRecv(allocCb AllocCb, recvCb UdpRecvCb) c.Int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,8 +235,8 @@ func (udp *Udp) UsingRecvmmsg() c.Int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// llgo:link (*Udp).RecvStop C.uv_udp_recv_stop
|
// llgo:link (*Udp).StopRecv C.uv_udp_recv_stop
|
||||||
func (udp *Udp) RecvStop() c.Int {
|
func (udp *Udp) StopRecv() c.Int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,24 +13,20 @@ type Signal struct {
|
|||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|
||||||
/* Signal related functions and method. */
|
/* Function type */
|
||||||
|
|
||||||
// llgo:type C
|
// llgo:type C
|
||||||
type SignalCb func(handle *Signal, sigNum c.Int)
|
type SignalCb func(handle *Signal, sigNum c.Int)
|
||||||
|
|
||||||
//go:linkname UvSignalInit C.uv_signal_init
|
// ----------------------------------------------
|
||||||
func UvSignalInit(loop *Loop, handle *Signal) c.Int
|
|
||||||
|
|
||||||
// llgo:link (*Signal).Start C.uv_signal_start
|
/* Signal related functions and method. */
|
||||||
func (s *Signal) Start(cb SignalCb, signum c.Int) c.Int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Signal).StartOneshot C.uv_signal_start_oneshot
|
//go:linkname SignalInit C.uv_signal_init
|
||||||
func (s *Signal) StartOneshot(handle *Signal, cb SignalCb, signum c.Int) c.Int {
|
func SignalInit(loop *Loop, handle *Signal) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Signal) Init(loop *Loop) int {
|
//go:linkname SignalStart C.uv_signal_start
|
||||||
return UvSignalInit(loop, s)
|
func SignalStart(handle *Signal, cb SignalCb, signum c.Int) c.Int
|
||||||
}
|
|
||||||
|
//go:linkname SignalStartOneshot C.uv_signal_start_oneshot
|
||||||
|
func SignalStartOneshot(handle *Signal, cb SignalCb, signum c.Int) c.Int
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ type Timer struct {
|
|||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|
||||||
// llgo:type C
|
// llgo:type Cgit
|
||||||
type TimerCb func(timer *Timer)
|
type TimerCb func(timer *Timer)
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user