Так и есть. На самом деле,
errno имеет особый статус: она может быть глобальной переменной или функцией, в зависимости от условной директивы
_REENTRANT, определяющей многопоточность.
Покопавшись в исходниках FPC, я увидел, что errno определяется по символу
__errno_location. В итоге, в LinLibc я определил
Код:
TYPE
PInt* = POINTER TO ARRAY [untagged] 1 OF INTEGER;
PROCEDURE [ccall] geterrno* ["__errno_location"] (): PInt; (* get last error for streams *)
PROCEDURE [ccall] seterrno* ["__errno_location"] (err: PInt); (* set last error for streams *)
Проверял на этом коде:
Код:
MODULE TestFilesLibc;
IMPORT Libc := LinLibc;
CONST
pathLen = 260;
invalid = Libc.NULL;
temp = 0; new = 1; shared = 2; hidden = 3; exclusive = 4; closed = 5; (* file states *)
ok = 0;
TYPE
ShortName = ARRAY pathLen OF SHORTCHAR;
PROCEDURE Msg(IN ss: ARRAY OF CHAR);
VAR res, l: INTEGER; s: ARRAY 1024 OF SHORTCHAR;
BEGIN
s := SHORT(ss);
l := LEN(ss$);
s[l] := 0AX; s[l + 1] := 0X;
res := Libc.printf(s);
res := Libc.fflush(Libc.NULL)
END Msg;
PROCEDURE Int (x: LONGINT);
VAR j, k: INTEGER; ch: CHAR; a, s: ARRAY 32 OF CHAR;
BEGIN
IF x # MIN(LONGINT) THEN
IF x < 0 THEN s[0] := "-"; k := 1; x := -x ELSE k := 0 END;
j := 0; REPEAT a[j] := CHR(x MOD 10 + ORD("0")); x := x DIV 10; INC(j) UNTIL x = 0
ELSE
a := "8085774586302733229"; s[0] := "-"; k := 1;
j := 0; WHILE a[j] # 0X DO INC(j) END
END;
ASSERT(k + j < LEN(s), 20);
REPEAT DEC(j); ch := a[j]; s[k] := ch; INC(k) UNTIL j = 0;
s[k] := 0X;
Msg(s);
END Int;
PROCEDURE LastError (): INTEGER;
VAR err: INTEGER; Pres: Libc.PInt;
BEGIN
Pres := Libc.geterrno();
err := Pres[0];
Pres[0] := 0; (* reset last error *)
RETURN err
END LastError;
PROCEDURE Open (name: ARRAY OF CHAR; state: INTEGER);
VAR n: ShortName; ref, res: INTEGER;
BEGIN
n := SHORT(name$);
IF state = shared THEN
Msg(" shared fopen");
ref := Libc.fopen(n, "r")
ELSE
Msg(" excl fopen");
ref := Libc.fopen(n, "r+")
END;
Msg("--");
res := LastError();
IF (res = ok) & (ref # invalid) THEN
res := Libc.fclose(ref)
END;
IF (res = ok) THEN
Msg(" OK")
ELSE
Msg(" res="); Int(res)
END
END Open;
PROCEDURE Do*;
VAR pathToFile: ARRAY pathLen OF SHORTCHAR;
res: INTEGER;
BEGIN
pathToFile := "./Test1.cmps";
Msg("Starting: ");
res := LastError();
Open(pathToFile$, shared)
END Do;
BEGIN
Do
END TestFilesLibc.
DevElfLinker.LinkDll libfiles.so := Kernel+ Files HostFiles TestFilesLibc#~