system.pp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. Unit system;
  2. interface
  3. // Was needed too bootstrap with our old 2.1 fpc for BeOS
  4. // to define real
  5. { $define VER2_0}
  6. {$define FPC_IS_SYSTEM}
  7. {$I sysunixh.inc}
  8. type
  9. THeapPointer = ^pointer;
  10. var
  11. heapstartpointer : THeapPointer;
  12. heapstart : pointer;//external;//external name 'HEAP';
  13. myheapsize : longint; //external;//external name 'HEAPSIZE';
  14. myheaprealsize : longint;
  15. heap_handle : longint;
  16. implementation
  17. procedure debugger(s : PChar); cdecl; external 'root' name 'debugger';
  18. //begin
  19. //end;
  20. { OS independant parts}
  21. {$I system.inc}
  22. {*****************************************************************************
  23. System Dependent Exit code
  24. *****************************************************************************}
  25. procedure prthaltproc;external name '_haltproc';
  26. procedure system_exit;
  27. begin
  28. asm
  29. jmp prthaltproc
  30. end;
  31. End;
  32. { OS dependant parts }
  33. {*****************************************************************************
  34. Heap Management
  35. *****************************************************************************}
  36. (*var myheapstart:pointer;
  37. myheapsize:longint;
  38. myheaprealsize:longint;
  39. heap_handle:longint;
  40. zero:longint;
  41. { first address of heap }
  42. function getheapstart:pointer;
  43. begin
  44. getheapstart:=myheapstart;
  45. end;
  46. { current length of heap }
  47. function getheapsize:longint;
  48. begin
  49. getheapsize:=myheapsize;
  50. end;
  51. *)
  52. (*function getheapstart:pointer;
  53. assembler;
  54. asm
  55. leal HEAP,%eax
  56. end ['EAX'];
  57. function getheapsize:longint;
  58. assembler;
  59. asm
  60. movl intern_HEAPSIZE,%eax
  61. end ['EAX'];*)
  62. { function to allocate size bytes more for the program }
  63. { must return the first address of new data space or nil if fail }
  64. (*function Sbrk(size : longint):pointer;
  65. var newsize,newrealsize:longint;
  66. s : string;
  67. begin
  68. WriteLn('SBRK');
  69. Str(size, s);
  70. WriteLn('size : ' + s);
  71. if (myheapsize+size)<=myheaprealsize then
  72. begin
  73. Sbrk:=pointer(heapstart+myheapsize);
  74. myheapsize:=myheapsize+size;
  75. exit;
  76. end;
  77. newsize:=myheapsize+size;
  78. newrealsize:=(newsize and $FFFFF000)+$1000;
  79. case resize_area(heap_handle,newrealsize) of
  80. B_OK :
  81. begin
  82. WriteLn('B_OK');
  83. Sbrk:=pointer(heapstart+myheapsize);
  84. myheapsize:=newsize;
  85. myheaprealsize:=newrealsize;
  86. exit;
  87. end;
  88. B_BAD_VALUE : WriteLn('B_BAD_VALUE');
  89. B_NO_MEMORY : WriteLn('B_NO_MEMORY');
  90. B_ERROR : WriteLn('B_ERROR');
  91. else
  92. begin
  93. Sbrk:=pointer(heapstart+myheapsize);
  94. myheapsize:=newsize;
  95. myheaprealsize:=newrealsize;
  96. exit;
  97. end;
  98. end;
  99. // Sbrk:=nil;
  100. end;*)
  101. function sys_resize_area (handle:cardinal; size:longint):longint; cdecl; external name 'sys_resize_area';
  102. //function sbrk2 (size : longint):pointer; cdecl; external name 'sbrk';
  103. { function to allocate size bytes more for the program }
  104. { must return the first address of new data space or nil if fail }
  105. //function Sbrk(size : longint):pointer;
  106. //var newsize,newrealsize:longint;
  107. // s : string;
  108. //begin
  109. // sbrk := sbrk2(size);
  110. (* sbrk := nil;
  111. WriteLn('sbrk');
  112. Str(size, s);
  113. WriteLn('size : ' + s);
  114. if (myheapsize+size)<=myheaprealsize then
  115. begin
  116. Sbrk:=heapstart+myheapsize;
  117. myheapsize:=myheapsize+size;
  118. exit;
  119. end;
  120. newsize:=myheapsize+size;
  121. newrealsize:=(newsize and $FFFFF000)+$1000;
  122. if sys_resize_area(heap_handle,newrealsize+$1000)=0 then
  123. begin
  124. WriteLn('sys_resize_area OK');
  125. Str(longint(newrealsize), s);
  126. WriteLn('newrealsize : $' + Hexstr(longint(newrealsize), 8));
  127. Str(longint(heapstartpointer), s);
  128. WriteLn('heapstart : $' + Hexstr(longint(heapstart), 8));
  129. Str(myheapsize, s);
  130. WriteLn('myheapsize : ' + s);
  131. Str(myheapsize, s);
  132. WriteLn('Total : ' + s);
  133. WriteLn('Before fillchar');
  134. WriteLn('sbrk : $' + Hexstr(longint(heapstart+myheapsize), 8));
  135. Sbrk:=heapstart+myheapsize;
  136. FillChar(sbrk^, size, #0);
  137. WriteLn('EndFillChar');
  138. WriteLn('sbrk : $' + Hexstr(longint(sbrk), 8));
  139. // ReadLn(s);
  140. myheapsize:=newsize;
  141. Str({longint(heapstartpointer) +} myheapsize, s);
  142. WriteLn('Total : ' + s);
  143. myheaprealsize:=newrealsize;
  144. exit;
  145. end
  146. else
  147. begin
  148. debugger('Bad resize_area');
  149. WriteLn('Bad resize_area');
  150. end;
  151. Sbrk:=nil;
  152. *)
  153. //end;
  154. {****************************************************************************
  155. Low level File Routines
  156. All these functions can set InOutRes on errors
  157. ****************************************************************************}
  158. (*
  159. { close a file from the handle value }
  160. procedure do_close(handle : longint);
  161. begin
  162. if handle<=2 then exit;
  163. InOutRes := fpclose(handle);
  164. end;
  165. procedure do_erase(p : pchar);
  166. begin
  167. if fpunlink(p)<>0 then InOutRes:=1
  168. else InOutRes:=0;
  169. end;
  170. procedure do_rename(p1,p2 : pchar);
  171. begin
  172. InOutRes := fprename(p1, p2);
  173. end;
  174. function do_write(h : longint; addr : pointer; len : longint) : longint;
  175. begin
  176. do_write := fpwrite (h,addr,len);
  177. if (do_write<0) then begin
  178. InOutRes:=do_write;
  179. do_write:=0;
  180. end else InOutRes:=0;
  181. end;
  182. function do_read(h:longint; addr : Pointer; len : longint) : longint;
  183. begin
  184. do_read := fpread (h,addr,len);
  185. if (do_read<0) then begin
  186. InOutRes:=do_read;
  187. do_read:=0;
  188. end else InOutRes:=0;
  189. end;
  190. function do_filepos(handle : longint) : longint;
  191. begin
  192. do_filepos := fplseek(handle,0,1); {1=SEEK_CUR}
  193. if (do_filepos<0) then begin
  194. InOutRes:=do_filepos;
  195. do_filepos:=0;
  196. end else InOutRes:=0;
  197. end;
  198. procedure do_seek(handle,pos : longint);
  199. begin
  200. InOutRes := fplseek(handle,pos,0);
  201. if InOutRes>0 then InOutRes:=0;
  202. end;
  203. function do_seekend(handle:longint):longint;
  204. begin
  205. do_seekend := fplseek (handle,0,2); {2=SEEK_END}
  206. if do_seekend<0 then begin
  207. InOutRes:=do_seekend;
  208. do_seekend:=0;
  209. end else InOutRes:=0;
  210. end;
  211. function do_filesize(handle : longint) : longint;
  212. var cur:longint;
  213. begin
  214. cur := fplseek (handle,0,1); {1=SEEK_CUR}
  215. if cur<0 then begin
  216. InOutRes:=cur;
  217. do_filesize:=0;
  218. exit;
  219. end;
  220. do_filesize := fplseek (handle,0,2); {2=SEEK_END}
  221. if do_filesize<0 then begin
  222. InOutRes:=do_filesize;
  223. do_filesize:=0;
  224. exit;
  225. end;
  226. cur := fplseek (handle,cur,0); {0=SEEK_POS}
  227. if cur<0 then begin
  228. InOutRes:=cur;
  229. do_filesize:=0;
  230. exit;
  231. end;
  232. end;
  233. { truncate at a given position }
  234. procedure do_truncate (handle,pos:longint);
  235. begin
  236. InOutRes:=1;
  237. end;
  238. (*procedure do_open(var f;p:pchar;flags:longint);
  239. {
  240. filerec and textrec have both handle and mode as the first items so
  241. they could use the same routine for opening/creating.
  242. when (flags and $100) the file will be append
  243. when (flags and $1000) the file will be truncate/rewritten
  244. when (flags and $10000) there is no check for close (needed for textfiles)
  245. }
  246. var m:longint;
  247. mode,h:longint;
  248. s : string;
  249. begin
  250. // WriteLn('do_open; -> ');
  251. // WriteLn('p : ' + p);
  252. // Str(flags, s);
  253. // WriteLn('flags : ' + s);
  254. { printf ('OPEN %d ',longint(f));
  255. printf (' %s',longint(p));
  256. printf (' %x',flags);}
  257. m:=0;
  258. case (flags and 3) of
  259. 0:
  260. begin
  261. // WriteLn('0');
  262. m:=m or O_RDONLY;
  263. mode:=fminput;
  264. end;
  265. 1:
  266. begin
  267. // WriteLn('1');
  268. m:=m or O_WRONLY or O_CREAT;
  269. mode:=fmoutput;
  270. end;
  271. 2:
  272. begin
  273. // WriteLn('2');
  274. m:=m or O_RDWR or O_CREAT;
  275. mode:=fminout;
  276. end;
  277. 3:
  278. begin
  279. // WriteLn('3');
  280. m:=m or O_APPEND;
  281. mode:=fmAppend;
  282. end;
  283. end;
  284. // if (flags and $100)<>0 then m:=m or O_APPEND;
  285. { if (flags and $200)<>0 then
  286. begin
  287. WriteLn('Création');
  288. m := m or O_CREAT;
  289. end;
  290. }
  291. // if (flags and $1000)<>0 then m:=m {or O_TRUNC} or O_CREAT;
  292. // m := m or O_CREAT;
  293. // if (flags and $10000)<>0 then m:=m or O_TEXT else m:=m or O_BINARY;
  294. h := fpopen(p, m, mode);
  295. Str(mode, s);
  296. // WriteLn('mode : ' + s);
  297. // Str(m, s);
  298. // WriteLn('m : ' + s);
  299. // Str(h, s);
  300. // WriteLn('h : ' + s);
  301. if h<0 then InOutRes:=h
  302. else InOutRes:=0;
  303. if InOutRes=0 then begin
  304. FileRec(f).handle:=h;
  305. FileRec(f).mode:=mode;
  306. end;
  307. end;*)
  308. const
  309. { Default creation mode for directories and files }
  310. { read/write permission for everyone }
  311. MODE_OPEN = S_IWUSR OR S_IRUSR OR
  312. S_IWGRP OR S_IRGRP OR
  313. S_IWOTH OR S_IROTH;
  314. { read/write search permission for everyone }
  315. MODE_MKDIR = MODE_OPEN OR
  316. S_IXUSR OR S_IXGRP OR S_IXOTH;
  317. Procedure Do_Open(var f;p:pchar;flags:longint);
  318. {
  319. FileRec and textrec have both Handle and mode as the first items so
  320. they could use the same routine for opening/creating.
  321. when (flags and $100) the file will be append
  322. when (flags and $1000) the file will be truncate/rewritten
  323. when (flags and $10000) there is no check for close (needed for textfiles)
  324. }
  325. var
  326. oflags : cint;
  327. Begin
  328. { close first if opened }
  329. if ((flags and $10000)=0) then
  330. begin
  331. case FileRec(f).mode of
  332. fminput,fmoutput,fminout : Do_Close(FileRec(f).Handle);
  333. fmclosed : ;
  334. else
  335. begin
  336. inoutres:=102; {not assigned}
  337. exit;
  338. end;
  339. end;
  340. end;
  341. { reset file Handle }
  342. FileRec(f).Handle:=UnusedHandle;
  343. { We do the conversion of filemodes here, concentrated on 1 place }
  344. case (flags and 3) of
  345. 0 : begin
  346. oflags :=O_RDONLY;
  347. FileRec(f).mode:=fminput;
  348. end;
  349. 1 : begin
  350. oflags :=O_WRONLY;
  351. FileRec(f).mode:=fmoutput;
  352. end;
  353. 2 : begin
  354. oflags :=O_RDWR;
  355. FileRec(f).mode:=fminout;
  356. end;
  357. end;
  358. if (flags and $1000)=$1000 then
  359. oflags:=oflags or (O_CREAT or O_TRUNC)
  360. else
  361. if (flags and $100)=$100 then
  362. oflags:=oflags or (O_APPEND);
  363. { empty name is special }
  364. if p[0]=#0 then
  365. begin
  366. case FileRec(f).mode of
  367. fminput :
  368. FileRec(f).Handle:=StdInputHandle;
  369. fminout, { this is set by rewrite }
  370. fmoutput :
  371. FileRec(f).Handle:=StdOutputHandle;
  372. fmappend :
  373. begin
  374. FileRec(f).Handle:=StdOutputHandle;
  375. FileRec(f).mode:=fmoutput; {fool fmappend}
  376. end;
  377. end;
  378. exit;
  379. end;
  380. { real open call }
  381. FileRec(f).Handle:=Fpopen(p,oflags,MODE_OPEN);
  382. if (FileRec(f).Handle<0) and
  383. (getErrNo=ESysEROFS) and
  384. ((OFlags and O_RDWR)<>0) then
  385. begin
  386. Oflags:=Oflags and not(O_RDWR);
  387. FileRec(f).Handle:=Fpopen(p,oflags,MODE_OPEN);
  388. end;
  389. If Filerec(f).Handle<0 Then
  390. InOutRes := 2
  391. else
  392. InOutRes:=0;
  393. end;
  394. *)
  395. {function do_isdevice(handle:longint):boolean;
  396. begin
  397. do_isdevice:=false;
  398. InOutRes:=0;
  399. end;
  400. }
  401. { $I text.inc}
  402. {*****************************************************************************
  403. UnTyped File Handling
  404. *****************************************************************************}
  405. { $i file.inc}
  406. {*****************************************************************************
  407. Typed File Handling
  408. *****************************************************************************}
  409. { $i typefile.inc}
  410. {*****************************************************************************
  411. Misc. System Dependent Functions
  412. *****************************************************************************}
  413. Function ParamCount: Longint;
  414. var
  415. s : string;
  416. Begin
  417. ParamCount := 0;
  418. Paramcount:=argc - 1;
  419. End;
  420. { variable where full path and filename and executable is stored }
  421. { is setup by the startup of the system unit. }
  422. var
  423. execpathstr : shortstring;
  424. {$ifdef FPC_USE_LIBC}
  425. // private; use the macros, below
  426. function _get_image_info(image : image_id; var info : image_info; size : size_t)
  427. : status_t; cdecl; external 'root' name '_get_image_info';
  428. function _get_next_image_info(team : team_id; var cookie : Longint; var info : image_info; size : size_t)
  429. : status_t; cdecl; external 'root' name '_get_next_image_info';
  430. function get_image_info(image : image_id; var info : image_info) : status_t;
  431. begin
  432. Result := _get_image_info(image, info, SizeOf(info));
  433. end;
  434. function get_next_image_info(team : team_id; var cookie : Longint; var info : image_info) : status_t;
  435. begin
  436. Result := _get_next_image_info(team, cookie, info, SizeOf(info));
  437. end;
  438. {$endif}
  439. { this routine sets up the paramstr(0) string at startup }
  440. procedure setupexecname;
  441. var
  442. cookie: longint;
  443. image : image_info;
  444. index : byte;
  445. s : string;
  446. begin
  447. cookie:=0;
  448. fillchar(image, sizeof(image_info), 0);
  449. if get_next_image_info(0, cookie, image) = B_OK then
  450. begin
  451. execpathstr := strpas(@image.name);
  452. end
  453. else
  454. execpathstr := '';
  455. { problem with Be 4.5 noted... path contains . character }
  456. { if file is directly executed in CWD }
  457. index:=pos('/./',execpathstr);
  458. if index <> 0 then
  459. begin
  460. { remove the /. characters }
  461. Delete(execpathstr,index, 2);
  462. end;
  463. end;
  464. function paramstr(l: longint) : string;
  465. var
  466. s: string;
  467. s1: string;
  468. begin
  469. { stricly conforming POSIX applications }
  470. { have the executing filename as argv[0] }
  471. if l = 0 then
  472. begin
  473. paramstr := execpathstr;
  474. end
  475. else
  476. begin
  477. paramstr := '';
  478. paramstr:=strpas(argv[l]);
  479. end;
  480. end;
  481. Procedure Randomize;
  482. Begin
  483. randseed:=longint(Fptime(nil));
  484. End;
  485. function GetProcessID:SizeUInt;
  486. begin
  487. {$WARNING To be corrected by platform maintainer}
  488. GetProcessID := 1;
  489. end;
  490. {*****************************************************************************
  491. SystemUnit Initialization
  492. *****************************************************************************}
  493. procedure SysInitStdIO;
  494. begin
  495. { Setup stdin, stdout and stderr, for GUI apps redirect stderr,stdout to be
  496. displayed in and messagebox }
  497. OpenStdIO(Input,fmInput,StdInputHandle);
  498. OpenStdIO(Output,fmOutput,StdOutputHandle);
  499. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  500. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  501. end;
  502. function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
  503. begin
  504. result := stklen;
  505. end;
  506. var
  507. s : string;
  508. begin
  509. IsConsole := TRUE;
  510. IsLibrary := FALSE;
  511. StackLength := CheckInitialStkLen(InitialStkLen);
  512. StackBottom := Sptr - StackLength;
  513. SysInitStdIO;
  514. { Setup heap }
  515. myheapsize:=4096*1;// $ 20000;
  516. myheaprealsize:=4096*1;// $ 20000;
  517. heapstart:=nil;
  518. heapstartpointer := nil;
  519. heapstartpointer := Sbrk2(4096*1);
  520. {$IFDEF FPC_USE_LIBC}
  521. // heap_handle := create_area('fpcheap',heapstart,0,myheaprealsize,0,3);//!!
  522. {$ELSE}
  523. // debugger('tata'#0);
  524. // heap_handle := create_area('fpcheap',longint(heapstartpointer),0,myheaprealsize,0,3);//!!
  525. // case heap_handle of
  526. // B_BAD_VALUE : WriteLn('B_BAD_VALUE');
  527. // B_PAGE_SIZE : WriteLn('B_PAGE_SIZE');
  528. // B_NO_MEMORY : WriteLn('B_NO_MEMORY');
  529. // B_ERROR : WriteLn('B_ERROR');
  530. // end;
  531. FillChar(heapstartpointer^, myheaprealsize, #0);
  532. // WriteLn('EndFillChar');
  533. // WriteLn('P : $' + Hexstr(longint(heapstartpointer), 8));
  534. // WriteLn('heapstart : $' + Hexstr(longint(heapstartpointer^), 8));
  535. heapstart := heapstartpointer;
  536. {$ENDIF}
  537. // WriteLn('before InitHeap');
  538. // case heap_handle of
  539. // B_BAD_VALUE : WriteLn('B_BAD_VALUE');
  540. // B_PAGE_SIZE : WriteLn('B_PAGE_SIZE');
  541. // B_NO_MEMORY : WriteLn('B_NO_MEMORY');
  542. // B_ERROR : WriteLn('B_ERROR');
  543. // else
  544. // begin
  545. // WriteLn('ok');
  546. // WriteLn('P : $' + Hexstr(longint(heapstartpointer), 8));
  547. // WriteLn('heapstart : $' + Hexstr(longint(heapstartpointer^), 8));
  548. // if heap_handle>0 then
  549. // begin
  550. InitHeap;
  551. // end;
  552. // end;
  553. // end;
  554. // WriteLn('after InitHeap');
  555. // end else system_exit;
  556. SysInitExceptions;
  557. // WriteLn('after SysInitException');
  558. { Setup IO }
  559. SysInitStdIO;
  560. { Reset IO Error }
  561. InOutRes:=0;
  562. InitSystemThreads;
  563. {$ifdef HASVARIANT}
  564. initvariantmanager;
  565. {$endif HASVARIANT}
  566. setupexecname;
  567. end.