[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[tyndur-devel] [PATCH v2 4/8] Pascal-RTL: lio_compat_* statt stdio.h-Funktionen benutzen
* Pascal-RTL: Benutzt jetzt direkt lio_compat_*. Doppelt Puffern ist
Blödsinn und sobald fread() blockiert wie es sollte, ist es vollends
unbrauchbar für unsere Zwecke.
Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
src/modules/pas/lib/rtl/sysfile.inc | 130 +++++++++++++++++++++++-------------
src/modules/pas/lib/rtl/system.pas | 15 +++--
2 files changed, 91 insertions(+), 54 deletions(-)
diff --git a/src/modules/pas/lib/rtl/sysfile.inc b/src/modules/pas/lib/rtl/sysfile.inc
index b0cd787..7d731a1 100644
--- a/src/modules/pas/lib/rtl/sysfile.inc
+++ b/src/modules/pas/lib/rtl/sysfile.inc
@@ -3,25 +3,34 @@ const
SEEK_CUR = 1;
SEEK_END = 2;
-function c_fopen(filename, mode: PChar): THandle; cdecl; external name 'fopen';
-function c_fclose(f: THandle): integer; cdecl; external name 'fclose';
-
-function c_fwrite(src: Pointer; blocksize, blockcount: TSize; f: THandle): TSize; cdecl; external name 'fwrite';
-function c_fread(dest: Pointer; blocksize, blockcount: TSize; f: THandle): TSize; cdecl; external name 'fread';
-function c_fseek(f: THandle; offset, whence: longint): longint; cdecl; external name 'fseek';
-function c_ftell(f: THandle): TSize; cdecl; external name 'ftell';
+const
+ IO_OPEN_MODE_READ = 1;
+ IO_OPEN_MODE_WRITE = 2;
+ IO_OPEN_MODE_APPEND = 4;
+ IO_OPEN_MODE_TRUNC = 8;
+ IO_OPEN_MODE_DIRECTORY = 16;
+ IO_OPEN_MODE_CREATE = 32;
+ IO_OPEN_MODE_LINK = 64;
+ IO_OPEN_MODE_SYNC = 128;
-function c_feof(f: THandle): boolean; cdecl; external name 'feof';
+const
+ EAGAIN = 18;
-function c_setvbuf(f: THandle; buf: Pointer; mode: integer; size: TSize):
- integer; cdecl; external name 'setvbuf';
+function lio_compat_open(filename: PChar; mode: byte): THandle; cdecl; external name 'lio_compat_open';
+function lio_compat_close(io_res: THandle): integer; cdecl; external name 'lio_compat_close';
+function lio_compat_read(dest: Pointer; blocksize, blockcount: TSize; io_res: THandle): TSSize; cdecl; external name 'lio_compat_read';
+function lio_compat_readahead(dest: Pointer; size: TSize; io_res: THandle): TSSize; cdecl; external name 'lio_compat_readahead';
+function lio_compat_write(src: Pointer; blocksize, blockcount: TSize; io_res: THandle): TSSize; cdecl; external name 'lio_compat_write';
+function lio_compat_eof(io_res: THandle): integer; cdecl; external name 'lio_compat_eof';
+function lio_compat_seek(io_res: THandle; offset: qword; origin: integer): boolean; cdecl; external name 'lio_compat_seek';
+function lio_compat_tell(io_res: THandle): int64; cdecl; external name 'lio_compat_tell';
{ TODO errno setzen nicht vergessen }
Procedure Do_Close(f: THandle);
begin
- c_fclose(f);
+ lio_compat_close(f);
end;
Procedure Do_Erase(p:pchar);
@@ -37,49 +46,70 @@ begin { TODO } end;
Function Do_Write(f: THandle; src: Pointer; len: TSize): TSize;
var
- ret: TSize;
+ ret: TSSize;
begin
- InOutRes := 0;
-
- Do_Write := 0;
- while len > 0 do begin
- ret := c_fwrite(src, 1, len, f);
- if (ret = 0) or (ret > len) then begin
- InOutRes := 101;
- exit(0);
- end;
-
- Inc(Do_Write, ret);
- Inc(src, ret);
- Dec(len, ret);
+ ret := lio_compat_write(src, 1, len, f);
+ if ret < 0 then begin
+ InOutRes := 101;
+ Do_Write := 0;
+ end else begin
+ InOutRes := 0;
+ Do_Write := ret;
end;
end;
Function Do_Read(f: THandle; dest: Pointer; len: TSize): TSize;
+var
+ ret: TSSize;
begin
InOutRes := 0;
- repeat
- Do_Read := c_fread(dest, 1, len, f);
- until (Do_Read <> 0) or (c_feof(f));
+ ret := lio_compat_read(dest, 1, len, f);
+ if ret < 0 then begin
+ InOutRes := 101;
+ exit(0);
+ end else begin
+ Do_Read := ret;
+ end;
end;
function Do_FilePos(f: THandle): TSize;
+var
+ ret: int64;
begin
InOutRes := 0;
- Do_FilePos := c_ftell(f);
+ ret := lio_compat_tell(f);
+ if ret < 0 then begin
+ InOutRes := 101;
+ exit(0);
+ end else begin
+ exit(ret);
+ end;
end;
Procedure Do_Seek(f: THandle; position: TSize);
+var
+ ret: boolean;
begin
InOutRes := 0;
- c_fseek(f, position, SEEK_SET);
+ ret := lio_compat_seek(f, position, SEEK_SET);
+ if not ret then begin
+ InOutRes := 101;
+ end;
end;
Function Do_SeekEnd(f: THandle): TSize;
+var
+ ret: boolean;
begin
InOutRes := 0;
- Do_SeekEnd := c_fseek(f, 0, SEEK_END);
+ ret := lio_compat_seek(f, 0, SEEK_END);
+ if not ret then begin
+ InOutRes := 101;
+ exit(0);
+ end else begin
+ exit(Do_FilePos(f));
+ end;
end;
Function Do_FileSize(f: THandle): Longint;
@@ -95,7 +125,8 @@ end;
Procedure Do_Open(var f; name: PChar; flags: longint);
var
- c_mode: string[3];
+ c_mode: byte;
+ autoclose: boolean;
append: boolean;
trunc: boolean;
frec: ^FileRec;
@@ -103,50 +134,55 @@ begin
InOutRes := 0;
frec := @FileRec(f);
+ append := (flags and $100 <> 0);
+ trunc := (flags and $1000 <> 0);
+ autoclose := (flags and $10000 <> 0);
+
// Wenn eine Datei noch geoeffnet ist, muss sie zuerst
// geschlossen werden.
- if (frec^.mode = fminput) or (frec^.mode = fmoutput) or (frec^.mode = fminout) then begin
+ if autoclose
+ and ((frec^.mode = fminput) or (frec^.mode = fmoutput) or (frec^.mode = fminout))
+ and (frec^.handle <> 0)
+ then begin
Do_Close(frec^.handle);
end;
-
- append := (flags and $100 <> 0);
- trunc := (flags and $1000 <> 0);
if name <> '' then begin
// Eine normale Datei
case flags and 3 of
0: begin
- c_mode := 'r'#0;
+ c_mode := IO_OPEN_MODE_READ;
frec^.mode := fmInput;
end;
1: begin
+ c_mode := IO_OPEN_MODE_WRITE;
if append then begin
- c_mode := 'a'#0
- end else begin
- c_mode := 'w'#0;
+ c_mode := c_mode or IO_OPEN_MODE_APPEND;
+ end else if trunc then begin
+ c_mode := c_mode or IO_OPEN_MODE_CREATE or IO_OPEN_MODE_TRUNC;
end;
frec^.mode := fmOutput;
end;
- 2: begin
+ 2: begin
if append then begin
- c_mode := 'a+'#0
+ c_mode := IO_OPEN_MODE_READ or IO_OPEN_MODE_WRITE
+ or IO_OPEN_MODE_CREATE or IO_OPEN_MODE_APPEND;
end else if trunc then begin
- c_mode := 'w+'#0
+ c_mode := IO_OPEN_MODE_READ or IO_OPEN_MODE_WRITE
+ or IO_OPEN_MODE_CREATE or IO_OPEN_MODE_TRUNC;
end else begin
- c_mode := 'r+'#0;
+ c_mode := IO_OPEN_MODE_READ or IO_OPEN_MODE_WRITE;
end;
frec^.mode := fmInOut;
end;
end;
- frec^.handle := c_fopen(name, @c_mode[1]);
+ frec^.handle := lio_compat_open(name, c_mode);
if frec^.handle = 0 then begin
InOutRes := 2;
- end else begin
- c_setvbuf(frec^.handle, nil, 1, 0);
end;
end else begin
diff --git a/src/modules/pas/lib/rtl/system.pas b/src/modules/pas/lib/rtl/system.pas
index a658a37..14661a3 100644
--- a/src/modules/pas/lib/rtl/system.pas
+++ b/src/modules/pas/lib/rtl/system.pas
@@ -12,6 +12,7 @@ interface
type
TSize = dword;
+ TSSize = longint;
const
LineEnding = #10;
@@ -48,7 +49,7 @@ const
DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsLF;
var
- argc: dword;
+ argc: integer;
argv: PPChar;
commandline: PChar;
@@ -168,9 +169,9 @@ function c_setvbuf(f: Pointer; buf: Pointer; mode: integer; size: TSize):
integer; cdecl; external name 'setvbuf';
var
- c_stdin: dword; external name 'stdin';
- c_stdout: dword; external name 'stdout';
- c_stderr: dword; external name 'stderr';
+ c_stdin: ^dword; external name 'stdin';
+ c_stdout: ^dword; external name 'stdout';
+ c_stderr: ^dword; external name 'stderr';
procedure SysInitStdIO;
(*
@@ -200,9 +201,9 @@ begin
c_stdio_init();
- StdInputHandle := c_stdin;
- StdOutputHandle := c_stdout;
- StdErrorHandle := c_stderr;
+ StdInputHandle := c_stdin^;
+ StdOutputHandle := c_stdout^;
+ StdErrorHandle := c_stderr^;
c_setvbuf(c_stdout, nil, 1, 0);
--
2.1.4