system.pp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2000 by Marco van de Voort
  4. member of the Free Pascal development team.
  5. System unit for Linux.
  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. { These things are set in the makefile, }
  13. { But you can override them here.}
  14. { If you use an aout system, set the conditional AOUT}
  15. { $Define AOUT}
  16. {$ifdef i386}
  17. {$DEFINE ELFRES32}
  18. {$endif}
  19. Unit System;
  20. {*****************************************************************************}
  21. interface
  22. {*****************************************************************************}
  23. {$define FPC_IS_SYSTEM}
  24. {$define HAS_CMDLINE}
  25. {$define USE_NOTHREADMANAGER}
  26. {$i osdefs.inc}
  27. {$I sysunixh.inc}
  28. function get_cmdline:Pchar;
  29. property cmdline:Pchar read get_cmdline;
  30. {$if defined(CPUARM) or defined(CPUM68K)}
  31. {$define fpc_softfpu_interface}
  32. {$i softfpu.pp}
  33. {$undef fpc_softfpu_interface}
  34. {$endif defined(CPUARM) or defined(CPUM68K)}
  35. {*****************************************************************************}
  36. implementation
  37. {*****************************************************************************}
  38. { Include ELF resources }
  39. {$ifdef ELFRES32}
  40. {$define HAS_RESOURCES}
  41. {$i elfres32.inc}
  42. {$endif}
  43. const calculated_cmdline:Pchar=nil;
  44. {$if defined(CPUARM) or defined(CPUM68K)}
  45. {$define fpc_softfpu_implementation}
  46. {$i softfpu.pp}
  47. {$undef fpc_softfpu_implementation}
  48. { we get these functions and types from the softfpu code }
  49. {$define FPC_SYSTEM_HAS_float64}
  50. {$define FPC_SYSTEM_HAS_float32}
  51. {$define FPC_SYSTEM_HAS_flag}
  52. {$define FPC_SYSTEM_HAS_extractFloat64Frac0}
  53. {$define FPC_SYSTEM_HAS_extractFloat64Frac1}
  54. {$define FPC_SYSTEM_HAS_extractFloat64Exp}
  55. {$define FPC_SYSTEM_HAS_extractFloat64Frac}
  56. {$define FPC_SYSTEM_HAS_extractFloat64Sign}
  57. {$define FPC_SYSTEM_HAS_ExtractFloat32Frac}
  58. {$define FPC_SYSTEM_HAS_extractFloat32Exp}
  59. {$define FPC_SYSTEM_HAS_extractFloat32Sign}
  60. {$endif defined(CPUARM) or defined(CPUM68K)}
  61. {$I system.inc}
  62. {*****************************************************************************
  63. Misc. System Dependent Functions
  64. *****************************************************************************}
  65. procedure haltproc(e:longint);cdecl;external name '_haltproc';
  66. procedure System_exit;
  67. begin
  68. haltproc(ExitCode);
  69. End;
  70. Function ParamCount: Longint;
  71. Begin
  72. Paramcount:=argc-1
  73. End;
  74. {function BackPos(c:char; const s: shortstring): integer;
  75. var
  76. i: integer;
  77. Begin
  78. for i:=length(s) downto 0 do
  79. if s[i] = c then break;
  80. if i=0 then
  81. BackPos := 0
  82. else
  83. BackPos := i;
  84. end;}
  85. { variable where full path and filename and executable is stored }
  86. { is setup by the startup of the system unit. }
  87. var
  88. execpathstr : shortstring;
  89. function paramstr(l: longint) : string;
  90. begin
  91. { stricly conforming POSIX applications }
  92. { have the executing filename as argv[0] }
  93. if l=0 then
  94. begin
  95. paramstr := execpathstr;
  96. end
  97. else
  98. paramstr:=strpas(argv[l]);
  99. end;
  100. Procedure Randomize;
  101. Begin
  102. randseed:=longint(Fptime(nil));
  103. End;
  104. {*****************************************************************************
  105. cmdline
  106. *****************************************************************************}
  107. procedure SetupCmdLine;
  108. var
  109. bufsize,
  110. len,j,
  111. size,i : longint;
  112. found : boolean;
  113. buf : pchar;
  114. procedure AddBuf;
  115. begin
  116. reallocmem(calculated_cmdline,size+bufsize);
  117. move(buf^,calculated_cmdline[size],bufsize);
  118. inc(size,bufsize);
  119. bufsize:=0;
  120. end;
  121. begin
  122. if argc<=0 then
  123. exit;
  124. GetMem(buf,ARG_MAX);
  125. size:=0;
  126. bufsize:=0;
  127. i:=0;
  128. while (i<argc) do
  129. begin
  130. len:=strlen(argv[i]);
  131. if len>ARG_MAX-2 then
  132. len:=ARG_MAX-2;
  133. found:=false;
  134. for j:=1 to len do
  135. if argv[i][j]=' ' then
  136. begin
  137. found:=true;
  138. break;
  139. end;
  140. if bufsize+len>=ARG_MAX-2 then
  141. AddBuf;
  142. if found then
  143. begin
  144. buf[bufsize]:='"';
  145. inc(bufsize);
  146. end;
  147. move(argv[i]^,buf[bufsize],len);
  148. inc(bufsize,len);
  149. if found then
  150. begin
  151. buf[bufsize]:='"';
  152. inc(bufsize);
  153. end;
  154. if i<argc then
  155. buf[bufsize]:=' '
  156. else
  157. buf[bufsize]:=#0;
  158. inc(bufsize);
  159. inc(i);
  160. end;
  161. AddBuf;
  162. FreeMem(buf,ARG_MAX);
  163. end;
  164. function get_cmdline:Pchar;
  165. begin
  166. if calculated_cmdline=nil then
  167. setupcmdline;
  168. get_cmdline:=calculated_cmdline;
  169. end;
  170. {*****************************************************************************
  171. SystemUnit Initialization
  172. *****************************************************************************}
  173. function reenable_signal(sig : longint) : boolean;
  174. var
  175. e : TSigSet;
  176. i,j : byte;
  177. begin
  178. fillchar(e,sizeof(e),#0);
  179. { set is 1 based PM }
  180. dec(sig);
  181. i:=sig mod (sizeof(cuLong) * 8);
  182. j:=sig div (sizeof(cuLong) * 8);
  183. e[j]:=1 shl i;
  184. fpsigprocmask(SIG_UNBLOCK,@e,nil);
  185. reenable_signal:=geterrno=0;
  186. end;
  187. // signal handler is arch dependant due to processorexception to language
  188. // exception translation
  189. {$i sighnd.inc}
  190. var
  191. act: SigActionRec;
  192. Procedure InstallSignals;
  193. begin
  194. { Initialize the sigaction structure }
  195. { all flags and information set to zero }
  196. FillChar(act, sizeof(SigActionRec),0);
  197. { initialize handler }
  198. act.sa_handler := SigActionHandler(@SignalToRunError);
  199. act.sa_flags:=SA_SIGINFO;
  200. FpSigAction(SIGFPE,@act,nil);
  201. FpSigAction(SIGSEGV,@act,nil);
  202. FpSigAction(SIGBUS,@act,nil);
  203. FpSigAction(SIGILL,@act,nil);
  204. end;
  205. procedure SysInitStdIO;
  206. begin
  207. OpenStdIO(Input,fmInput,StdInputHandle);
  208. OpenStdIO(Output,fmOutput,StdOutputHandle);
  209. OpenStdIO(ErrOutput,fmOutput,StdErrorHandle);
  210. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  211. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  212. end;
  213. procedure SysInitExecPath;
  214. var
  215. i : longint;
  216. begin
  217. execpathstr[0]:=#0;
  218. i:=Fpreadlink('/proc/self/exe',@execpathstr[1],high(execpathstr));
  219. { it must also be an absolute filename, linux 2.0 points to a memory
  220. location so this will skip that }
  221. if (i>0) and (execpathstr[1]='/') then
  222. execpathstr[0]:=char(i);
  223. end;
  224. function GetProcessID: SizeUInt;
  225. begin
  226. GetProcessID := SizeUInt (fpGetPID);
  227. end;
  228. function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
  229. var
  230. limits : TRLimit;
  231. success : boolean;
  232. begin
  233. success := false;
  234. fillchar(limits, sizeof(limits), 0);
  235. {$ifdef has_ugetrlimit}
  236. success := fpugetrlimit(RLIMIT_STACK, @limits)=0;
  237. {$endif}
  238. if (not success) then
  239. success := fpgetrlimit(RLIMIT_STACK, @limits)=0;
  240. if (success) and (limits.rlim_cur < stklen) then
  241. result := limits.rlim_cur
  242. else
  243. result := stklen;
  244. end;
  245. var
  246. initialstkptr : Pointer;external name '__stkptr';
  247. begin
  248. SysResetFPU;
  249. {$if defined(cpupowerpc)}
  250. // some PPC kernels set the exception bits FE0/FE1 in the MSR to zero,
  251. // disabling all FPU exceptions. Enable them again.
  252. fpprctl(PR_SET_FPEXC, PR_FP_EXC_PRECISE);
  253. {$endif}
  254. IsConsole := TRUE;
  255. StackLength := CheckInitialStkLen(initialStkLen);
  256. StackBottom := initialstkptr - StackLength;
  257. { Set up signals handlers }
  258. InstallSignals;
  259. { Setup heap }
  260. InitHeap;
  261. SysInitExceptions;
  262. { Setup stdin, stdout and stderr }
  263. SysInitStdIO;
  264. { Arguments }
  265. SysInitExecPath;
  266. { Reset IO Error }
  267. InOutRes:=0;
  268. { threading }
  269. InitSystemThreads;
  270. initvariantmanager;
  271. initwidestringmanager;
  272. end.