syscalls.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  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. add $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:LONGINT):longint; assembler;
  109. asm
  110. movl sysnr,%eax
  111. pushl param6
  112. pushl param5
  113. pushl param4
  114. pushl param3
  115. pushl param2
  116. pushl Param1
  117. call actualsyscall
  118. addl $24,%esp
  119. movw %bx,Errno
  120. end;
  121. function Do_SysCall(sysnr,param1,param2,param3,param4,param5,param6,param7:LONGINT):longint; assembler;
  122. asm
  123. movl sysnr,%eax
  124. pushl param7
  125. pushl param6
  126. pushl param5
  127. pushl param4
  128. pushl param3
  129. pushl param2
  130. pushl Param1
  131. call actualsyscall
  132. addl $28,%esp
  133. movw %bx,Errno
  134. end;
  135. Function Sys_Time:longint;
  136. VAR tv : timeval;
  137. tz : timezone;
  138. retval : longint;
  139. begin
  140. Retval:=do_syscall(116,longint(@tv),longint(@tz));
  141. If retval=-1 then
  142. sys_time:=-1
  143. else
  144. sys_time:=tv.sec;
  145. end;
  146. {*****************************************************************************
  147. --- File:File handling related calls ---
  148. *****************************************************************************}
  149. Function Sys_Open(f:pchar;flags:longint;mode:integer):longint;
  150. Begin
  151. sys_open:=do_syscall(syscall_nr_open,longint(f),flags,mode);
  152. End;
  153. Function Sys_Close(f:longint):longint;
  154. begin
  155. sys_close:=do_syscall(syscall_nr_close,f);
  156. end;
  157. {
  158. Function Sys_Lseek(F:longint;Off:longint;Whence:longint):longint;
  159. var returnvalue64 : array[0..1] of longint;
  160. begin
  161. {Lseek's offset is 64-bit, the highword is the 0}
  162. do_syscall(syscall_nr_lseek,longint(@returnvalue64),F,Off,0,Whence);
  163. sys_lseek:=returnvalue64[0];
  164. end;
  165. }
  166. Function Sys_Lseek(F:longint;Off:longint;Whence:longint):longint; assembler;
  167. {this one is special for the return value being 64-bit..}
  168. asm
  169. pushl Whence
  170. pushl $0 // high dword
  171. pushl Off
  172. pushl $0
  173. pushl F
  174. pushl $0 // Your guess is as good as mine.
  175. pushl $0xc7 // Actual lseek syscall number.
  176. movl $0xc6,%eax
  177. call actualsyscall
  178. addl $28,%esp
  179. mov %ebx,Errno
  180. end;
  181. Function Sys_Read(f:longint;buffer:pchar;count:longint):longint;
  182. begin
  183. sys_read:=do_syscall(syscall_nr_read,F,longint(buffer),count);
  184. end;
  185. Function Sys_Write(f:longint;buffer:pchar;count:longint):longint;
  186. begin
  187. sys_write:=do_syscall(syscall_nr_write,F,longint(buffer),count);
  188. end;
  189. Function Sys_Unlink(Filename:pchar):longint;
  190. begin
  191. sys_unlink:=do_syscall(syscall_nr_unlink,longint(Filename));
  192. end;
  193. Function Sys_Rename(Oldname,Newname:pchar):longint;
  194. begin
  195. sys_rename:=do_syscall(syscall_nr_rename,longint(oldname),longint(newname));
  196. end;
  197. Function Sys_Stat(Filename:pchar;var Buffer: stat):longint;
  198. {
  199. We need this for getcwd
  200. }
  201. begin
  202. sys_stat:=do_syscall(syscall_nr_stat,longint(filename),longint(@buffer));
  203. end;
  204. Function Sys_Symlink(oldname,newname:pchar):longint;
  205. {
  206. We need this for erase
  207. }
  208. begin
  209. sys_symlink:=do_syscall(syscall_nr_symlink,longint(oldname),longint(newname));
  210. end;
  211. Function Sys_ReadLink(name,linkname:pchar;maxlen:longint):longint;
  212. begin
  213. sys_readlink:=do_syscall(syscall_nr_readlink, longint(name),longint(linkname),maxlen);
  214. end;
  215. {*****************************************************************************
  216. --- Directory:Directory related calls ---
  217. *****************************************************************************}
  218. Function Sys_Chdir(Filename:pchar):longint;
  219. begin
  220. sys_chdir:=do_syscall(syscall_nr_chdir,longint(filename));
  221. end;
  222. Function Sys_Mkdir(Filename:pchar;mode:longint):longint;
  223. begin {Mode is 16-bit on F-BSD}
  224. sys_mkdir:=do_syscall(syscall_nr_mkdir,longint(filename),mode);
  225. end;
  226. Function Sys_Rmdir(Filename:pchar):longint;
  227. begin
  228. sys_rmdir:=do_syscall(syscall_nr_rmdir,longint(filename));
  229. end;
  230. const DIRBLKSIZ=1024;
  231. { we need this for getcwd, NOT touched for BSD version }
  232. Function OpenDir(f:pchar):pdir;
  233. var
  234. fd:longint;
  235. st:stat;
  236. ptr:pdir;
  237. begin
  238. opendir:=nil;
  239. if sys_stat(f,st)<0 then
  240. exit;
  241. { Is it a dir ? }
  242. if not((st.mode and $f000)=$4000)then
  243. begin
  244. errno:=sys_enotdir;
  245. exit
  246. end;
  247. { Open it}
  248. fd:=sys_open(f,OPEN_RDONLY,438);
  249. if fd<0 then
  250. exit;
  251. new(ptr);
  252. if ptr=nil then
  253. exit;
  254. Getmem(ptr^.buf,2*DIRBLKSIZ);
  255. if ptr^.buf=nil then
  256. exit;
  257. ptr^.fd:=fd;
  258. ptr^.loc:=-1;
  259. ptr^.rewind:=longint(ptr^.buf);
  260. ptr^.size:=0;
  261. // ptr^.dd_max:=sizeof(ptr^.buf^);
  262. opendir:=ptr;
  263. end;
  264. function CloseDir(p:pdir):integer;
  265. begin
  266. closedir:=sys_close(p^.fd);
  267. Freemem(p^.buf);
  268. dispose(p);
  269. end;
  270. Function Sys_ReadDir(p:pdir):pdirent;
  271. {Different from Linux, Readdir on BSD is based on Getdents, due to the
  272. missing of the readdir syscall.
  273. Getdents requires the buffer to be larger than the blocksize.
  274. This usually the sectorsize =512 bytes, but maybe tapedrives and harddisks
  275. with blockmode have this higher?}
  276. function readbuffer:longint;
  277. var retval :longint;
  278. begin
  279. retval:=do_syscall(syscall_nr_getdents,longint(p^.fd),longint(@p^.buf^),DIRBLKSIZ {sizeof(getdentsbuffer)});
  280. p^.rewind:=longint(p^.buf);
  281. if retval=0 then
  282. begin
  283. p^.rewind:=0;
  284. p^.loc:=0;
  285. end
  286. else
  287. P^.loc:=retval;
  288. readbuffer:=retval;
  289. end;
  290. var
  291. l : pdirent;
  292. novalid : boolean;
  293. begin
  294. if (p^.buf=nil) or (p^.loc=0) THEN
  295. exit(nil);
  296. if p^.loc=-1 then {First readdir on this pdir. Initial fill of buffer}
  297. begin
  298. if readbuffer()=0 Then {nothing to be read}
  299. exit(nil)
  300. end;
  301. l:=nil;
  302. repeat
  303. novalid:=false;
  304. if (pdirent(p^.rewind)^.reclen<>0) then
  305. begin {valid direntry?}
  306. if pdirent(P^.rewind)^.ino<>0 then
  307. l:=pdirent(p^.rewind);
  308. inc(p^.rewind,pdirent(p^.rewind)^.reclen);
  309. if p^.rewind>=(longint(p^.buf)+dirblksiz) then
  310. novalid:=true;
  311. end
  312. else
  313. novalid:=true;
  314. if novalid then
  315. begin {block entirely searched or reclen=0}
  316. if p^.loc<>0 THEN {blocks left?}
  317. if readbuffer()<>0 then {succesful read?}
  318. novalid:=false;
  319. end;
  320. until (l<>nil) or novalid;
  321. If novalid then
  322. l:=nil;
  323. Sys_ReadDir:=l;
  324. end;
  325. {*****************************************************************************
  326. --- Process:Process & program handling - related calls ---
  327. *****************************************************************************}
  328. Function sys_GetPid:LongInt;
  329. {
  330. Get Process ID.
  331. }
  332. begin
  333. sys_GetPID:=do_syscall(syscall_nr_getpid);
  334. end;
  335. Procedure Sys_Exit(ExitCode:longint);
  336. begin
  337. do_syscall(syscall_nr_exit,exitcode);
  338. end;
  339. {
  340. Change action of process upon receipt of a signal.
  341. Signum specifies the signal (all except SigKill and SigStop).
  342. If Act is non-nil, it is used to specify the new action.
  343. If OldAct is non-nil the previous action is saved there.
  344. }
  345. Procedure SigAction(Signum:longint;Act,OldAct:PSigActionRec );
  346. {
  347. Change action of process upon receipt of a signal.
  348. Signum specifies the signal (all except SigKill and SigStop).
  349. If Act is non-nil, it is used to specify the new action.
  350. If OldAct is non-nil the previous action is saved there.
  351. }
  352. begin
  353. do_syscall(syscall_nr_sigaction,longint(signum),longint(act),longint(oldact));
  354. {$ifdef linuxunit}
  355. LinuxError:=Errno;
  356. {$endif}
  357. end;
  358. (*=================== MOVED from syslinux.inc ========================*)
  359. {
  360. Function Sys_FTruncate(Handle,Pos:longint):longint; //moved from sysunix.inc Do_Truncate
  361. begin
  362. Sys_FTruncate:=do_syscall(syscall_nr_ftruncate,handle,pos,0);
  363. end;
  364. }
  365. Function Sys_ftruncate(handle,pos:longint):longint; assembler;
  366. {this one is special for the return value being 64-bit..}
  367. asm
  368. pushl $0
  369. pushl pos
  370. pushl $0 // Your guess is as good as mine.
  371. pushl handle
  372. pushl $0
  373. pushl $0xc9 // Actual lseek syscall number.
  374. movl $0xc6,%eax
  375. call actualsyscall
  376. addl $24,%esp
  377. mov %ebx,Errno
  378. end;
  379. Function Sys_fstat(fd : longint;var Info:stat):Longint; // This was missing here, instead an fstat call was included in Do_FileSize
  380. begin
  381. Sys_FStat:=do_SysCall(syscall_nr_fstat,fd,longint(@info));
  382. end;
  383. {$ifdef NewReaddir}
  384. {$I readdir.inc}
  385. {$endif}
  386. {
  387. Interface to Unix ioctl call.
  388. Performs various operations on the filedescriptor Handle.
  389. Ndx describes the operation to perform.
  390. Data points to data needed for the Ndx function. The structure of this
  391. data is function-dependent.
  392. }
  393. Function Sys_IOCtl(Handle,Ndx: Longint;Data: Pointer):LongInt; // This was missing here, instead hardcoded in Do_IsDevice
  394. begin
  395. Sys_IOCtl:=do_SysCall(syscall_nr_ioctl,handle,Ndx,longint(data));
  396. end;
  397. Function Sys_mmap(adr,len,prot,flags,fdes,off:longint):longint; // moved from sysunix.inc, used in sbrk
  398. begin
  399. Sys_mmap:=do_syscall(syscall_nr_mmap,Adr,Len,Prot,Flags,fdes,off,0);
  400. end;
  401. {
  402. $Log$
  403. Revision 1.7 2001-08-27 09:35:07 marco
  404. * Ftruncate intermediate fix.
  405. Revision 1.6 2001/06/19 08:34:16 marco
  406. * Peter didn't merge the FreeBSD directory when he merged the Unix one. Fixed
  407. Revision 1.5 2001/04/23 11:38:30 marco
  408. * Small readdir fix from fixes branch.
  409. Revision 1.4 2000/09/19 09:57:35 marco
  410. * Fixed mkdir
  411. Revision 1.3 2000/09/19 09:25:17 marco
  412. * addw fix for main thread.
  413. Revision 1.2 2000/09/18 13:42:35 marco
  414. * FreeBSD support into 1.1
  415. Revision 1.4 2000/09/11 14:38:10 marco
  416. * 14 april version killed, and replaced by newer fixes branch version
  417. Revision 1.1.2.1 2000/09/10 16:12:14 marco
  418. Initial signals, sockets and clone
  419. Revision 1.1 2000/07/13 06:30:32 michael
  420. + Initial import
  421. Revision 1.15 2000/04/16 16:08:53 marco
  422. * Fixes (mainly opendir/Readdir/closedir)
  423. Revision 1.14 2000/04/14 17:04:13 marco
  424. * Working!
  425. Revision 1.13 2000/04/10 15:46:52 marco
  426. * worked all day. probably a lot changed
  427. Revision 1.11 2000/04/05 13:58:40 marco
  428. * syscall variablenames reintroduced.
  429. Revision 1.10 2000/03/16 16:18:12 marco
  430. * Last changes before next test. ppc386 -h works with these srcs.
  431. Revision 1.9 2000/03/02 15:34:07 marco
  432. * added a syscall for 5 longints
  433. Revision 1.8 2000/03/01 20:03:57 marco
  434. * small fixes for syslinux
  435. Revision 1.7 2000/03/01 17:28:40 marco
  436. * some changes due to updating linux.pp to new syscall
  437. Revision 1.6 2000/02/27 23:45:39 marco
  438. * Redone the syscalls
  439. Revision 1.5 2000/02/04 16:53:26 marco
  440. * Finished Linux (and rest syscalls) roughly. Some things still need to be
  441. tested, and checked (off_t calls specially)
  442. Revision 1.4 2000/02/03 17:04:47 marco
  443. * additions fixes due to port linux
  444. Revision 1.3 2000/02/02 18:07:27 marco
  445. * Ported except for readdir which is 200 lines C code in FBSD linux
  446. emulator
  447. Revision 1.2 2000/02/02 16:35:10 marco
  448. * Ported more functions. Half done now.
  449. Revision 1.1 2000/02/02 15:41:56 marco
  450. * Initial BSD version. Still needs a lot of work.
  451. }