From 77dd315869bbcbcdafbd7e32f1f78a92cd9b5a46 Mon Sep 17 00:00:00 2001 From: marco <marco@freepascal.org> Date: Wed, 2 Feb 2000 15:41:56 +0000 Subject: [PATCH] * Initial BSD version. Still needs a lot of work. --- rtl/bsd/syscalls.inc | 387 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 387 insertions(+) create mode 100644 rtl/bsd/syscalls.inc diff --git a/rtl/bsd/syscalls.inc b/rtl/bsd/syscalls.inc new file mode 100644 index 0000000000..4756fc3309 --- /dev/null +++ b/rtl/bsd/syscalls.inc @@ -0,0 +1,387 @@ +{ + $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 tv,%ebx + pushl %ebx + lea tz,%ecx + pushl %ecx + mov $116,%eax + int $0x80 + add $8,%esp + mov %eax,retval + end; + + sys_time:=checkreturnvalue(retval,tv.tv_sec); +end; + +{***************************************************************************** + --- File:File handling related calls --- +*****************************************************************************} + + +Function Sys_Open(f:pchar;flags:longint;mode:integer):longint; + +var retval: LONGINT; + +Begin + asm + pushl mode + pushl flags + pushl f + movl $5,%eax + int $0x80 + add $12,%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 + regs : SysCallregs; +begin + regs.reg2:=longint(filename); + regs.reg3:=longint(@buffer); + Sys_Stat:=SysCall(SysCall_nr_stat,regs); +end; + + +Function Sys_Symlink(oldname,newname:pchar):longint; +{ + We need this for erase +} +var + regs : SysCallregs; +begin + regs.reg2:=longint(oldname); + regs.reg3:=longint(newname); + Sys_symlink:=SysCall(SysCall_nr_symlink,regs); +end; + + +{***************************************************************************** + --- Directory:Directory related calls --- +*****************************************************************************} + + +Function Sys_Chdir(Filename:pchar):longint; +var + regs : SysCallregs; + +begin + regs.reg2:=longint(filename); + Sys_ChDir:=SysCall(SysCall_nr_chdir,regs); +end; + + + +Function Sys_Mkdir(Filename:pchar;mode:longint):longint; +var + regs : SysCallregs; +begin + regs.reg2:=longint(filename); + regs.reg3:=mode; + Sys_MkDir:=SysCall(SysCall_nr_mkdir,regs); +end; + + + +Function Sys_Rmdir(Filename:pchar):longint; +var + regs : SysCallregs; +begin + regs.reg2:=longint(filename); + Sys_Rmdir:=SysCall(SysCall_nr_rmdir,regs); +end; + + + +{ we need this for getcwd } +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 + regs :SysCallregs; + dummy:longint; +begin + regs.reg3:=longint(p^.buf); + regs.reg2:=p^.fd; + regs.reg4:=1; + dummy:=SysCall(SysCall_nr_readdir,regs); +{ the readdir system call returns the number of bytes written } + if dummy=0 then + sys_readdir:=nil + else + sys_readdir:=p^.buf +end; + + +{***************************************************************************** + --- Process:Process & program handling - related calls --- +*****************************************************************************} + +Procedure Sys_Exit(ExitCode:Integer); +var + regs : SysCallregs; +begin + regs.reg2:=exitcode; + SysCall(SysCall_nr_exit,regs) +end; + +{ + $Log$ + Revision 1.1 2000-02-02 15:41:56 marco + * Initial BSD version. Still needs a lot of work. + + +} \ No newline at end of file