syscalls.inc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  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; {inline requires a dummy push IIRC}
  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. add $2,%esp
  64. movw %bx,Errno
  65. end;
  66. }
  67. function Do_SysCall(sysnr,param1,param2:LONGINT):longint; assembler;
  68. asm
  69. movl sysnr,%eax
  70. pushl param2
  71. pushl Param1
  72. call actualsyscall
  73. addl $8,%esp
  74. movw %bx,Errno
  75. end;
  76. function Do_SysCall(sysnr,param1,param2,param3:LONGINT):longint; assembler;
  77. asm
  78. movl sysnr,%eax
  79. pushl param3
  80. pushl param2
  81. pushl Param1
  82. call actualsyscall
  83. addl $12,%esp
  84. movw %bx,Errno
  85. end;
  86. function Do_SysCall(sysnr,param1,param2,param3,param4:LONGINT):longint; assembler;
  87. asm
  88. movl sysnr,%eax
  89. pushl param4
  90. pushl param3
  91. pushl param2
  92. pushl Param1
  93. call actualsyscall
  94. addl $16,%esp
  95. movw %bx,Errno
  96. end;
  97. function Do_SysCall(sysnr,param1,param2,param3,param4,param5:LONGINT):longint; assembler;
  98. asm
  99. movl sysnr,%eax
  100. pushl param5
  101. pushl param4
  102. pushl param3
  103. pushl param2
  104. pushl Param1
  105. call actualsyscall
  106. addl $20,%esp
  107. movw %bx,Errno
  108. end;
  109. function Do_SysCall(sysnr,param1,param2,param3,param4,param5,param6:LONGINT):int64; assembler;
  110. asm
  111. movl sysnr,%eax
  112. pushl param6
  113. pushl param5
  114. pushl param4
  115. pushl param3
  116. pushl param2
  117. pushl Param1
  118. call actualsyscall
  119. addl $24,%esp
  120. movw %bx,Errno
  121. end;
  122. function Do_SysCall(sysnr,param1,param2,param3,param4,param5,param6,param7:LONGINT):int64; assembler;
  123. asm
  124. movl sysnr,%eax
  125. pushl param7
  126. pushl param6
  127. pushl param5
  128. pushl param4
  129. pushl param3
  130. pushl param2
  131. pushl Param1
  132. call actualsyscall
  133. addl $28,%esp
  134. movw %bx,Errno
  135. end;
  136. Function Sys_Time:longint;
  137. VAR tv : timeval;
  138. tz : timezone;
  139. retval : longint;
  140. begin
  141. Retval:=do_syscall(116,longint(@tv),longint(@tz));
  142. If retval=-1 then
  143. sys_time:=-1
  144. else
  145. sys_time:=tv.sec;
  146. end;
  147. {*****************************************************************************
  148. --- File:File handling related calls ---
  149. *****************************************************************************}
  150. Function Sys_Open(f:pchar;flags:longint;mode:integer):longint;
  151. Begin
  152. sys_open:=do_syscall(syscall_nr_open,longint(f),flags,mode);
  153. End;
  154. Function Sys_Close(f:longint):longint;
  155. begin
  156. sys_close:=do_syscall(syscall_nr_close,f);
  157. end;
  158. {
  159. Function Sys_Lseek(F:longint;Off:longint;Whence:longint):longint;
  160. var returnvalue64 : array[0..1] of longint;
  161. begin
  162. {Lseek's offset is 64-bit, the highword is the 0}
  163. do_syscall(syscall_nr_lseek,longint(@returnvalue64),F,Off,0,Whence);
  164. sys_lseek:=returnvalue64[0];
  165. end;
  166. }
  167. Function Sys_Lseek(F:longint;Off:longint;Whence:longint):longint; assembler;
  168. {this one is special for the return value being 64-bit..}
  169. asm
  170. pushl Whence
  171. pushl $0 // high dword
  172. pushl Off
  173. pushl $0
  174. pushl F
  175. pushl $0 // Your guess is as good as mine.
  176. pushl $0xc7 // Actual lseek syscall number.
  177. movl $0xc6,%eax
  178. call actualsyscall
  179. addl $28,%esp
  180. mov %ebx,Errno
  181. end;
  182. Function Sys_Read(f:longint;buffer:pchar;count:longint):longint;
  183. begin
  184. sys_read:=do_syscall(syscall_nr_read,F,longint(buffer),count);
  185. end;
  186. Function Sys_Write(f:longint;buffer:pchar;count:longint):longint;
  187. begin
  188. sys_write:=do_syscall(syscall_nr_write,F,longint(buffer),count);
  189. end;
  190. Function Sys_Unlink(Filename:pchar):longint;
  191. begin
  192. sys_unlink:=do_syscall(syscall_nr_unlink,longint(Filename));
  193. end;
  194. Function Sys_Rename(Oldname,Newname:pchar):longint;
  195. begin
  196. sys_rename:=do_syscall(syscall_nr_rename,longint(oldname),longint(newname));
  197. end;
  198. Function Sys_Stat(Filename:pchar;var Buffer: stat):longint;
  199. {
  200. We need this for getcwd
  201. }
  202. begin
  203. sys_stat:=do_syscall(syscall_nr_stat,longint(filename),longint(@buffer));
  204. end;
  205. Function Sys_Symlink(oldname,newname:pchar):longint;
  206. {
  207. We need this for erase
  208. }
  209. begin
  210. sys_symlink:=do_syscall(syscall_nr_symlink,longint(oldname),longint(newname));
  211. end;
  212. Function Sys_ReadLink(name,linkname:pchar;maxlen:longint):longint;
  213. begin
  214. sys_readlink:=do_syscall(syscall_nr_readlink, longint(name),longint(linkname),maxlen);
  215. end;
  216. {*****************************************************************************
  217. --- Directory:Directory related calls ---
  218. *****************************************************************************}
  219. Function Sys_Chdir(Filename:pchar):longint;
  220. begin
  221. sys_chdir:=do_syscall(syscall_nr_chdir,longint(filename));
  222. end;
  223. Function Sys_Mkdir(Filename:pchar;mode:longint):longint;
  224. begin {Mode is 16-bit on F-BSD}
  225. sys_mkdir:=do_syscall(syscall_nr_mkdir,longint(filename),mode);
  226. end;
  227. Function Sys_Rmdir(Filename:pchar):longint;
  228. begin
  229. sys_rmdir:=do_syscall(syscall_nr_rmdir,longint(filename));
  230. end;
  231. {$ifndef NewReaddir}
  232. const DIRBLKSIZ=1024;
  233. { we need this for getcwd, NOT touched for BSD version }
  234. Function OpenDir(f:pchar):pdir;
  235. var
  236. fd:longint;
  237. st:stat;
  238. ptr:pdir;
  239. begin
  240. opendir:=nil;
  241. if sys_stat(f,st)<0 then
  242. exit;
  243. { Is it a dir ? }
  244. if not((st.mode and $f000)=$4000)then
  245. begin
  246. errno:=Esysenotdir;
  247. exit
  248. end;
  249. { Open it}
  250. fd:=sys_open(f,OPEN_RDONLY,438);
  251. if fd<0 then
  252. exit;
  253. new(ptr);
  254. if ptr=nil then
  255. exit;
  256. Getmem(ptr^.buf,2*DIRBLKSIZ);
  257. if ptr^.buf=nil then
  258. exit;
  259. ptr^.fd:=fd;
  260. ptr^.loc:=-1;
  261. ptr^.rewind:=longint(ptr^.buf);
  262. ptr^.size:=0;
  263. // ptr^.dd_max:=sizeof(ptr^.buf^);
  264. opendir:=ptr;
  265. end;
  266. function CloseDir(p:pdir):integer;
  267. begin
  268. closedir:=sys_close(p^.fd);
  269. Freemem(p^.buf);
  270. dispose(p);
  271. end;
  272. Function Sys_ReadDir(p:pdir):pdirent;
  273. {Different from Linux, Readdir on BSD is based on Getdents, due to the
  274. missing of the readdir syscall.
  275. Getdents requires the buffer to be larger than the blocksize.
  276. This usually the sectorsize =512 bytes, but maybe tapedrives and harddisks
  277. with blockmode have this higher?}
  278. function readbuffer:longint;
  279. var retval :longint;
  280. begin
  281. retval:=do_syscall(syscall_nr_getdents,longint(p^.fd),longint(@p^.buf^),DIRBLKSIZ {sizeof(getdentsbuffer)});
  282. p^.rewind:=longint(p^.buf);
  283. if retval=0 then
  284. begin
  285. p^.rewind:=0;
  286. p^.loc:=0;
  287. end
  288. else
  289. P^.loc:=retval;
  290. readbuffer:=retval;
  291. end;
  292. var
  293. FinalEntry : pdirent;
  294. novalid : boolean;
  295. Reclen : Longint;
  296. CurEntry : PDirent;
  297. begin
  298. if (p^.buf=nil) or (p^.loc=0) THEN
  299. exit(nil);
  300. if (p^.loc=-1) OR {First readdir on this pdir. Initial fill of buffer}
  301. (p^.rewind>=(longint(p^.buf)+dirblksiz)) then {no more entries left?}
  302. Begin
  303. if readbuffer=0 then {succesful read?}
  304. Exit(NIL); {No more data}
  305. End;
  306. FinalEntry:=NIL;
  307. CurEntry:=nil;
  308. repeat
  309. novalid:=false;
  310. CurEntry:=pdirent(p^.rewind);
  311. RecLen:=CurEntry^.reclen;
  312. if RecLen<>0 Then
  313. begin {valid direntry?}
  314. if CurEntry^.ino<>0 then
  315. FinalEntry:=CurEntry;
  316. inc(p^.rewind,Reclen);
  317. end
  318. else
  319. begin {block entirely searched or reclen=0}
  320. Novalid:=True;
  321. if p^.loc<>0 THEN {blocks left?}
  322. if readbuffer()<>0 then {succesful read?}
  323. novalid:=false;
  324. end;
  325. until (FinalEntry<>nil) or novalid;
  326. If novalid then
  327. FinalEntry:=nil;
  328. Sys_ReadDir:=FinalEntry;
  329. end;
  330. {$endif}
  331. {*****************************************************************************
  332. --- Process:Process & program handling - related calls ---
  333. *****************************************************************************}
  334. Function sys_GetPid:LongInt;
  335. {
  336. Get Process ID.
  337. }
  338. begin
  339. sys_GetPID:=do_syscall(syscall_nr_getpid);
  340. end;
  341. Procedure Sys_Exit(ExitCode:longint);
  342. begin
  343. do_syscall(syscall_nr_exit,exitcode);
  344. end;
  345. {
  346. Change action of process upon receipt of a signal.
  347. Signum specifies the signal (all except SigKill and SigStop).
  348. If Act is non-nil, it is used to specify the new action.
  349. If OldAct is non-nil the previous action is saved there.
  350. }
  351. Procedure SigAction(Signum:longint;Act,OldAct:PSigActionRec );
  352. {
  353. Change action of process upon receipt of a signal.
  354. Signum specifies the signal (all except SigKill and SigStop).
  355. If Act is non-nil, it is used to specify the new action.
  356. If OldAct is non-nil the previous action is saved there.
  357. }
  358. begin
  359. do_syscall(syscall_nr_sigaction,longint(signum),longint(act),longint(oldact));
  360. {$ifdef linuxunit}
  361. LinuxError:=Errno;
  362. {$endif}
  363. end;
  364. (*=================== MOVED from syslinux.inc ========================*)
  365. {
  366. Function Sys_FTruncate(Handle,Pos:longint):longint; //moved from sysunix.inc Do_Truncate
  367. begin
  368. Sys_FTruncate:=do_syscall(syscall_nr_ftruncate,handle,pos,0);
  369. end;
  370. }
  371. Function Sys_ftruncate(handle,pos:longint):longint; assembler;
  372. {this one is special for the return value being 64-bit..}
  373. asm
  374. pushl $0
  375. pushl pos
  376. pushl $0 // Your guess is as good as mine.
  377. pushl handle
  378. pushl $0
  379. pushl $0xc9 // Actual lseek syscall number.
  380. movl $0xc6,%eax
  381. call actualsyscall
  382. addl $24,%esp
  383. mov %ebx,Errno
  384. end;
  385. Function Sys_fstat(fd : longint;var Info:stat):Longint; // This was missing here, instead an fstat call was included in Do_FileSize
  386. begin
  387. Sys_FStat:=do_SysCall(syscall_nr_fstat,fd,longint(@info));
  388. end;
  389. {$ifdef NewReaddir}
  390. {$I readdir.inc}
  391. {$endif}
  392. {
  393. Interface to Unix ioctl call.
  394. Performs various operations on the filedescriptor Handle.
  395. Ndx describes the operation to perform.
  396. Data points to data needed for the Ndx function. The structure of this
  397. data is function-dependent.
  398. }
  399. Function Sys_IOCtl(Handle,Ndx: Longint;Data: Pointer):LongInt; // This was missing here, instead hardcoded in Do_IsDevice
  400. begin
  401. Sys_IOCtl:=do_SysCall(syscall_nr_ioctl,handle,Ndx,longint(data));
  402. end;
  403. Function Sys_mmap(adr,len,prot,flags,fdes,off:longint):longint; // moved from sysunix.inc, used in sbrk
  404. begin
  405. Sys_mmap:=do_syscall(syscall_nr_mmap,Adr,Len,Prot,Flags,fdes,off,0);
  406. end;
  407. {
  408. $Log$
  409. Revision 1.11 2003-06-01 16:35:28 marco
  410. * Several small fixes to harmonize the *BSD rtls and Linux.
  411. Revision 1.10 2003/01/05 19:02:29 marco
  412. * Should now work with baseunx. (gmake all works)
  413. Revision 1.9 2002/09/07 16:01:17 peter
  414. * old logs removed and tabs fixed
  415. Revision 1.8 2002/05/06 07:27:39 marco
  416. * Fixed a readdir bug, already fixed in januari in 1.0.x
  417. }