system.pp 7.6 KB

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