diff --git a/_demo/fcntl/fcntl.go b/_demo/fcntl/fcntl.go new file mode 100644 index 00000000..11b7918c --- /dev/null +++ b/_demo/fcntl/fcntl.go @@ -0,0 +1,77 @@ +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/fcntl" + "github.com/goplus/llgo/c/os" + "unsafe" +) + +func main() { + + filename := c.Str("testfile.txt") + data := c.Str("Hello, fcntl!") + + var buffer [20]c.Char + + // Open a file, O_CREAT|O_WRONLY|O_TRUNC means create, write only, or clear the file + fd := fcntl.Open(filename, fcntl.O_CREAT|fcntl.O_WRONLY|fcntl.O_TRUNC, 0644) + if fd == -1 { + c.Printf(c.Str("open error\n")) + return + } + + // Writing data to a file + bytesWritten := os.Write(fd, c.Pointer(data), c.Strlen(data)) + if bytesWritten == -1 { + c.Printf(c.Str("write error\n")) + os.Close(fd) + return + } + c.Printf(c.Str("Written %ld bytes to %s\n"), bytesWritten, filename) + + // Get file status flags + flags := fcntl.FcNtl(fd, fcntl.F_GETFL) + if flags == -1 { + c.Printf(c.Str("fcntl error\n")) + os.Close(fd) + return + } + c.Printf(c.Str("File flags: %d\n"), flags) + + // Set the file status flag to non-blocking mode + if fcntl.FcNtl(fd, fcntl.F_SETFL, flags|fcntl.O_NONBLOCK) == -1 { + c.Printf(c.Str("fcntl error\n")) + os.Close(fd) + return + } + c.Printf(c.Str("set file status successfully\n")) + + c.Printf(c.Str("111")) + // Close file + os.Close(fd) + + // Reopen the file, O_RDONLY means read-only + fd = fcntl.Open(filename, fcntl.O_RDONLY) + if fd == -1 { + c.Printf(c.Str("open error\n")) + return + } + + // Reading data from a file + // &buffer[:][0] + // unsafe.SliceData(buffer[:]) + bytesRead := os.Read(fd, c.Pointer(unsafe.SliceData(buffer[:])), unsafe.Sizeof(buffer)-1) + if bytesRead == -1 { + c.Printf(c.Str("read error\n")) + os.Close(fd) + return + } + + // Ensure that the buffer is null-terminated + buffer[bytesRead] = c.Char(0) + c.Printf(c.Str("Read %ld bytes: %s\n"), bytesRead, buffer) + + // Close file + os.Close(fd) +} diff --git a/_demo/fcntl/testfile.txt b/_demo/fcntl/testfile.txt new file mode 100644 index 00000000..48858db3 --- /dev/null +++ b/_demo/fcntl/testfile.txt @@ -0,0 +1 @@ +Hello, fcntl! \ No newline at end of file diff --git a/c/fcntl/fcntl.go b/c/fcntl/fcntl.go new file mode 100644 index 00000000..2c31b8e1 --- /dev/null +++ b/c/fcntl/fcntl.go @@ -0,0 +1,42 @@ +package fcntl + +import ( + _ "unsafe" + + "github.com/goplus/llgo/c" +) + +// #include + +const ( + LLGoPackage = "decl" +) + +const ( + /* get file status flags */ + F_GETFL = 3 + /* set file status flags */ + F_SETFL = 4 + + /* open for reading only */ + O_RDONLY = 0x0000 + /* open for writing only */ + O_WRONLY = 0x0001 + /* open for reading and writing */ + O_RDWR = 0x0002 + /* mask for above modes */ + O_ACCMODE = 0x0003 + + /* no delay */ + O_NONBLOCK = 0x00000004 + /* create if nonexistant */ + O_CREAT = 0x00000200 + /* truncate to zero length */ + O_TRUNC = 0x00000400 +) + +//go:linkname FcNtl C.fcntl +func FcNtl(a c.Int, b c.Int, vars ...any) c.Int + +//go:linkname Open C.open +func Open(path *c.Char, op c.Int, vars ...any) c.Int