fpc/rtl/bsd/syscalls.inc
2000-02-04 16:53:26 +00:00

435 lines
8.5 KiB
PHP

{
$Id$
This file is part of the Free Pascal run time library.
Copyright (c) 1999-2000 by Michael Van Canneyt,
member of the Free Pascal development team.
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
{BSD version of the syscalls required to implement SysLinux.}
{No debugging for syslinux include !}
{$IFDEF SYS_LINUX}
{$UNDEF SYSCALL_DEBUG}
{$ENDIF SYS_LINUX}
{*****************************************************************************
--- Main:The System Call Self ---
*****************************************************************************}
{ The system designed for Linux can't be used for FreeBSD so easily, since
FreeBSD pushes arguments, instead of loading them to registers.
For now I do them in assembler, which makes it easier to test them (copy and
paste to and AS source). Ultimately I hope to design something like this}
{
Function SysCall( callnr:longint;var regs : SysCallregs ):longint;
{
This function serves as an interface to do_SysCall.
If the SysCall returned a negative number, it returns -1, and puts the
SysCall result in errno. Otherwise, it returns the SysCall return value
}
begin
do_SysCall(callnr,regs);
if regs.reg1<0 then
begin
{$IFDEF SYSCALL_DEBUG}
If DoSysCallDebug then
debugtxt:=' syscall error: ';
{$endif}
ErrNo:=-regs.reg1;
SysCall:=-1;
end
else
begin
{$IFDEF SYSCALL_DEBUG}
if DoSysCallDebug then
debugtxt:=' syscall returned: ';
{$endif}
SysCall:=regs.reg1;
errno:=0
end;
{$IFDEF SYSCALL_DEBUG}
if DoSysCallDebug then
begin
inc(lastcnt);
if (callnr<>lastcall) or (regs.reg1<>lasteax) then
begin
if lastcnt>1 then
writeln(sys_nr_txt[lastcall],debugtxt,lasteax,' (',lastcnt,'x)');
lastcall:=callnr;
lasteax:=regs.reg1;
lastcnt:=0;
writeln(sys_nr_txt[lastcall],debugtxt,lasteax);
end;
end;
{$endif}
end;
}
{$PACKRECORDS C}
{
TYPE timeval=RECORD
tv_sec,
tv_used : int64;
END;
timezone=RECORD
tz_minuteswest,
tz_dsttime : LONGINT;
END;
}
function checkreturnvalue(retval:LONGINT;value:LONGINT):LONGINT;
begin
if retval<0 THEN
begin
errno:=-retval;
checkreturnvalue:=-1;
end
else
begin
checkreturnvalue:=value;
errno:=0
end;
end;
Function Sys_Time:longint;
VAR tv : timeval;
tz : timezone;
retval : longint;
begin
asm
lea tz,%ebx
pushl %ebx
lea tv,%ecx
pushl %ecx
mov $116,%eax
int $0x80
add $8,%esp
mov %eax,retval
end;
sys_time:=checkreturnvalue(retval,tv.sec);
end;
{*****************************************************************************
--- File:File handling related calls ---
*****************************************************************************}
Function Sys_Open(f:pchar;flags:longint;mode:integer):longint;
var retval: LONGINT;
Begin
asm
pushw mode
pushl flags
pushl f
movl $5,%eax
int $0x80
add $10,%esp
mov %eax,retval
end;
sys_open:=checkreturnvalue(retval,retval);
End;
Function Sys_Close(f:longint):longint;
var retval: LONGINT;
begin
asm
pushl f
movl $6,%eax
int $0x80
addl $4,%esp
mov %eax,retval
end;
Sys_Close:=checkreturnvalue(retval,retval);
end;
Function Sys_Lseek(F:longint;Off:longint;Whence:longint):longint;
var retval: LONGINT;
begin
asm
pushl Whence
pushl Off
pushl F
mov $199,%eax
int $0x80
addl $12,%eax
mov %eax,retval
end;
Sys_Lseek:=checkreturnvalue(retval,retval);
end;
Function Sys_Read(f:longint;buffer:pchar;count:longint):longint;
var retval: LONGINT;
begin
asm
pushl Count
pushl Buffer
pushl F
mov $3,%eax
int $0x80
addl $12,%eax
mov %eax,retval
end;
Sys_Read:=checkreturnvalue(retval,retval);
end;
Function Sys_Write(f:longint;buffer:pchar;count:longint):longint;
var retval: LONGINT;
begin
asm
pushl Count
pushl Buffer
pushl F
mov $4,%eax
int $0x80
addl $12,%eax
mov %eax,retval
end;
Sys_Write:=checkreturnvalue(retval,retval);
end;
Function Sys_Unlink(Filename:pchar):longint;
var retval: LONGINT;
begin
asm
pushl FileName
mov $10,%eax
int $0x80
addl $4,%eax
mov %eax,retval
end;
Sys_UnLink:=checkreturnvalue(retval,retval);
end;
Function Sys_Rename(Oldname,Newname:pchar):longint;
var retval: LONGINT;
begin
asm
pushl NewName
pushl OldName
mov $38,%eax
int $0x80
addl $8,%eax
mov %eax,retval
end;
Sys_Rename:=checkreturnvalue(retval,retval);
end;
Function Sys_Stat(Filename:pchar;var Buffer: stat):longint;
{
We need this for getcwd
}
var retval: LONGINT;
begin
asm
pushl buffer
pushl FileName
mov $188,%eax
int $0x80
addl $8,%eax
mov %eax,retval
end;
Sys_Stat:=checkreturnvalue(retval,retval);
end;
Function Sys_Symlink(oldname,newname:pchar):longint;
{
We need this for erase
}
var retval : longint;
begin
asm
pushl newname
pushl oldname
mov $57,%eax
int $0x80
addl $8,%eax
mov %eax,retval
end;
Sys_Symlink:=checkreturnvalue(retval,retval);
end;
{*****************************************************************************
--- Directory:Directory related calls ---
*****************************************************************************}
Function Sys_Chdir(Filename:pchar):longint;
var retval : longint;
begin
asm
pushl FileName
mov $12,%eax
int $0x80
addl $4,%eax
mov %eax,retval
end;
Sys_ChDir:=checkreturnvalue(retval,retval);
end;
Function Sys_Mkdir(Filename:pchar;mode:longint):longint;
var retval : longint;
begin {Mode is 16-bit on F-BSD}
asm
mov mode,%eax
pushw %ax
pushl FileName
mov $136,%eax
int $0x80
addl $6,%eax
mov %eax,retval
end;
Sys_MkDir:=checkreturnvalue(retval,retval);
end;
Function Sys_Rmdir(Filename:pchar):longint;
var retval : longint;
begin
asm
pushl FileName
mov $137,%eax
int $0x80
addl $4,%eax
mov %eax,retval
end;
Sys_RmDir:=checkreturnvalue(retval,retval);
end;
{ we need this for getcwd, NOT touched for BSD version }
Function OpenDir(f:pchar):pdir;
var
fd:integer;
st:stat;
ptr:pdir;
begin
opendir:=nil;
if sys_stat(f,st)<0 then
exit;
{ Is it a dir ? }
if not((st.mode and $f000)=$4000)then
begin
errno:=sys_enotdir;
exit
end;
{ Open it}
fd:=sys_open(f,OPEN_RDONLY,438);
if fd<0 then
exit;
new(ptr);
if ptr=nil then
exit;
new(ptr^.buf);
if ptr^.buf=nil then
exit;
ptr^.fd:=fd;
ptr^.loc:=0;
ptr^.size:=0;
ptr^.dd_max:=sizeof(ptr^.buf^);
opendir:=ptr;
end;
function CloseDir(p:pdir):integer;
begin
closedir:=sys_close(p^.fd);
dispose(p^.buf);
dispose(p);
end;
Function Sys_ReadDir(p:pdir):pdirent;
var
retval : longint;
begin
retval:=SIZEOF(dirent) ;
asm
mov p,%esi
push retval
push tdir.buf(%esi)
push tdir.fd(%esi)
mov $272,%eax
int $0x80
addl $12,%esp
mov %eax,retval
end;
retval:=checkreturnvalue(retval,retval);
if retval=0 then
sys_readdir:=nil
else
sys_readdir:=p^.buf
end;
{*****************************************************************************
--- Process:Process & program handling - related calls ---
*****************************************************************************}
Procedure Sys_Exit(ExitCode:longint);
var retval : longint;
begin
asm
pushl ExitCode
mov $1,%eax
int $0x80
addl $4,%eax
mov %eax,retval
end;
checkreturnvalue(retval,retval); {is nonsense :-)}
end;
{
$Log$
Revision 1.5 2000-02-04 16:53:26 marco
* Finished Linux (and rest syscalls) roughly. Some things still need to be
tested, and checked (off_t calls specially)
Revision 1.4 2000/02/03 17:04:47 marco
* additions fixes due to port linux
Revision 1.3 2000/02/02 18:07:27 marco
* Ported except for readdir which is 200 lines C code in FBSD linux
emulator
Revision 1.2 2000/02/02 16:35:10 marco
* Ported more functions. Half done now.
Revision 1.1 2000/02/02 15:41:56 marco
* Initial BSD version. Still needs a lot of work.
}