syscalls.inc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  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. {Darwin 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. Procedure Do_SysCall( callnr:longint;var regs : SysCallregs );assembler;
  21. {
  22. This function puts the registers in place, does the call, and then
  23. copies back the registers as they are after the SysCall.
  24. }
  25. {$ifdef cpupowerpc}
  26. {$define fpc_syscall_ok}
  27. asm
  28. { load the registers... }
  29. lwz r5, 12(r4)
  30. lwz r6, 16(r4)
  31. lwz r7, 20(r4)
  32. lwz r8, 24(r4)
  33. lwz r9, 28(r4)
  34. mr r0, r3
  35. lwz r3, 4(r4)
  36. stw r4, regs
  37. lwz r4, 8(r4)
  38. { Go ! }
  39. sc
  40. { Put back the registers... }
  41. lwz r8, regs
  42. stw r3, 4(r8)
  43. stw r4, 8(r8)
  44. stw r5, 12(r8)
  45. stw r6, 16(r8)
  46. stw r7, 20(r8)
  47. end;
  48. {$endif cpupowerpc}
  49. {$ifndef fpc_syscall_ok}
  50. {$error Cannot decide which processor you have!}
  51. asm
  52. end;
  53. {$endif not fpc_syscall_ok}
  54. {$IFDEF SYSCALL_DEBUG}
  55. Const
  56. DoSysCallDebug : Boolean = False;
  57. var
  58. LastCnt,
  59. LastR0,
  60. LastCall : longint;
  61. DebugTxt : string[20];
  62. {$ENDIF}
  63. Function SysCall( callnr:longint;var regs : SysCallregs ):longint;
  64. {
  65. This function serves as an interface to do_SysCall.
  66. If the SysCall returned a negative number, it returns -1, and puts the
  67. SysCall result in errno. Otherwise, it returns the SysCall return value
  68. }
  69. begin
  70. do_SysCall(callnr,regs);
  71. if regs.reg1<0 then
  72. begin
  73. {$IFDEF SYSCALL_DEBUG}
  74. If DoSysCallDebug then
  75. debugtxt:=' syscall error: ';
  76. {$endif}
  77. ErrNo:=-regs.reg1;
  78. SysCall:=-1;
  79. end
  80. else
  81. begin
  82. {$IFDEF SYSCALL_DEBUG}
  83. if DoSysCallDebug then
  84. debugtxt:=' syscall returned: ';
  85. {$endif}
  86. SysCall:=regs.reg1;
  87. errno:=0
  88. end;
  89. {$IFDEF SYSCALL_DEBUG}
  90. if DoSysCallDebug then
  91. begin
  92. inc(lastcnt);
  93. if (callnr<>lastcall) or (regs.reg1<>lastR0) then
  94. begin
  95. if lastcnt>1 then
  96. writeln(sys_nr_txt[lastcall],debugtxt,lasteax,' (',lastcnt,'x)');
  97. lastcall:=callnr;
  98. lasteax:=regs.reg1;
  99. lastcnt:=0;
  100. writeln(sys_nr_txt[lastcall],debugtxt,lasteax);
  101. end;
  102. end;
  103. {$endif}
  104. end;
  105. Function Sys_Time:longint;
  106. VAR tv : timeval;
  107. tz : timezone;
  108. retval : longint;
  109. begin
  110. Retval:=do_syscall(116,longint(@tv),longint(@tz));
  111. If retval=-1 then
  112. sys_time:=-1
  113. else
  114. sys_time:=tv.sec;
  115. end;
  116. Function Sys_Time:longint;
  117. var
  118. tv : timeval;
  119. tz : timezone;
  120. regs : SysCallregs;
  121. retval: longint;
  122. begin
  123. regs.reg2:=@tv;
  124. regs.reg3:=@tz;
  125. retval:=SysCall(SYS_gettimeofday,regs);
  126. if retval = -1 then
  127. Sys_Time := -1
  128. else
  129. Sys_Time := tv.sec;
  130. end;
  131. {*****************************************************************************
  132. --- File:File handling related calls ---
  133. *****************************************************************************}
  134. Function Sys_Open(f:pchar;flags:longint;mode:integer):longint;
  135. var
  136. regs : SysCallregs;
  137. Begin
  138. regs.reg2:=longint(f);
  139. regs.reg3:=flags;
  140. regs.reg4:=mode;
  141. Sys_Open:=SysCall(SysCall_nr_open,regs);
  142. End;
  143. Function Sys_Close(f:longint):longint;
  144. var
  145. regs : SysCallregs;
  146. begin
  147. regs.reg2:=f;
  148. Sys_Close:=SysCall(SysCall_nr_close,regs);
  149. end;
  150. Function Sys_Lseek(F:longint;Off:longint;Whence:longint):longint;
  151. var
  152. regs : SysCallregs;
  153. begin
  154. {Lseek's offset is 64-bit, the highword is the 0}
  155. regs.reg2:=f;
  156. { strange, even on the PPC, the order of the low/high dword in the }
  157. { registers is in "little endian" here (JM) }
  158. regs.reg3:=off;
  159. regs.reg4:=0;
  160. regs.reg5:=whence
  161. Sys_Lseek:=do_syscall(syscall_nr_lseek,regs);
  162. end;
  163. Function Sys_Read(f:longint;buffer:pchar;count:longint):longint;
  164. var
  165. regs : SysCallregs;
  166. begin
  167. regs.reg2:=f;
  168. regs.reg3:=longint(buffer);
  169. regs.reg4:=count;
  170. Sys_Read:=SysCall(SysCall_nr_read,regs);
  171. end;
  172. Function Sys_Write(f:longint;buffer:pchar;count:longint):longint;
  173. var
  174. regs : SysCallregs;
  175. begin
  176. regs.reg2:=f;
  177. regs.reg3:=longint(buffer);
  178. regs.reg4:=count;
  179. Sys_Write:=SysCall(SysCall_nr_write,regs);
  180. end;
  181. Function Sys_Unlink(Filename:pchar):longint;
  182. var
  183. regs : SysCallregs;
  184. begin
  185. regs.reg2:=longint(filename);
  186. Sys_Unlink:=SysCall(SysCall_nr_unlink,regs);
  187. end;
  188. Function Sys_fstat(fd : longint;var Info:stat):Longint;
  189. var
  190. regs : SysCallregs;
  191. begin
  192. regs.reg2:=fd;
  193. regs.reg3:=longint(@Info);
  194. Sys_fStat:=SysCall(SysCall_nr_fstat,regs);
  195. end;
  196. Function Sys_Rename(Oldname,Newname:pchar):longint;
  197. var
  198. regs : SysCallregs;
  199. begin
  200. regs.reg2:=longint(oldname);
  201. regs.reg3:=longint(newname);
  202. Sys_Rename:=SysCall(SysCall_nr_rename,regs);
  203. end;
  204. Function Sys_Stat(Filename:pchar;var Buffer: stat):longint;
  205. {
  206. We need this for getcwd
  207. }
  208. var
  209. regs : SysCallregs;
  210. begin
  211. regs.reg2:=longint(filename);
  212. regs.reg3:=longint(@buffer);
  213. Sys_Stat:=SysCall(SysCall_nr_stat,regs);
  214. end;
  215. Function Sys_Symlink(oldname,newname:pchar):longint;
  216. {
  217. We need this for erase
  218. }
  219. var
  220. regs : SysCallregs;
  221. begin
  222. regs.reg2:=longint(oldname);
  223. regs.reg3:=longint(newname);
  224. Sys_symlink:=SysCall(SysCall_nr_symlink,regs);
  225. end;
  226. Function Sys_ReadLink(name,linkname:pchar;maxlen:longint):longint;
  227. var
  228. regs : SysCallRegs;
  229. begin
  230. regs.reg2:=longint(name);
  231. regs.reg3:=longint(linkname);
  232. regs.reg4:=maxlen;
  233. Sys_ReadLink:=SysCall(Syscall_nr_readlink,regs);
  234. end;
  235. {*****************************************************************************
  236. --- Directory:Directory related calls ---
  237. *****************************************************************************}
  238. Function Sys_Chdir(Filename:pchar):longint;
  239. var
  240. regs : SysCallregs;
  241. begin
  242. regs.reg2:=longint(filename);
  243. Sys_ChDir:=SysCall(SysCall_nr_chdir,regs);
  244. end;
  245. Function Sys_Mkdir(Filename:pchar;mode:longint):longint;
  246. var
  247. regs : SysCallregs;
  248. begin
  249. regs.reg2:=longint(filename);
  250. regs.reg3:=mode;
  251. Sys_MkDir:=SysCall(SysCall_nr_mkdir,regs);
  252. end;
  253. Function Sys_Rmdir(Filename:pchar):longint;
  254. var
  255. regs : SysCallregs;
  256. begin
  257. regs.reg2:=longint(filename);
  258. Sys_Rmdir:=SysCall(SysCall_nr_rmdir,regs);
  259. end;
  260. {*****************************************************************************
  261. --- Process:Process & program handling - related calls ---
  262. *****************************************************************************}
  263. Function sys_GetPid:LongInt;
  264. {
  265. Get Process ID.
  266. }
  267. var
  268. regs : SysCallregs;
  269. begin
  270. Sys_GetPid:=SysCall(SysCall_nr_getpid,regs);
  271. end;
  272. Procedure Sys_Exit(ExitCode:longint);
  273. var
  274. regs : SysCallregs;
  275. begin
  276. regs.reg2:=exitcode;
  277. SysCall(SysCall_nr_exit,regs)
  278. end;
  279. Procedure SigAction(Signum:longint;Act,OldAct:PSigActionRec );
  280. {
  281. Change action of process upon receipt of a signal.
  282. Signum specifies the signal (all except SigKill and SigStop).
  283. If Act is non-nil, it is used to specify the new action.
  284. If OldAct is non-nil the previous action is saved there.
  285. }
  286. Var
  287. sr : Syscallregs;
  288. begin
  289. sr.reg2:=Signum;
  290. sr.reg3:=Longint(act);
  291. sr.reg4:=Longint(oldact);
  292. SysCall(Syscall_nr_sigaction,sr);
  293. {$ifdef linuxunit}
  294. LinuxError:=Errno;
  295. {$endif}
  296. end;
  297. (*=================== MOVED from syslinux.inc ========================*)
  298. Function Sys_FTruncate(Handle,Pos:longint):longint; //moved from sysunix.inc Do_Truncate
  299. var
  300. sr : syscallregs;
  301. begin
  302. sr.reg2:=Handle;
  303. sr.reg3:=Pos;
  304. sr.reg4:=0;
  305. Sys_FTruncate:=syscall(syscall_nr_ftruncate,sr);
  306. end;
  307. Function Sys_ReadDir(p:pdir):pdirent;
  308. {
  309. Different from Linux, Readdir on BSD is based on Getdents/getdirentries,
  310. due to the absense of the readdir syscall.
  311. }
  312. function readbuffer:longint;
  313. var
  314. retval :longint;
  315. dummy :longint;
  316. begin
  317. retval:=do_syscall(syscall_nr_getdirentries,longint(p^.fd),
  318. longint(@p^.buf^),DIRBLKSIZ,longint(@dummy));
  319. p^.rewind:=longint(p^.buf);
  320. if retval=0 then
  321. begin
  322. p^.rewind:=0;
  323. p^.loc:=0;
  324. end
  325. else
  326. P^.loc:=retval;
  327. readbuffer:=retval;
  328. end;
  329. var
  330. l : pdirent;
  331. novalid : boolean;
  332. begin
  333. if (p^.buf=nil) or (p^.loc=0) THEN
  334. exit(nil);
  335. if p^.loc=-1 then {First readdir on this pdir. Initial fill of buffer}
  336. begin
  337. if readbuffer()=0 Then {nothing to be read}
  338. exit(nil)
  339. end;
  340. l:=nil;
  341. repeat
  342. novalid:=false;
  343. if (pdirent(p^.rewind)^.reclen<>0) then
  344. begin {valid direntry?}
  345. if pdirent(p^.rewind)^.ino<>0 then
  346. l:=pdirent(p^.rewind);
  347. inc(p^.rewind,pdirent(p^.rewind)^.reclen);
  348. if p^.rewind>=(longint(p^.buf)+dirblksiz) then
  349. novalid:=true;
  350. end
  351. else
  352. novalid:=true;
  353. if novalid then
  354. begin {block entirely searched or reclen=0}
  355. if p^.loc<>0 then {blocks left?}
  356. if readbuffer()<>0 then {succesful read?}
  357. novalid:=false;
  358. end;
  359. until (l<>nil) or novalid;
  360. if novalid then
  361. l:=nil;
  362. Sys_ReadDir:=l;
  363. end;
  364. Function Sys_mmap(adr,len,prot,flags,fdes,off:longint):longint; // moved from sysunix.inc, used in sbrk
  365. var
  366. sr: syscallregs;
  367. begin
  368. sr.reg2:=adr;
  369. sr.reg3:=len;
  370. sr.reg4:=prot;
  371. sr.reg5:=flags;
  372. sr.reg6:=fdes;
  373. sr.reg7:=off;
  374. sr.reg8:=0;
  375. Sys_mmap:=do_syscall(syscall_nr_mmap,sr);
  376. end;
  377. {
  378. Interface to Unix ioctl call.
  379. Performs various operations on the filedescriptor Handle.
  380. Ndx describes the operation to perform.
  381. Data points to data needed for the Ndx function. The structure of this
  382. data is function-dependent.
  383. }
  384. Function Sys_IOCtl(Handle,Ndx: Longint;Data: Pointer):LongInt; // This was missing here, instead hardcoded in Do_IsDevice
  385. var
  386. sr: SysCallRegs;
  387. begin
  388. sr.reg2:=Handle;
  389. sr.reg3:=Ndx;
  390. sr.reg4:=Longint(Data);
  391. Sys_IOCtl:=SysCall(Syscall_nr_ioctl,sr);
  392. end;
  393. {
  394. $Log$
  395. Revision 1.4 2003-08-21 22:25:17 olle
  396. - removed parameter from fpc_iocheck
  397. Revision 1.3 2002/09/08 15:29:23 jonas
  398. + added sys_readdir code from OpenBSD in fixes branch
  399. Revision 1.2 2002/09/07 16:01:17 peter
  400. * old logs removed and tabs fixed
  401. Revision 1.1 2002/09/06 18:35:59 jonas
  402. * implemented most syscalls, except readdir because the getdents
  403. syscall is declared obsolete in Darwin...
  404. }