file io working

This commit is contained in:
Aaron committed 2026-02-28 14:42:30 +00:00
1 parent 8b80b6864b
commit 84b589c856
23 files changed
+4084 -587

No files matched your search

+1 -1
View File
@@ -4,4 +4,4 @@ echo "======================="
echo " "
echo "Compiling FPC Sources..."
echo " "
fpc -Aelf -gw -n -O3 -Op3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/driver/storage/* -Fusrc/driver/storage/AHCI/* -Fusrc/driver/* -Fusrc/driver/net/* src/kernel.pas
fpc -Aelf -gw -n -O3 -Op3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/driver/storage/* -Fusrc/driver/storage/AHCI/* -Fusrc/driver/* -Fusrc/driver/net/* -Fusrc/prog/* src/kernel.pas
+185
View File
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+7 -7
View File
@@ -20,15 +20,15 @@
unit AHCITypes;
interface
uses
util,
PCI,
drivertypes,
drivermanagement,
lmemorymanager,
console,
vmemorymanager,
drivermanagement,
drivertypes,
idetypes,
lists;
lists,
lmemorymanager,
PCI,
util,
vmemorymanager;
const
AHCI_CONTROLLER_MODE = $80000000;
+1 -1
View File
@@ -140,7 +140,7 @@ begin
writestringlnWND('MBR already exists', getTerminalHWND());
//write first partiton sectorStart and sectorCount
//write first partition sectorStart and sectorCount
writeintlnWND(mb^.partition[0].LBA_start, getTerminalHWND());
writeintlnWND(mb^.partition[0].sector_count, getTerminalHWND());
+7 -6
View File
@@ -23,14 +23,15 @@ interface
uses
console,
storagemanagement,
util, terminal,
lmemorymanager,
strings,
lists,
tracer,
lmemorymanager,
rtc,
serial,
rtc;
storagemanagement,
strings,
terminal,
tracer,
util;
type
File diff suppressed because it is too large. Load diff
+120
View File
@@ -0,0 +1,120 @@
{
Driver->Storage->FilesystemManager - Filesystem driver registry and routing.
Filesystem drivers (FAT32, FlatFS, etc.) register themselves here.
When VolumeManager discovers a volume, FilesystemManager probes it
against all registered filesystem drivers to detect the filesystem type.
@author(Aaron Hance <[email protected]>)
}
unit filesystemmanager;
interface
uses
lists,
lmemorymanager,
storagetypes,
strings,
tracer,
util;
var
filesystems : PLinkedListBase;
procedure init();
procedure register_filesystem(filesystem : PFilesystem);
function get_filesystem_count() : uint32;
function get_filesystem(index : uint32) : PFilesystem;
function find_filesystem_by_name(name : pchar) : PFilesystem;
function find_filesystem_by_id(system_id : uint8) : PFilesystem;
procedure probe_volume(volume : PStorage_Volume);
implementation
procedure init();
begin
push_trace('FilesystemManager.init');
filesystems := LL_New(sizeof(TFilesystem));
end;
procedure register_filesystem(filesystem : PFilesystem);
var
elm : void;
begin
push_trace('FilesystemManager.register_filesystem');
elm := LL_Add(filesystems);
memcpy(uint32(filesystem), uint32(elm), sizeof(TFilesystem));
end;
function get_filesystem_count() : uint32;
begin
get_filesystem_count := LL_Size(filesystems);
end;
function get_filesystem(index : uint32) : PFilesystem;
begin
if index < LL_Size(filesystems) then
get_filesystem := PFilesystem(LL_Get(filesystems, index))
else
get_filesystem := nil;
end;
function find_filesystem_by_name(name : pchar) : PFilesystem;
var
i : uint32;
fs : PFilesystem;
begin
push_trace('FilesystemManager.find_filesystem_by_name');
find_filesystem_by_name := nil;
for i := 0 to LL_Size(filesystems) - 1 do begin
fs := PFilesystem(LL_Get(filesystems, i));
if stringEquals(fs^.sName, name) then begin
find_filesystem_by_name := fs;
exit;
end;
end;
end;
function find_filesystem_by_id(system_id : uint8) : PFilesystem;
var
i : uint32;
fs : PFilesystem;
begin
push_trace('FilesystemManager.find_filesystem_by_id');
find_filesystem_by_id := nil;
for i := 0 to LL_Size(filesystems) - 1 do begin
fs := PFilesystem(LL_Get(filesystems, i));
if fs^.system_id = system_id then begin
find_filesystem_by_id := fs;
exit;
end;
end;
end;
procedure probe_volume(volume : PStorage_Volume);
var
i : uint32;
fs : PFilesystem;
begin
push_trace('FilesystemManager.probe_volume.enter');
{ Try each registered filesystem's identify callback against this volume }
for i := 0 to LL_Size(filesystems) - 1 do begin
fs := PFilesystem(LL_Get(filesystems, i));
if fs^.identifyCallback <> nil then begin
push_trace('FilesystemManager.probe_volume.tryFS');
if fs^.identifyCallback(volume) then begin
volume^.filesystem := fs;
push_trace('FilesystemManager.probe_volume.found');
exit;
end;
end;
end;
push_trace('FilesystemManager.probe_volume.exit');
end;
end.
+91 -12
View File
@@ -25,13 +25,14 @@ interface
uses
tracer,
strings,
volumemanager,
filesystemmanager,
lists,
console,
terminal,
storagetypes,
lmemorymanager,
util;
util,
volumemanager;
type
@@ -547,26 +548,30 @@ var
begin
push_trace('flatfs.detectVolumes()');
volume:= PStorage_volume(kalloc(sizeof(TStorage_Volume)));
//check first address for MBR
//if found then add volume and use info to see if there is another volume
buffer := puint32(kalloc(512));
memset(uint32(buffer), 0, 512);
disk^.readcallback(disk, 2, 1, buffer);
if disk^.readCallback = nil then begin
console.writestringln('FlatFS: detect_volumes: device has no read callback.');
kfree(buffer);
exit;
end;
disk^.readcallback(disk, 2, 1, buffer);
if (PDisk_Info(buffer)^.signature = $0B00B1E5) then begin
console.writestringln('FlatFS: volume found!');
volume := PStorage_volume(kalloc(sizeof(TStorage_Volume)));
memset(uint32(volume), 0, sizeof(TStorage_Volume));
volume^.device := disk;
volume^.sectorStart := 2;
volume^.sectorSize := 512;
volume^.sectorCount := PDisk_Info(buffer)^.sectorCount;
volume^.freeSectors:= 1000000; //TODO implement get free sectors need FSINFO implemented first
volume^.freeSectors := 0; { TODO: implement free sector count }
volume^.filesystem := @filesystem;
volume^.isBootDrive := false;
// storagemanagement.register_volume(disk, volume); TODO repalce with new thing
volumemanager.register_volume(disk, volume);
end;
kfree(buffer);
@@ -705,20 +710,94 @@ begin
end;
function identify_volume(volume : PStorage_Volume) : boolean;
var
buffer : puint32;
begin
push_trace('flatfs.identify_volume');
identify_volume := false;
if volume^.device^.readCallback = nil then exit;
buffer := puint32(kalloc(512));
memset(uint32(buffer), 0, 512);
volume^.device^.readCallback(volume^.device, volume^.sectorStart, 1, buffer);
if (PDisk_Info(buffer)^.signature = $0B00B1E5) then
identify_volume := true;
kfree(buffer);
end;
function readDirectoryEntries(volume : PStorage_Volume; directory : pchar; status : PuInt32) : PLinkedListBase;
var
entries : PLinkedListBase;
fileEntrys : PFile_Entry;
i : uint32;
compString : PChar;
afterString : PChar;
slash : PChar;
fileCount : uint32;
dirEntry : PDirectory_Entry;
elm : void;
slashArray : array[0..1] of char;
begin
push_trace('flatfs.readDirectoryEntries');
fileCount := 1000;
slashArray[0] := '/';
slashArray[1] := char(0);
entries := LL_New(sizeof(TDirectory_Entry));
fileEntrys := PFile_Entry(Kalloc(sizeof(TFile_Entry) * fileCount + 512));
volume^.device^.readCallback(volume^.device, volume^.sectorStart + 1,
sizeof(TFile_Entry) * fileCount div 512, puint32(fileEntrys));
slash := stringNew(2);
memcpy(uint32(@slashArray), uint32(slash), 1);
for i := 0 to fileCount - 1 do begin
if uint32(fileEntrys[i].name[0]) = 0 then break;
compString := stringSub(fileEntrys[i].name, 0, stringSize(directory));
afterString := stringSub(fileEntrys[i].name, stringSize(directory),
stringSize(fileEntrys[i].name) - 1);
if stringEquals(compString, directory) and
(not stringContains(afterString, slash)) then begin
elm := LL_Add(entries);
dirEntry := PDirectory_Entry(elm);
dirEntry^.fileName := stringCopy(afterString);
dirEntry^.extension := nil;
if fileEntrys[i].attribues and $10 = $10 then
dirEntry^.entryType := TDirectory_Entry_Type.directoryEntry
else
dirEntry^.entryType := TDirectory_Entry_Type.fileEntry;
end;
kfree(void(compString));
kfree(void(afterString));
end;
Kfree(puint32(fileEntrys));
kfree(void(slash));
readDirectoryEntries := entries;
end;
procedure init();
begin
push_trace('flatfs.init()');
filesystem.sName:= 'flatfs';
filesystem.system_id:= $02;
filesystem.readDirCallback:= @read_directory;
filesystem.readDirCallback:= @readDirectoryEntries;
// filesystem.createDirCallback:= @writeDirectoryGen;
filesystem.createcallback:= @create_volume;
filesystem.detectcallback:= @detect_volumes;
filesystem.identifyCallback:= @identify_volume;
// filesystem.writecallback:= @writeFile;
// filesystem.readcallback := @readFile;
// filesystem.formatVolumeCallback := @create_volume;
volumemanager.register_filesystem(@filesystem);
filesystemmanager.register_filesystem(@filesystem);
end;
+12 -11
View File
@@ -1,6 +1,6 @@
{ ************************************************
* Asuro
* Unit: Drivers/storage/partitontable
* Unit: Drivers/storage/partitiontable
* Description: partionTable
*
************************************************
@@ -8,32 +8,33 @@
* Contributors:
************************************************ }
unit partitontable;
unit partitiontable;
interface
uses
console,
storagemanagement,
util, terminal,
lmemorymanager,
strings,
lists,
lmemorymanager,
rtc,
storagemanagement,
strings,
terminal,
tracer,
rtc;
util;
type
TPartitonTable = record
TpartitionTable = record
end;
PPartitonTable = ^TPartitonTable;
PpartitionTable = ^TpartitionTable;
var
location = $1BE;
procedure create_new(device : PStorage_Device);
function get_table() : PPartitonTable;
function get_table() : PpartitionTable;
procedure add_volume(volume : TStorage_Volume);
implementation
@@ -45,7 +46,7 @@ begin
end;
function get_table() : PPartitonTable;
function get_table() : PpartitionTable;
procedure add_volume(volume : TStorage_Volume);
end.
+96
View File
@@ -0,0 +1,96 @@
{
Driver->Storage->StorageManager - Physical storage device registry.
Manages registration of physical storage devices (AHCI, IDE, USB, etc.)
and provides a global device list plus raw MBR read/write.
Device drivers call register_device() when they discover a new device.
@author(Aaron Hance <[email protected]>)
}
unit storagemanager;
interface
uses
lists,
lmemorymanager,
MBR,
storagetypes,
tracer,
util;
var
storageDevices : PDList;
procedure init();
procedure register_device(device : PStorage_Device);
function get_device_list() : PDList;
function get_device_count() : uint32;
function get_device(index : uint32) : PStorage_Device;
function controller_type_2_string(controllerType : TControllerType) : pchar;
function read_mbr(device : PStorage_Device) : PMaster_Boot_Record;
procedure write_mbr(device : PStorage_Device; mbr : PMaster_Boot_Record);
implementation
procedure init();
begin
push_trace('StorageManager.init');
storageDevices := DL_New(sizeof(TStorage_Device));
end;
procedure register_device(device : PStorage_Device);
begin
push_trace('StorageManager.register_device');
DL_Add(storageDevices);
DL_Set(storageDevices, DL_Size(storageDevices) - 1, puint32(device));
end;
function get_device_list() : PDList;
begin
get_device_list := storageDevices;
end;
function get_device_count() : uint32;
begin
get_device_count := DL_Size(storageDevices);
end;
function get_device(index : uint32) : PStorage_Device;
begin
if index < DL_Size(storageDevices) then
get_device := PStorage_Device(DL_Get(storageDevices, index))
else
get_device := nil;
end;
function controller_type_2_string(controllerType : TControllerType) : pchar;
begin
case controllerType of
ControllerATA: controller_type_2_string := 'ATA';
ControllerATAPI: controller_type_2_string := 'ATAPI';
ControllerUSB: controller_type_2_string := 'USB';
ControllerAHCI: controller_type_2_string := 'AHCI';
ControllerAHCI_ATAPI: controller_type_2_string := 'AHCI_ATAPI';
ControllerNVMe: controller_type_2_string := 'NVMe';
ControllerNET: controller_type_2_string := 'NET';
ControllerRAM: controller_type_2_string := 'RAM';
ControllerSCSI: controller_type_2_string := 'SCSI';
end;
end;
function read_mbr(device : PStorage_Device) : PMaster_Boot_Record;
begin
push_trace('StorageManager.read_mbr');
read_mbr := PMaster_Boot_Record(kalloc(sizeof(TMaster_Boot_Record)));
device^.readCallback(device, 0, 1, puint32(read_mbr));
end;
procedure write_mbr(device : PStorage_Device; mbr : PMaster_Boot_Record);
begin
push_trace('StorageManager.write_mbr');
if not device^.writable then exit;
device^.writeCallback(device, 0, 1, puint32(mbr));
end;
end.
+48 -5
View File
@@ -26,6 +26,7 @@ uses
type
{ Controller types }
TControllerType = (
ControllerATA,
ControllerATAPI,
@@ -38,6 +39,7 @@ type
ControllerSCSI
);
{ Filesystem type identifiers }
TFileSystemType = (
FileSystemFAT32,
FileSystemExFAT,
@@ -47,12 +49,31 @@ type
FileSystemOther
);
{ Directory entry types }
TDirectory_Entry_Type = (directoryEntry, fileEntry, mountEntry);
{ Forward declarations }
PStorage_device = ^TStorage_Device;
PStorage_Volume = ^TStorage_Volume;
PFilesystem = ^TFilesystem;
PDirectory_Entry = ^TDirectory_Entry;
PDrive_Error = ^TDrive_Error;
{ Block I/O callback for raw device access }
PPHIOHook = procedure(drive : PStorage_device; addr : uint32; sectors : uint32; buffer : puint32);
PPHIOHook_ = procedure;
{ Filesystem callback types }
PPWriteHook = procedure(volume : PStorage_volume; directory : pchar; entry : PDirectory_Entry; byteCount : uint32; buffer : puint32; statusOut : puint32);
PPReadHook = function(volume : PStorage_Volume; directory : pchar; fileName : pchar; fileExtension : pchar; buffer : puint32; bytecount : puint32) : uint32;
PPCreateHook = procedure(volume : PStorage_volume; start : uint32; size : uint32; config : puint32);
PPDetectHook = procedure(disk : PStorage_Device);
PPCreateDirHook = procedure(volume : PStorage_volume; directory : pchar; dirname : pchar; attributes : uint32; status : puint32);
PPReadDirHook = function(volume : PStorage_volume; directory : pchar; status : puint32) : PLinkedListBase;
PPDeleteFileHook = procedure(volume : PStorage_Volume; filePath : pchar; status : puint32);
PPDeleteDirHook = procedure(volume : PStorage_Volume; path : pchar; status : puint32);
PPIdentifyHook = function(volume : PStorage_Volume) : boolean;
byteArray8 = array[0..7] of char;
PByteArray8 = ^byteArray8;
@@ -70,17 +91,39 @@ type
start : uint32; //start of device in sectors
end;
{ Filesystem driver descriptor }
TFilesystem = record
sName : pchar;
system_id : uint8;
writeCallback : PPWriteHook;
readCallback : PPReadHook;
createCallback : PPCreateHook;
detectCallback : PPDetectHook;
createDirCallback : PPCreateDirHook;
readDirCallback : PPReadDirHook;
deleteFileCallback : PPDeleteFileHook;
deleteDirCallback : PPDeleteDirHook;
identifyCallback : PPIdentifyHook;
end;
{ Generic storage volume }
TStorage_Volume = record
id : uint32;
device : PStorage_device;
name : pchar;
fileSystem : TFileSystemType;
size : uint32; //size of volume in sectors
start : uint32; //start of volume in sectors
sectorStart : uint32;
sectorSize : uint32;
sectorCount : uint32;
freeSectors : uint32;
filesystem : PFilesystem;
isBootDrive : boolean;
end;
PStorage_Volume = ^TStorage_Volume;
{ Generic directory entry }
TDirectory_Entry = record
fileName : pchar;
extension : pchar;
entryType : TDirectory_Entry_Type;
end;
TDrive_Error = record
code : uint16;
+899 -146
View File
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+42 -7
View File
@@ -23,9 +23,9 @@ unit strings;
interface
uses
util,
lists,
lmemorymanager,
lists;
util;
function stringToUpper(str : pchar) : pchar;
function stringToLower(str : pchar) : pchar;
@@ -116,6 +116,11 @@ var
size : uint32;
begin
if str = nil then begin
result := stringNew(0);
stringCopy := result;
exit;
end;
size:= stringSize(str);
result:= stringNew(size);
memcpy(uint32(str), uint32(result), size);
@@ -137,6 +142,10 @@ var
i : uint32;
begin
if str = nil then begin
stringSize := 0;
exit;
end;
i:=0;
while byte(str[i]) <> 0 do begin
inc(i);
@@ -300,8 +309,30 @@ begin
end;
function intToString(i : uint32) : pchar;
var
buf : array[0..11] of char;
p : uint32;
tmp : uint32;
begin
intToString:= ' ';
if i = 0 then begin
intToString := stringNew(1);
intToString[0] := '0';
exit;
end;
for p := 0 to 11 do buf[p] := char(0);
p := 10;
tmp := i;
while tmp > 0 do begin
buf[p] := char(ord('0') + (tmp mod 10));
tmp := tmp div 10;
if (tmp > 0) and (p > 0) then
p := p - 1;
end;
intToString := stringCopy(@buf[p]);
end;
function boolToString(b : boolean; ext : boolean) : pchar;
@@ -311,11 +342,15 @@ var
begin
if ext then begin
t:= stringCopy('true');
f:= stringCopy('false');
t:= stringNew(4);
t[0]:= 't'; t[1]:= 'r'; t[2]:= 'u'; t[3]:= 'e';
f:= stringNew(5);
f[0]:= 'f'; f[1]:= 'a'; f[2]:= 'l'; f[3]:= 's'; f[4]:= 'e';
end else begin
t:= stringCopy('1');
f:= stringCopy('0');
t:= stringNew(1);
t[0]:= '1';
f:= stringNew(1);
f[0]:= '0';
end;
if b then begin
kfree(void(f));
+19 -8
View File
@@ -42,11 +42,13 @@ uses
IDE,
// storagemanagement,
// drivemanager,
storagemanager,
volumemanager,
filesystemmanager,
lists,
net,
// fat32,
// flatfs,
fat32,
flatfs,
isrmanager,
faults,
fonts,
@@ -59,7 +61,10 @@ uses
terminal,
hashmap, vfs,
AHCI,
AHCITest;
AHCITest,
diskcmd,
partcmd,
volcmd;
procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall;
@@ -210,9 +215,9 @@ begin
tracer.push_trace('kmain.DRVMGMT');
drivermanagement.init();
tracer.push_trace('kmain.STRMGMT');
// storagemanagement.init();
// drivemanager.init();
// volumemanager.init();
storagemanager.init();
volumemanager.init();
filesystemmanager.init();
{ Hook Timer for Ticks }
tracer.push_trace('kmain.TMR');
@@ -220,8 +225,8 @@ begin
TMR_0_ISR.hook(uint32(@bios_data_area.tick_update));
{ Filsystems }
// fat32.init();
// flatfs.init();
fat32.init();
flatfs.init();
{ Device Drivers }
tracer.push_trace('kmain.DEVDRV');
@@ -233,6 +238,9 @@ begin
// IDE.init();
AHCI.init();
AHCITest.init();
diskcmd.init();
partcmd.init();
volcmd.init();
console.outputln('KERNEL', 'DEVICE DRIVERS: INIT END.');
{ Bus Drivers }
@@ -242,6 +250,9 @@ begin
pci.init();
console.outputln('KERNEL', 'BUS DRIVERS: INIT END.');
{ Auto-mount discovered volumes into VFS }
vfs.auto_mount_volumes();
{ Network Stack }
tracer.push_trace('kmain.NETDRV');
net.init;
+8 -1
View File
@@ -177,15 +177,22 @@ var
i, j : uint32;
hp : PHeapPage;
miss : boolean;
maxSearch : uint32;
begin
//push_trace('lmemorymanager.kalloc');
Heap_Entries:= size div 8;
If sint32(size-(Heap_Entries*8)) > 0 then Heap_Entries:= Heap_Entries + 1;
{ Prevent searching past end of Entries array }
if Heap_Entries > MAX_ENTRIES then begin
kalloc := nil;
exit;
end;
maxSearch := MAX_ENTRIES - Heap_Entries;
hp:= Search_Page;
kalloc:= nil;
while kalloc = nil do begin
for i:=0 to MAX_ENTRIES-1 do begin
for i:=0 to maxSearch do begin
miss:= false;
for j:=0 to Heap_Entries-1 do begin
if hp^.Entries[i+j].Present then begin
File diff suppressed because it is too large. Load diff
+589 -146
View File
File diff suppressed because it is too large. Load diff
+144
View File
@@ -0,0 +1,144 @@
{
Prog->inio - Inline IO
Usage:
inio <file> < Read file contents to terminal
inio <file> > text Write text to file
@author(Aaron Hance <[email protected]>)
}
unit inio;
interface
uses
console,
lmemorymanager,
strings,
terminal,
tracer,
util,
vfs;
procedure init();
implementation
procedure Run(Params : PParamList);
var
filePath : pchar;
absPath : pchar;
op : pchar;
fError : vfs.TError;
fHandle : vfs.TFileHandle;
buf : pchar;
bytesRead : uint32;
content : pchar;
part : pchar;
tmp : pchar;
i : uint32;
pCount : uint32;
contentLen : uint32;
begin
tracer.push_trace('inio.run');
pCount := paramCount(Params);
if pCount < 2 then begin
console.writestringlnWND('Usage: inio <file> < | inio <file> > text', getTerminalHWND());
exit;
end;
filePath := getParam(0, Params);
op := getParam(1, Params);
if filePath = nil then begin
console.writestringlnWND('Error: no file specified.', getTerminalHWND());
exit;
end;
if op = nil then begin
console.writestringlnWND('Error: no operation specified.', getTerminalHWND());
exit;
end;
absPath := vfs.MakeAbsolutePath(filePath);
{ ---- READ ---- }
if op[0] = '<' then begin
fHandle := vfs.OpenFile(absPath, omReadOnly, wmRewrite, false, @fError);
if (fHandle = 0) or (fError <> eNone) then begin
console.writestringlnWND('Error: cannot open file for reading.', getTerminalHWND());
kfree(void(absPath));
exit;
end;
buf := pchar(kalloc(32768));
memset(uint32(buf), 0, 32768);
bytesRead := vfs.ReadFile(fHandle, 0, puint8(buf), 32767);
vfs.CloseFile(fHandle);
if bytesRead > 0 then begin
buf[bytesRead] := char(0);
console.writestringWND(buf, getTerminalHWND());
console.writestringlnWND(' ', getTerminalHWND());
end else begin
console.writestringlnWND('(0 bytes read)', getTerminalHWND());
end;
kfree(puint32(buf));
end
{ ---- WRITE ---- }
else if op[0] = '>' then begin
if pCount < 3 then begin
console.writestringlnWND('Error: no content to write.', getTerminalHWND());
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 := vfs.OpenFile(absPath, omReadWrite, wmRewrite, false, @fError);
if (fHandle = 0) or (fError <> eNone) then begin
{ Try creating new file }
fHandle := vfs.OpenFile(absPath, omWriteOnly, wmNew, false, @fError);
end;
if (fHandle = 0) or (fError <> eNone) then begin
console.writestringlnWND('Error: cannot open file for writing.', getTerminalHWND());
kfree(void(content));
kfree(void(absPath));
exit;
end;
vfs.WriteFile(fHandle, 0, puint8(content), contentLen);
vfs.CloseFile(fHandle);
console.writestringlnWND('Written.', getTerminalHWND());
kfree(void(content));
end else begin
console.writestringlnWND('Error: operation must be < or >.', getTerminalHWND());
end;
kfree(void(absPath));
end;
procedure init();
begin
tracer.push_trace('inio.init');
terminal.registerCommand('INIO', @Run, 'Inline IO: inio <file> < | inio <file> > text');
end;
end.
Loaded 20 of 23 files, more files were not shown because too many files have changed in this diff. Show more