system.pp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2019 the Free Pascal development team.
  4. System unit for Haiku
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. Unit System;
  12. interface
  13. {$define FPC_IS_SYSTEM}
  14. {$I sysunixh.inc}
  15. implementation
  16. var
  17. initialstkptr : Pointer; external name '__stkptr';
  18. procedure debugger(s : PChar); cdecl; external 'root' name 'debugger';
  19. function disable_debugger(state : integer): integer; cdecl; external 'root' name 'disable_debugger';
  20. { OS independant parts}
  21. {$I system.inc}
  22. {*****************************************************************************
  23. System Dependent Exit code
  24. *****************************************************************************}
  25. {$ifdef legacy_startup}
  26. procedure prthaltproc;external name '_haltproc';
  27. procedure system_exit;
  28. begin
  29. asm
  30. jmp prthaltproc
  31. end;
  32. End;
  33. {$else legacy_startup}
  34. procedure haltproc(exitcode: longint); cdecl; external name '_haltproc';
  35. procedure system_exit;
  36. begin
  37. haltproc(ExitCode);
  38. end;
  39. {$endif legacy_startup}
  40. { OS dependant parts }
  41. { $I text.inc}
  42. {*****************************************************************************
  43. UnTyped File Handling
  44. *****************************************************************************}
  45. { $i file.inc}
  46. {*****************************************************************************
  47. Typed File Handling
  48. *****************************************************************************}
  49. { $i typefile.inc}
  50. {*****************************************************************************
  51. Misc. System Dependent Functions
  52. *****************************************************************************}
  53. Function ParamCount: Longint;
  54. Begin
  55. Paramcount := argc - 1;
  56. End;
  57. { variable where full path and filename and executable is stored }
  58. { is setup by the startup of the system unit. }
  59. var
  60. execpathstr : shortstring;
  61. {$ifdef FPC_USE_LIBC}
  62. // private; use the macros, below
  63. function _get_image_info(image : image_id; var info : image_info; size : size_t)
  64. : status_t; cdecl; external 'root' name '_get_image_info';
  65. function _get_next_image_info(team : team_id; var cookie : Longint; var info : image_info; size : size_t)
  66. : status_t; cdecl; external 'root' name '_get_next_image_info';
  67. function get_image_info(image : image_id; var info : image_info) : status_t;
  68. begin
  69. Result := _get_image_info(image, info, SizeOf(info));
  70. end;
  71. function get_next_image_info(team : team_id; var cookie : Longint; var info : image_info) : status_t;
  72. begin
  73. Result := _get_next_image_info(team, cookie, info, SizeOf(info));
  74. end;
  75. {$endif}
  76. { this routine sets up the paramstr(0) string at startup }
  77. procedure setupexecname;
  78. var
  79. cookie: longint;
  80. image : image_info;
  81. index : byte;
  82. s : string;
  83. begin
  84. cookie:=0;
  85. fillchar(image, sizeof(image_info), 0);
  86. if get_next_image_info(0, cookie, image) = B_OK then
  87. begin
  88. execpathstr := strpas(@image.name);
  89. end
  90. else
  91. execpathstr := '';
  92. { problem with Be 4.5 noted... path contains . character }
  93. { if file is directly executed in CWD }
  94. index:=pos('/./',execpathstr);
  95. if index <> 0 then
  96. begin
  97. { remove the /. characters }
  98. Delete(execpathstr,index, 2);
  99. end;
  100. end;
  101. function paramstr(l: longint) : string;
  102. var
  103. s: string;
  104. s1: string;
  105. begin
  106. { stricly conforming POSIX applications }
  107. { have the executing filename as argv[0] }
  108. if l = 0 then
  109. begin
  110. paramstr := execpathstr;
  111. end
  112. else if (l < argc) then
  113. begin
  114. paramstr:=strpas(argv[l]);
  115. end
  116. else
  117. paramstr := '';
  118. end;
  119. Procedure Randomize;
  120. Begin
  121. randseed:=longint(Fptime(nil));
  122. End;
  123. function GetProcessID: SizeUInt;
  124. begin
  125. GetProcessID := SizeUInt (fpGetPID);
  126. end;
  127. {*****************************************************************************
  128. SystemUnit Initialization
  129. *****************************************************************************}
  130. function reenable_signal(sig : longint) : boolean;
  131. var
  132. e : TSigSet;
  133. i,j : byte;
  134. olderrno: cint;
  135. begin
  136. fillchar(e,sizeof(e),#0);
  137. { set is 1 based PM }
  138. dec(sig);
  139. i:=sig mod (sizeof(cuLong) * 8);
  140. j:=sig div (sizeof(cuLong) * 8);
  141. e[j]:=1 shl i;
  142. { this routine is called from a signal handler, so must not change errno }
  143. olderrno:=geterrno;
  144. fpsigprocmask(SIG_UNBLOCK,@e,nil);
  145. reenable_signal:=geterrno=0;
  146. seterrno(olderrno);
  147. end;
  148. // signal handler is arch dependant due to processorexception to language
  149. // exception translation
  150. {$i sighnd.inc}
  151. procedure set_signal_stack(ptr : pointer; size : size_t); cdecl; external 'root' name 'set_signal_stack';
  152. function sigaltstack(const stack : pstack_t; oldStack : pstack_t) : integer; cdecl; external 'root' name 'sigaltstack';
  153. type
  154. {$PACKRECORDS C}
  155. TAlternateSignalStack = record
  156. case Integer of
  157. 0 : (buffer : array[0..(SIGSTKSZ * 4)-1] of Char);
  158. 1 : (ld : clonglong);
  159. 2 : (l : integer);
  160. 3 : (p : pointer);
  161. end;
  162. var
  163. alternate_signal_stack : TAlternateSignalStack;
  164. procedure InstallDefaultSignalHandler(signum: longint; out oldact: SigActionRec); public name '_FPC_INSTALLDEFAULTSIGHANDLER';
  165. var
  166. r : integer;
  167. st : stack_t;
  168. act : SigActionRec;
  169. begin
  170. st.ss_flags := 0;
  171. st.ss_sp := @alternate_signal_stack.buffer;
  172. st.ss_size := SizeOf(alternate_signal_stack.buffer);
  173. r := sigaltstack(@st, nil);
  174. if (r <> 0) then
  175. begin
  176. debugger('sigaltstack error');
  177. end;
  178. { Initialize the sigaction structure }
  179. { all flags and information set to zero }
  180. FillChar(act, sizeof(SigActionRec), #0);
  181. { initialize handler }
  182. act.sa_mask[0] := 0;
  183. act.sa_handler := SigActionHandler(@SignalToRunError);
  184. act.sa_flags := SA_ONSTACK or SA_SIGINFO;
  185. FpSigAction(signum,@act,@oldact);
  186. end;
  187. var
  188. oldsigfpe: SigActionRec; public name '_FPC_OLDSIGFPE';
  189. oldsigsegv: SigActionRec; public name '_FPC_OLDSIGSEGV';
  190. oldsigbus: SigActionRec; public name '_FPC_OLDSIGBUS';
  191. oldsigill: SigActionRec; public name '_FPC_OLDSIGILL';
  192. Procedure InstallSignals;
  193. begin
  194. InstallDefaultSignalHandler(SIGFPE,oldsigfpe);
  195. InstallDefaultSignalHandler(SIGSEGV,oldsigsegv);
  196. InstallDefaultSignalHandler(SIGBUS,oldsigbus);
  197. InstallDefaultSignalHandler(SIGILL,oldsigill);
  198. end;
  199. Procedure RestoreOldSignalHandlers;
  200. begin
  201. FpSigAction(SIGFPE,@oldsigfpe,nil);
  202. FpSigAction(SIGSEGV,@oldsigsegv,nil);
  203. FpSigAction(SIGBUS,@oldsigbus,nil);
  204. FpSigAction(SIGILL,@oldsigill,nil);
  205. end;
  206. procedure SysInitStdIO;
  207. begin
  208. { Setup stdin, stdout and stderr, for GUI apps redirect stderr,stdout to be
  209. displayed in and messagebox }
  210. OpenStdIO(Input,fmInput,StdInputHandle);
  211. OpenStdIO(Output,fmOutput,StdOutputHandle);
  212. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  213. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  214. end;
  215. function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
  216. begin
  217. result := stklen;
  218. end;
  219. begin
  220. IsConsole := TRUE;
  221. StackLength := CheckInitialStkLen(InitialStkLen);
  222. {$if FPC_FULLVERSION >= 30301}
  223. StackBottom := initialstkptr - StackLength;
  224. {$else}
  225. StackBottom := Sptr - StackLength;
  226. {$endif}
  227. ReturnNilIfGrowHeapFails := False;
  228. { Set up signals handlers }
  229. InstallSignals;
  230. {$ifdef cpui386}
  231. fpc_cpucodeinit;
  232. {$endif}
  233. { Setup heap }
  234. InitHeap;
  235. SysInitExceptions;
  236. initunicodestringmanager;
  237. { Setup IO }
  238. SysInitStdIO;
  239. { Reset IO Error }
  240. InOutRes:=0;
  241. InitSystemThreads;
  242. InitSystemDynLibs;
  243. setupexecname;
  244. { restore original signal handlers in case this is a library }
  245. if IsLibrary then
  246. RestoreOldSignalHandlers;
  247. end.