Files
Asuro/src/app/app.inio.pas
T
Aaron fcc9809248 vfs: major overhaul — device nodes, stream I/O, mode simplification
- 5-phase VFS architecture overhaul (path resolution, dir cache, watch/notify,
  symlinks, async API)
- Add character/block device node layer with /dev/null and /dev/zero built-ins
- RegisterDevice() API for custom device nodes with read/write/size callbacks
- Merge TOpenMode + TWriteMode into single TOpenMode enum
  (omRead, omWrite, omCreate, omReadWrite, omStream)
- Add stream write support: WriteFile/WriteFileAsync now accept omStream handles
  with auto-advancing offset for both device and volume FDs
- Add PPWriteOffsetHook type and writeOffsetCallback field to TFilesystem
- Add PPReadOffsetHook-based streaming reads for FAT32 and ISO9660
- Update all callers (notepad, edit, inio, wasm runner, filepicker, filedispatch,
  vterminal, stdio) to new 2-param OpenFile API
- 77 unit tests (0 failures) covering path ops, dir cache, symlinks, watch,
  device nodes, and stream read/write
- Add doc/vfs.md — comprehensive public VFS API documentation
2026-03-08 18:07:44 +00:00

146 lines
4.1 KiB
ObjectPascal

{
Prog->app.inio - Inline IO
Usage:
app.inio <file> < Read file contents to terminal
app.inio <file> > text Write text to file
@author(Aaron Hance <[email protected]>)
}
unit app.inio;
interface
uses
io.syslog,
memory.heap,
driver.storage.types,
core.strings,
io.stdio,
debug.tracer,
core.util, arch.x86.util,
driver.storage.vfs;
procedure init();
implementation
procedure Run(Params : PParamList; stdin_buf, stdout_buf, stderr_buf: POutBuf);
var
filePath : pchar;
absPath : pchar;
op : pchar;
fError : driver.storage.types.TError;
fHandle : driver.storage.vfs.TFileHandle;
buf : pchar;
bytesRead : uint32;
content : pchar;
part : pchar;
tmp : pchar;
i : uint32;
pCount : uint32;
contentLen : uint32;
begin
debug.tracer.push_trace('inio.run');
pCount := paramCount(Params);
if pCount < 2 then begin
io.syslog.writestringln('Usage: app.inio <file> < | app.inio <file> > text');
exit;
end;
filePath := getParam(0, Params);
op := getParam(1, Params);
if filePath = nil then begin
io.syslog.writestringln('Error: no file specified.');
exit;
end;
if op = nil then begin
io.syslog.writestringln('Error: no operation specified.');
exit;
end;
absPath := driver.storage.vfs.MakeAbsolutePath(filePath);
{ ---- READ ---- }
if op[0] = '<' then begin
fHandle := driver.storage.vfs.OpenFile(absPath, omRead, @fError);
if (fHandle = 0) or (fError <> eNone) then begin
io.syslog.writestringln('Error: cannot open file for reading.');
kfree(void(absPath));
exit;
end;
buf := pchar(kalloc(32768));
memset(uint32(buf), 0, 32768);
bytesRead := driver.storage.vfs.ReadFile(fHandle, 0, puint8(buf), 32767);
driver.storage.vfs.CloseFile(fHandle);
if bytesRead > 0 then begin
buf[bytesRead] := char(0);
io.syslog.writestring(buf);
io.syslog.writestringln(' ');
end else begin
io.syslog.writestringln('(0 bytes read)');
end;
kfree(puint32(buf));
end
{ ---- WRITE ---- }
else if op[0] = '>' then begin
if pCount < 3 then begin
io.syslog.writestringln('Error: no content to write.');
kfree(void(absPath));
exit;
end;
{ Build content string by joining params 2..N with spaces }
content := stringCopy(getParam(2, Params));
i := 3;
while i < pCount do begin
part := getParam(i, Params);
if part <> nil then begin
{ content + ' ' + part }
tmp := stringConcat(content, ' ');
kfree(void(content));
content := stringConcat(tmp, part);
kfree(void(tmp));
end;
i := i + 1;
end;
contentLen := stringSize(content);
{ Try read-write rewrite first (existing file) }
fHandle := driver.storage.vfs.OpenFile(absPath, omReadWrite, @fError);
if (fHandle = 0) or (fError <> eNone) then begin
{ Try creating new file }
fHandle := driver.storage.vfs.OpenFile(absPath, omCreate, @fError);
end;
if (fHandle = 0) or (fError <> eNone) then begin
io.syslog.writestringln('Error: cannot open file for writing.');
kfree(void(content));
kfree(void(absPath));
exit;
end;
driver.storage.vfs.WriteFile(fHandle, 0, puint8(content), contentLen);
driver.storage.vfs.CloseFile(fHandle);
io.syslog.writestringln('Written.');
kfree(void(content));
end else begin
io.syslog.writestringln('Error: operation must be < or >.');
end;
kfree(void(absPath));
end;
procedure init();
begin
debug.tracer.push_trace('inio.init');
io.stdio.registerCommand('INIO', @Run, 'Inline IO: app.inio <file> < | app.inio <file> > text');
end;
end.