diff --git a/_demo/fcntl/fcntl.go b/_demo/fcntl/fcntl.go new file mode 100644 index 00000000..8e312cea --- /dev/null +++ b/_demo/fcntl/fcntl.go @@ -0,0 +1,77 @@ +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/os" + "unsafe" +) + +func main() { + + filename := c.Str("testfile.txt") + data := c.Str("Hello, os!") + var buffer [20]c.Char + + // Open a file, O_CREAT|O_WRONLY|O_TRUNC means create, write only, or clear the file + fd := os.Open(filename, os.O_CREAT|os.O_WRONLY|os.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 := os.Fcntl(fd, os.F_GETFL) + if flags == -1 { + c.Printf(c.Str("os 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 os.Fcntl(fd, os.F_SETFL, flags|os.O_NONBLOCK) == -1 { + c.Printf(c.Str("os 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 = os.Open(filename, os.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[0]) + + // Close file + os.Close(fd) +} diff --git a/c/os/os.go b/c/os/os.go index 04ce435b..583cf631 100644 --- a/c/os/os.go +++ b/c/os/os.go @@ -35,6 +35,29 @@ const ( PATH_MAX = C.PATH_MAX ) +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 +) + type ( ModeT C.mode_t UidT C.uid_t @@ -146,7 +169,7 @@ func Fstatat(dirfd c.Int, path *c.Char, buf *StatT, flags c.Int) c.Int // ----------------------------------------------------------------------------- //go:linkname Open C.open -func Open(path *c.Char, flags c.Int, mode ModeT) c.Int +func Open(path *c.Char, flags c.Int, __llgo_va_list ...any) c.Int //go:linkname Openat C.openat func Openat(dirfd c.Int, path *c.Char, flags c.Int, mode ModeT) c.Int @@ -154,6 +177,9 @@ func Openat(dirfd c.Int, path *c.Char, flags c.Int, mode ModeT) c.Int //go:linkname Creat C.creat func Creat(path *c.Char, mode ModeT) c.Int +//go:linkname Fcntl C.fcntl +func Fcntl(a c.Int, b c.Int, __llgo_va_list ...any) c.Int + //go:linkname Dup C.dup func Dup(fd c.Int) c.Int