Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions backend/paket.dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ nuget FSharp.Core = 10.0.100
nuget System.Text.Json = 10.0.0
nuget NodaTime = 3.2.2
nuget System.IO.Hashing 10.0.0
nuget Wcwidth = 4.0.1

// Sqlite and binary serialization
nuget Microsoft.Data.Sqlite = 10.0.0
Expand Down
1 change: 1 addition & 0 deletions backend/paket.lock
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,4 @@ NUGET
System.Memory (4.6.3)
System.Text.Json (10.0)
System.Threading.Tasks.Extensions (4.6.3)
Wcwidth (4.0.1)
2 changes: 1 addition & 1 deletion backend/src/Builtins/Builtins.Cli/Builtins.Cli.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
<Compile Include="Libs/Output.fs" />
<Compile Include="Libs/Execution.fs" />
<Compile Include="Libs/Stdin.fs" />
<Compile Include="Libs/Terminal.fs" />
<Compile Include="Libs/Posix.fs" />
<Compile Include="Libs/Terminal.fs" />
<Compile Include="Builtin.fs" />
</ItemGroup>
<ItemGroup>
Expand Down
75 changes: 75 additions & 0 deletions backend/src/Builtins/Builtins.Cli/Libs/Posix.fs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ module Libc =
[<DllImport("libc", EntryPoint = "read", SetLastError = true)>]
extern int private read_raw(int fd, byte[] buf, int count)

[<DllImport("libc", EntryPoint = "lseek", SetLastError = true)>]
extern int64 private lseek_raw(int fd, int64 offset, int whence)

[<DllImport("libc", EntryPoint = "ioctl", SetLastError = true)>]
extern int private ioctl_raw(int fd, uint64 request, IntPtr argument)

[<DllImport("libc", EntryPoint = "write", SetLastError = true)>]
extern int private write_raw(int fd, byte[] buf, int count)

Expand Down Expand Up @@ -151,6 +157,10 @@ module Libc =

let O_APPEND = if isMac then 0x8 else 0x400 // Linux

let SEEK_SET = 0
let SEEK_CUR = 1
let SEEK_END = 2


// -- Wrappers -----------------------------------------------------

Expand Down Expand Up @@ -362,6 +372,39 @@ module Libc =
let n = read_raw (fd, buf, count)
if n < 0 then Error(lastError ()) else Ok(buf[0 .. n - 1])

let fdSeek
(fd : int)
(offset : int64)
(whence : int)
: Result<int64, int * string> =
let position = lseek_raw (fd, offset, whence)
if position < 0L then Error(lastError ()) else Ok position

/// Read one terminal file descriptor's window size as (columns, rows).
let tryTerminalWindowSize (fd : int) : Option<int64 * int64> =
if OperatingSystem.IsWindows() then
None
else
let request =
if isMac then
0x40087468UL // TIOCGWINSZ on Darwin
else
0x5413UL // TIOCGWINSZ on Linux

let buffer = Marshal.AllocHGlobal 8
try
if ioctl_raw (fd, request, buffer) = 0 then
let rows = uint16 (Marshal.ReadInt16(buffer, 0))
let columns = uint16 (Marshal.ReadInt16(buffer, 2))
if rows > 0us && columns > 0us then
Some(int64 columns, int64 rows)
else
None
else
None
finally
Marshal.FreeHGlobal buffer

let fdWrite (fd : int) (data : byte[]) : Result<int, int * string> =
let mutable offset = 0
let mutable error = None
Expand Down Expand Up @@ -972,6 +1015,38 @@ let fns () : List<BuiltInFn> =
deprecated = NotDeprecated }


{ name = fn "posixFdSeek" 0
typeParams = []
parameters =
[ Param.make "fd" TInt "File descriptor to reposition"
Param.make "offset" TInt "Byte offset"
Param.make
"whence"
TInt
"Seek origin: 0 for start, 1 for current position, 2 for end" ]
returnType = TypeReference.result TInt (posixErrorTypeRef ())
description =
"Seeks to a new position in an open file and returns the resulting byte offset."
fn =
(function
| _, vm, _, [ DInt fd; DInt offset; DInt whence ] ->
let resultOk = Dval.resultOk KTInt (posixErrorKT ())
let resultError = Dval.resultError KTInt (posixErrorKT ())
match
Libc.fdSeek
(intToInt32 vm fd)
(intToInt64 vm offset)
(intToInt32 vm whence)
with
| Ok position -> resultOk (Dval.int (bigint position)) |> Ply
| Error e -> resultError (dPosixError e) |> Ply
| _ -> incorrectArgs ())
sqlSpec = NotQueryable
previewable = Impure
capabilities = LibExecution.Capabilities.Needs.fileReadWrite
deprecated = NotDeprecated }


{ name = fn "posixFdWrite" 0
typeParams = []
parameters =
Expand Down
Loading