syscalls.inc 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Michael Van Canneyt,
  5. member of the Free Pascal development team.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {BSD version of the syscalls required to implement SysLinux.}
  13. {No debugging for syslinux include !}
  14. {$IFDEF SYS_LINUX}
  15. {$UNDEF SYSCALL_DEBUG}
  16. {$ENDIF SYS_LINUX}
  17. {*****************************************************************************
  18. --- Main:The System Call Self ---
  19. *****************************************************************************}
  20. { The system designed for Linux can't be used for FreeBSD so easily, since
  21. FreeBSD pushes arguments, instead of loading them to registers.
  22. For now I do them in assembler, which makes it easier to test them (copy and
  23. paste to and AS source). Ultimately I hope to design something like this}
  24. {actualsyscall:
  25. _actualsyscall : int $0x80
  26. jb someerror
  27. ret
  28. someerror: storeerrorsomewhere
  29. ret
  30. }
  31. {
  32. procedure actualsyscall; cdecl; EXTERNAL NAME '_actualsyscall';
  33. }
  34. procedure actualsyscall; assembler;
  35. asm
  36. int $0x80
  37. jb .LErrorcode
  38. xor %ebx,%ebx
  39. ret
  40. .LErrorcode:
  41. mov %eax,%ebx
  42. mov $-1,%eax
  43. end;
  44. function Do_SysCall(sysnr:LONGINT):longint; assembler;
  45. asm
  46. movl sysnr,%eax
  47. call actualsyscall
  48. movw %bx,Errno
  49. end;
  50. function Do_SysCall(sysnr,param1:longint):longint; assembler;
  51. asm
  52. movl sysnr,%eax
  53. pushl Param1
  54. call actualsyscall
  55. addl $4,%esp
  56. movw %bx,Errno
  57. end;
  58. function Do_SysCall(sysnr,param1:integer):longint; assembler;
  59. asm
  60. movl sysnr,%eax
  61. pushw Param1
  62. call actualsyscall
  63. addw $2,%esp
  64. movw %bx,Errno
  65. end;
  66. function Do_SysCall(sysnr,param1,param2:LONGINT):longint; assembler;
  67. asm
  68. movl sysnr,%eax
  69. pushl param2
  70. pushl Param1
  71. call actualsyscall
  72. addl $8,%esp
  73. movw %bx,Errno
  74. end;
  75. function Do_SysCall(sysnr,param1,param2,param3:LONGINT):longint; assembler;
  76. asm
  77. movl sysnr,%eax
  78. pushl param3
  79. pushl param2
  80. pushl Param1
  81. call actualsyscall
  82. addl $12,%esp
  83. movw %bx,Errno
  84. end;
  85. function Do_SysCall(sysnr,param1,param2,param3,param4:LONGINT):longint; assembler;
  86. asm
  87. movl sysnr,%eax
  88. pushl param4
  89. pushl param3
  90. pushl param2
  91. pushl Param1
  92. call actualsyscall
  93. addl $16,%esp
  94. movw %bx,Errno
  95. end;
  96. function Do_SysCall(sysnr,param1,param2,param3,param4,param5:LONGINT):longint; assembler;
  97. asm
  98. movl sysnr,%eax
  99. pushl param5
  100. pushl param4
  101. pushl param3
  102. pushl param2
  103. pushl Param1
  104. call actualsyscall
  105. addl $20,%esp
  106. movw %bx,Errno
  107. end;
  108. function Do_SysCall(sysnr,param1,param2,param3,param4,param5,param6,param7:LONGINT):longint; assembler;
  109. asm
  110. movl sysnr,%eax
  111. pushl param7
  112. pushl param6
  113. pushl param5
  114. pushl param4
  115. pushl param3
  116. pushl param2
  117. pushl Param1
  118. call actualsyscall
  119. addl $28,%esp
  120. movw %bx,Errno
  121. end;
  122. Function Sys_Time:longint;
  123. VAR tv : timeval;
  124. tz : timezone;
  125. retval : longint;
  126. begin
  127. Retval:=do_syscall(116,longint(@tv),longint(@tz));
  128. If retval=-1 then
  129. sys_time:=-1
  130. else
  131. sys_time:=tv.sec;
  132. end;
  133. {*****************************************************************************
  134. --- File:File handling related calls ---
  135. *****************************************************************************}
  136. Function Sys_Open(f:pchar;flags:longint;mode:integer):longint;
  137. Begin
  138. sys_open:=do_syscall(syscall_nr_open,longint(f),flags,mode);
  139. End;
  140. Function Sys_Close(f:longint):longint;
  141. begin
  142. sys_close:=do_syscall(syscall_nr_close,f);
  143. end;
  144. {
  145. Function Sys_Lseek(F:longint;Off:longint;Whence:longint):longint;
  146. var returnvalue64 : array[0..1] of longint;
  147. begin
  148. {Lseek's offset is 64-bit, the highword is the 0}
  149. do_syscall(syscall_nr_lseek,longint(@returnvalue64),F,Off,0,Whence);
  150. sys_lseek:=returnvalue64[0];
  151. end;
  152. }
  153. Function Sys_Lseek(F:longint;Off:longint;Whence:longint):longint; assembler;
  154. {this one is special for the return value being 64-bit..}
  155. asm
  156. pushl Whence
  157. pushl $0 // high dword
  158. pushl Off
  159. pushl $0
  160. pushl F
  161. pushl $0 // Your guess is as good as mine.
  162. pushl $0xc7 // Actual lseek syscall number.
  163. movl $0xc6,%eax
  164. call actualsyscall
  165. addl $28,%esp
  166. mov %ebx,Errno
  167. end;
  168. Function Sys_Read(f:longint;buffer:pchar;count:longint):longint;
  169. begin
  170. sys_read:=do_syscall(syscall_nr_read,F,longint(buffer),count);
  171. end;
  172. Function Sys_Write(f:longint;buffer:pchar;count:longint):longint;
  173. begin
  174. sys_write:=do_syscall(syscall_nr_write,F,longint(buffer),count);
  175. end;
  176. Function Sys_Unlink(Filename:pchar):longint;
  177. begin
  178. sys_unlink:=do_syscall(syscall_nr_unlink,longint(Filename));
  179. end;
  180. Function Sys_Rename(Oldname,Newname:pchar):longint;
  181. begin
  182. sys_rename:=do_syscall(syscall_nr_rename,longint(oldname),longint(newname));
  183. end;
  184. Function Sys_Stat(Filename:pchar;var Buffer: stat):longint;
  185. {
  186. We need this for getcwd
  187. }
  188. begin
  189. sys_stat:=do_syscall(syscall_nr_stat,longint(filename),longint(@buffer));
  190. end;
  191. Function Sys_Symlink(oldname,newname:pchar):longint;
  192. {
  193. We need this for erase
  194. }
  195. begin
  196. sys_symlink:=do_syscall(syscall_nr_symlink,longint(oldname),longint(newname));
  197. end;
  198. Function Sys_ReadLink(name,linkname:pchar;maxlen:longint):longint;
  199. begin
  200. sys_readlink:=do_syscall(syscall_nr_readlink, longint(name),longint(linkname),maxlen);
  201. end;
  202. {*****************************************************************************
  203. --- Directory:Directory related calls ---
  204. *****************************************************************************}
  205. Function Sys_Chdir(Filename:pchar):longint;
  206. begin
  207. sys_chdir:=do_syscall(syscall_nr_chdir,longint(filename));
  208. end;
  209. Function Sys_Mkdir(Filename:pchar;mode:longint):longint;
  210. begin {Mode is 16-bit on F-BSD}
  211. sys_mkdir:=do_syscall(syscall_nr_mkdir,longint(filename),mode shl 8);
  212. end;
  213. Function Sys_Rmdir(Filename:pchar):longint;
  214. begin
  215. sys_rmdir:=do_syscall(syscall_nr_rmdir,longint(filename));
  216. end;
  217. const DIRBLKSIZ=1024;
  218. { we need this for getcwd, NOT touched for BSD version }
  219. Function OpenDir(f:pchar):pdir;
  220. var
  221. fd:longint;
  222. st:stat;
  223. ptr:pdir;
  224. begin
  225. opendir:=nil;
  226. if sys_stat(f,st)<0 then
  227. exit;
  228. { Is it a dir ? }
  229. if not((st.mode and $f000)=$4000)then
  230. begin
  231. errno:=sys_enotdir;
  232. exit
  233. end;
  234. { Open it}
  235. fd:=sys_open(f,OPEN_RDONLY,438);
  236. if fd<0 then
  237. exit;
  238. new(ptr);
  239. if ptr=nil then
  240. exit;
  241. Getmem(ptr^.buf,2*DIRBLKSIZ);
  242. if ptr^.buf=nil then
  243. exit;
  244. ptr^.fd:=fd;
  245. ptr^.loc:=-1;
  246. ptr^.rewind:=longint(ptr^.buf);
  247. ptr^.size:=0;
  248. // ptr^.dd_max:=sizeof(ptr^.buf^);
  249. opendir:=ptr;
  250. end;
  251. function CloseDir(p:pdir):integer;
  252. begin
  253. closedir:=sys_close(p^.fd);
  254. Freemem(p^.buf);
  255. dispose(p);
  256. end;
  257. Function Sys_ReadDir(p:pdir):pdirent;
  258. {Different from Linux, Readdir on BSD is based on Getdents, due to the
  259. missing of the readdir syscall.
  260. Getdents requires the buffer to be larger than the blocksize.
  261. This usually the sectorsize =512 bytes, but maybe tapedrives and harddisks
  262. with blockmode have this higher?}
  263. function readbuffer:longint;
  264. var retval :longint;
  265. begin
  266. retval:=do_syscall(syscall_nr_getdents,longint(p^.fd),longint(@p^.buf^),DIRBLKSIZ {sizeof(getdentsbuffer)});
  267. p^.rewind:=longint(p^.buf);
  268. if retval=0 then
  269. begin
  270. p^.rewind:=0;
  271. p^.loc:=0;
  272. end
  273. else
  274. P^.loc:=retval;
  275. readbuffer:=retval;
  276. end;
  277. var
  278. l : pdirent;
  279. novalid : boolean;
  280. begin
  281. if (p^.buf=nil) or (p^.loc=0) THEN
  282. exit(nil);
  283. if p^.loc=-1 then {First readdir on this pdir. Initial fill of buffer}
  284. begin
  285. if readbuffer()=0 Then {nothing to be read}
  286. exit(nil)
  287. end;
  288. l:=nil;
  289. repeat
  290. novalid:=false;
  291. if (pdirent(p^.rewind)^.reclen<>0) then
  292. begin {valid direntry?}
  293. if pdirent(P^.rewind)^.ino<>0 then
  294. l:=pdirent(p^.rewind);
  295. inc(p^.rewind,pdirent(p^.rewind)^.reclen);
  296. if p^.rewind>=(longint(p^.buf)+dirblksiz) then
  297. novalid:=true;
  298. end
  299. else
  300. novalid:=true;
  301. if novalid then
  302. begin {block entirely searched or reclen=0}
  303. if p^.loc<>0 THEN {blocks left?}
  304. if readbuffer()<>0 then {succesful read?}
  305. novalid:=false;
  306. end;
  307. until (l<>nil) or novalid;
  308. Sys_ReadDir:=l;
  309. end;
  310. {*****************************************************************************
  311. --- Process:Process & program handling - related calls ---
  312. *****************************************************************************}
  313. Function sys_GetPid:LongInt;
  314. {
  315. Get Process ID.
  316. }
  317. begin
  318. sys_GetPID:=do_syscall(syscall_nr_getpid);
  319. end;
  320. Procedure Sys_Exit(ExitCode:longint);
  321. begin
  322. do_syscall(syscall_nr_exit,exitcode);
  323. end;
  324. {
  325. $Log$
  326. Revision 1.2 2000-07-13 11:33:37 michael
  327. + removed logs
  328. }