system.pp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by the Free Pascal development team.
  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. { no stack check in system }
  12. {$S-}
  13. unit system;
  14. interface
  15. {$define StdErrToConsole}
  16. {$ifdef SYSTEMDEBUG}
  17. {$define SYSTEMEXCEPTIONDEBUG}
  18. {$endif SYSTEMDEBUG}
  19. {$ifdef i386}
  20. {$define Set_i386_Exception_handler}
  21. {$endif i386}
  22. { include system-independent routine headers }
  23. {$I systemh.inc}
  24. {Platform specific information}
  25. const LineEnding = #13#10; LFNSupport = false; { ??? - that's how it was declared in dos.pp! } DirectorySeparator = '\'; DriveSeparator = ':'; PathSeparator = ';';
  26. { FileNameCaseSensitive is defined separately below!!! }
  27. type
  28. { the fields of this record are os dependent }
  29. { and they shouldn't be used in a program }
  30. { only the type TCriticalSection is important }
  31. TRTLCriticalSection = packed record
  32. SemaHandle : LONGINT;
  33. SemaIsOpen : BOOLEAN;
  34. end;
  35. { include threading stuff }
  36. {$i threadh.inc}
  37. { include heap support headers }
  38. {$I heaph.inc}
  39. CONST
  40. { Default filehandles }
  41. UnusedHandle : longint = -1;
  42. StdInputHandle : longint = 0;
  43. StdOutputHandle : longint = 0;
  44. StdErrorHandle : longint = 0;
  45. FileNameCaseSensitive : boolean = false;
  46. sLineBreak = LineEnding;
  47. DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsCRLF;
  48. TYPE
  49. TNWCheckFunction = procedure (var code : longint);
  50. VAR
  51. ArgC : INTEGER;
  52. ArgV : ppchar;
  53. NetwareCheckFunction : TNWCheckFunction;
  54. NetwareMainThreadGroupID: longint;
  55. CONST
  56. envp : ppchar = nil; {dummy to make heaptrc happy}
  57. PROCEDURE ConsolePrintf (FormatStr : PCHAR; Param : LONGINT); CDecl;
  58. PROCEDURE ConsolePrintf3 (FormatStr : PCHAR; P1,P2,P3 : LONGINT); CDecl;
  59. PROCEDURE ConsolePrintf (FormatStr : PCHAR); CDecl;
  60. implementation
  61. { Indicate that stack checking is taken care by OS} {$DEFINE NO_GENERIC_STACK_CHECK}
  62. { include system independent routines } {$I system.inc}
  63. { some declarations for Netware API calls }
  64. {$I nwsys.inc}
  65. {$I errno.inc}
  66. {procedure setup_arguments;
  67. begin
  68. end; }
  69. {procedure setup_environment;
  70. begin
  71. end; }
  72. procedure PASCALMAIN;external name 'PASCALMAIN';
  73. procedure fpc_do_exit;external name 'FPC_DO_EXIT';
  74. {*****************************************************************************
  75. Startup
  76. *****************************************************************************}
  77. PROCEDURE nlm_main (_ArgC : LONGINT; _ArgV : ppchar); CDECL; [public,alias: '_nlm_main'];
  78. BEGIN
  79. ArgC := _ArgC;
  80. ArgV := _ArgV;
  81. PASCALMAIN;
  82. END;
  83. {$ifdef MT}
  84. procedure CloseAllRemainingSemaphores; FORWARD;
  85. procedure ReleaseThreadVars; FORWARD;
  86. {$endif}
  87. {*****************************************************************************
  88. System Dependent Exit code
  89. *****************************************************************************}
  90. procedure FreeSbrkMem; forward;
  91. var SigTermHandlerActive : boolean;
  92. Procedure system_exit;
  93. begin
  94. {$ifdef MT}
  95. CloseAllRemainingSemaphores;
  96. ReleaseThreadVars;
  97. {$endif}
  98. FreeSbrkMem; { free memory allocated by heapmanager }
  99. if not SigTermHandlerActive then
  100. begin
  101. if ExitCode <> 0 Then { otherwise we dont see runtime-errors }
  102. PressAnyKeyToContinue;
  103. _exit (ExitCode);
  104. end;
  105. end;
  106. {*****************************************************************************
  107. Stack check code
  108. *****************************************************************************}
  109. procedure int_stackcheck(stack_size:longint);[public,alias:'FPC_STACKCHECK'];
  110. {
  111. called when trying to get local stack if the compiler directive $S is set this function must preserve esi !!!! because esi is set by the calling proc for methods it must preserve all registers !!
  112. With a 2048 byte safe area used to write to StdIo without crossing the stack boundary
  113. }
  114. begin
  115. IF _stackavail > stack_size + 2048 THEN EXIT;
  116. HandleError (202);
  117. end;
  118. {*****************************************************************************
  119. ParamStr/Randomize
  120. *****************************************************************************}
  121. { number of args }
  122. function paramcount : longint;
  123. begin
  124. paramcount := argc - 1;
  125. end;
  126. { argument number l }
  127. function paramstr(l : longint) : string;
  128. begin
  129. if (l>=0) and (l+1<=argc) then
  130. paramstr:=strpas(argv[l])
  131. else
  132. paramstr:='';
  133. end;
  134. { set randseed to a new pseudo random value }
  135. procedure randomize;
  136. begin
  137. randseed := _time (NIL);
  138. end;
  139. {*****************************************************************************
  140. Heap Management
  141. *****************************************************************************}
  142. { first address of heap }
  143. function getheapstart:pointer;
  144. assembler;
  145. asm
  146. leal HEAP,%eax
  147. end ['EAX'];
  148. { current length of heap }
  149. function getheapsize:longint;
  150. assembler;
  151. asm
  152. movl HEAPSIZE,%eax
  153. end ['EAX'];
  154. const HeapInitialMaxBlocks = 32;
  155. type THeapSbrkBlockList = array [1.. HeapInitialMaxBlocks] of pointer;
  156. var HeapSbrkBlockList : ^THeapSbrkBlockList = nil;
  157. HeapSbrkLastUsed : dword = 0;
  158. HeapSbrkAllocated : dword = 0;
  159. { function to allocate size bytes more for the program }
  160. { must return the first address of new data space or -1 if fail }
  161. { for netware all allocated blocks are saved to free them at }
  162. { exit (to avoid message "Module did not release xx resources") }
  163. Function Sbrk(size : longint):longint;
  164. var P,P2 : POINTER;
  165. begin
  166. P := _malloc (size);
  167. if P = nil then
  168. Sbrk := -1
  169. else begin
  170. Sbrk := LONGINT (P);
  171. if HeapSbrkBlockList = nil then
  172. begin
  173. Pointer (HeapSbrkBlockList) := _malloc (sizeof (HeapSbrkBlockList^));
  174. if HeapSbrkBlockList = nil then
  175. begin
  176. _free (P);
  177. Sbrk := -1;
  178. exit;
  179. end;
  180. fillchar (HeapSbrkBlockList^,sizeof(HeapSbrkBlockList^),0);
  181. HeapSbrkAllocated := HeapInitialMaxBlocks;
  182. end;
  183. if (HeapSbrkLastUsed = HeapSbrkAllocated) then
  184. begin { grow }
  185. p2 := _realloc (HeapSbrkBlockList, HeapSbrkAllocated + HeapInitialMaxBlocks);
  186. if p2 = nil then
  187. begin
  188. _free (P);
  189. Sbrk := -1;
  190. exit;
  191. end;
  192. inc (HeapSbrkAllocated, HeapInitialMaxBlocks);
  193. end;
  194. inc (HeapSbrkLastUsed);
  195. HeapSbrkBlockList^[HeapSbrkLastUsed] := P;
  196. end;
  197. end;
  198. procedure FreeSbrkMem;
  199. var i : longint;
  200. begin
  201. if HeapSbrkBlockList <> nil then
  202. begin
  203. for i := 1 to HeapSbrkLastUsed do
  204. _free (HeapSbrkBlockList^[i]);
  205. _free (HeapSbrkBlockList);
  206. HeapSbrkAllocated := 0;
  207. HeapSbrkLastUsed := 0;
  208. HeapSbrkBlockList := nil;
  209. end;
  210. end;
  211. { include standard heap management }
  212. {$I heap.inc}
  213. {****************************************************************************
  214. Low level File Routines
  215. All these functions can set InOutRes on errors
  216. ****************************************************************************}
  217. PROCEDURE NW2PASErr (Err : LONGINT);
  218. BEGIN
  219. if Err = 0 then { Else it will go through all the cases }
  220. exit;
  221. case Err of
  222. Sys_ENFILE,
  223. Sys_EMFILE : Inoutres:=4;
  224. Sys_ENOENT : Inoutres:=2;
  225. Sys_EBADF : Inoutres:=6;
  226. Sys_ENOMEM,
  227. Sys_EFAULT : Inoutres:=217;
  228. Sys_EINVAL : Inoutres:=218;
  229. Sys_EPIPE,
  230. Sys_EINTR,
  231. Sys_EIO,
  232. Sys_EAGAIN,
  233. Sys_ENOSPC : Inoutres:=101;
  234. Sys_ENAMETOOLONG,
  235. Sys_ELOOP,
  236. Sys_ENOTDIR : Inoutres:=3;
  237. Sys_EROFS,
  238. Sys_EEXIST,
  239. Sys_EACCES : Inoutres:=5;
  240. Sys_EBUSY : Inoutres:=162;
  241. end;
  242. END;
  243. FUNCTION errno : LONGINT;
  244. BEGIN
  245. errno := __get_errno_ptr^;
  246. END;
  247. PROCEDURE Errno2Inoutres;
  248. BEGIN
  249. NW2PASErr (errno);
  250. END;
  251. PROCEDURE SetFileError (VAR Err : LONGINT);
  252. BEGIN
  253. IF Err >= 0 THEN
  254. InOutRes := 0
  255. ELSE
  256. BEGIN
  257. Err := errno;
  258. NW2PASErr (Err);
  259. Err := 0;
  260. END;
  261. END;
  262. { close a file from the handle value }
  263. procedure do_close(handle : longint);
  264. VAR res : LONGINT;
  265. begin
  266. res := _close (handle);
  267. IF res <> 0 THEN
  268. SetFileError (res)
  269. ELSE
  270. InOutRes := 0;
  271. end;
  272. procedure do_erase(p : pchar);
  273. VAR res : LONGINT;
  274. begin
  275. res := _unlink (p);
  276. IF Res < 0 THEN
  277. SetFileError (res)
  278. ELSE
  279. InOutRes := 0;
  280. end;
  281. procedure do_rename(p1,p2 : pchar);
  282. VAR res : LONGINT;
  283. begin
  284. res := _rename (p1,p2);
  285. IF Res < 0 THEN
  286. SetFileError (res)
  287. ELSE
  288. InOutRes := 0
  289. end;
  290. function do_write(h,addr,len : longint) : longint;
  291. VAR res : LONGINT;
  292. begin
  293. res := _write (h,POINTER(addr),len);
  294. IF res > 0 THEN
  295. InOutRes := 0
  296. ELSE
  297. SetFileError (res);
  298. do_write := res;
  299. end;
  300. function do_read(h,addr,len : longint) : longint;
  301. VAR res : LONGINT;
  302. begin
  303. res := _read (h,POINTER(addr),len);
  304. IF res > 0 THEN
  305. InOutRes := 0
  306. ELSE
  307. SetFileError (res);
  308. do_read := res;
  309. end;
  310. function do_filepos(handle : longint) : longint;
  311. VAR res : LONGINT;
  312. begin
  313. InOutRes:=1;
  314. res := _tell (handle);
  315. IF res < 0 THEN
  316. SetFileError (res)
  317. ELSE
  318. InOutRes := 0;
  319. do_filepos := res;
  320. end;
  321. CONST SEEK_SET = 0; // Seek from beginning of file.
  322. SEEK_CUR = 1; // Seek from current position.
  323. SEEK_END = 2; // Seek from end of file.
  324. procedure do_seek(handle,pos : longint);
  325. VAR res : LONGINT;
  326. begin
  327. res := _lseek (handle,pos, SEEK_SET);
  328. IF res >= 0 THEN
  329. InOutRes := 0
  330. ELSE
  331. SetFileError (res);
  332. end;
  333. function do_seekend(handle:longint):longint;
  334. VAR res : LONGINT;
  335. begin
  336. res := _lseek (handle,0, SEEK_END);
  337. IF res >= 0 THEN
  338. InOutRes := 0
  339. ELSE
  340. SetFileError (res);
  341. do_seekend := res;
  342. end;
  343. function do_filesize(handle : longint) : longint;
  344. VAR res : LONGINT;
  345. begin
  346. res := _filelength (handle);
  347. IF res < 0 THEN
  348. BEGIN
  349. SetFileError (Res);
  350. do_filesize := -1;
  351. END ELSE
  352. BEGIN
  353. InOutRes := 0;
  354. do_filesize := res;
  355. END;
  356. end;
  357. { truncate at a given position }
  358. procedure do_truncate (handle,pos:longint);
  359. VAR res : LONGINT;
  360. begin
  361. res := _chsize (handle,pos);
  362. IF res <> 0 THEN
  363. SetFileError (res)
  364. ELSE
  365. InOutRes := 0;
  366. end;
  367. // mostly stolen from syslinux
  368. procedure do_open(var f;p:pchar;flags:longint);
  369. {
  370. filerec and textrec have both handle and mode as the first items so
  371. they could use the same routine for opening/creating.
  372. when (flags and $10) the file will be append
  373. when (flags and $100) the file will be truncate/rewritten
  374. when (flags and $1000) there is no check for close (needed for textfiles)
  375. }
  376. var
  377. oflags : longint;
  378. Begin
  379. { close first if opened }
  380. if ((flags and $10000)=0) then
  381. begin
  382. case FileRec(f).mode of
  383. fminput,fmoutput,fminout : Do_Close(FileRec(f).Handle);
  384. fmclosed : ;
  385. else
  386. begin
  387. inoutres:=102; {not assigned}
  388. exit;
  389. end;
  390. end;
  391. end;
  392. { reset file Handle }
  393. FileRec(f).Handle:=UnusedHandle;
  394. { We do the conversion of filemodes here, concentrated on 1 place }
  395. case (flags and 3) of
  396. 0 : begin
  397. oflags := O_RDONLY;
  398. filerec(f).mode := fminput;
  399. end;
  400. 1 : begin
  401. oflags := O_WRONLY;
  402. filerec(f).mode := fmoutput;
  403. end;
  404. 2 : begin
  405. oflags := O_RDWR;
  406. filerec(f).mode := fminout;
  407. end;
  408. end;
  409. if (flags and $1000)=$1000 then
  410. oflags:=oflags or (O_CREAT or O_TRUNC)
  411. else
  412. if (flags and $100)=$100 then
  413. oflags:=oflags or (O_APPEND);
  414. { empty name is special }
  415. if p[0]=#0 then
  416. begin
  417. case FileRec(f).mode of
  418. fminput :
  419. FileRec(f).Handle:=StdInputHandle;
  420. fminout, { this is set by rewrite }
  421. fmoutput :
  422. FileRec(f).Handle:=StdOutputHandle;
  423. fmappend :
  424. begin
  425. FileRec(f).Handle:=StdOutputHandle;
  426. FileRec(f).mode:=fmoutput; {fool fmappend}
  427. end;
  428. end;
  429. exit;
  430. end;
  431. { real open call }
  432. FileRec(f).Handle := _open(p,oflags,438);
  433. //WriteLn ('_open (',p,') liefert ',ErrNo, 'Handle: ',FileRec(f).Handle);
  434. // errno does not seem to be set on succsess ??
  435. IF FileRec(f).Handle < 0 THEN
  436. if (ErrNo=Sys_EROFS) and ((OFlags and O_RDWR)<>0) then
  437. begin // i.e. for cd-rom
  438. Oflags:=Oflags and not(O_RDWR);
  439. FileRec(f).Handle := _open(p,oflags,438);
  440. end;
  441. IF FileRec(f).Handle < 0 THEN
  442. Errno2Inoutres
  443. ELSE
  444. InOutRes := 0;
  445. End;
  446. function do_isdevice(handle:longint):boolean;
  447. begin
  448. do_isdevice := (_isatty (handle) > 0);
  449. end;
  450. {*****************************************************************************
  451. UnTyped File Handling
  452. *****************************************************************************}
  453. {$i file.inc}
  454. {*****************************************************************************
  455. Typed File Handling
  456. *****************************************************************************}
  457. {$i typefile.inc}
  458. {*****************************************************************************
  459. Text File Handling
  460. *****************************************************************************}
  461. { should we consider #26 as the end of a file ? }
  462. {?? $DEFINE EOF_CTRLZ}
  463. {$i text.inc}
  464. {*****************************************************************************
  465. Directory Handling
  466. *****************************************************************************}
  467. procedure mkdir(const s : string);[IOCheck];
  468. VAR S2 : STRING;
  469. Res: LONGINT;
  470. BEGIN
  471. S2 := S;
  472. IF Length (S2) = 255 THEN DEC (BYTE(S2[0]));
  473. S2 := S2 + #0;
  474. Res := _mkdir (@S2[1]);
  475. IF Res = 0 THEN
  476. InOutRes:=0
  477. ELSE
  478. SetFileError (Res);
  479. END;
  480. procedure rmdir(const s : string);[IOCheck];
  481. VAR S2 : STRING;
  482. Res: LONGINT;
  483. BEGIN
  484. S2 := S;
  485. IF Length (S2) = 255 THEN DEC (BYTE(S2[0]));
  486. S2 := S2 + #0;
  487. Res := _rmdir (@S2[1]);
  488. IF Res = 0 THEN
  489. InOutRes:=0
  490. ELSE
  491. SetFileError (Res);
  492. end;
  493. procedure chdir(const s : string);[IOCheck];
  494. VAR S2 : STRING;
  495. Res: LONGINT;
  496. begin
  497. S2 := S;
  498. IF Length (S2) = 255 THEN DEC (BYTE(S2[0]));
  499. S2 := S2 + #0;
  500. Res := _chdir (@S2[1]);
  501. IF Res = 0 THEN
  502. InOutRes:=0
  503. ELSE
  504. SetFileError (Res);
  505. end;
  506. procedure getdir(drivenr : byte;var dir : shortstring);
  507. VAR P : ARRAY [0..255] OF CHAR;
  508. Len: LONGINT;
  509. begin
  510. P[0] := #0;
  511. _getcwd (@P, SIZEOF (P));
  512. Len := _strlen (P);
  513. IF Len > 0 THEN
  514. BEGIN
  515. Move (P, dir[1], Len);
  516. BYTE(dir[0]) := Len;
  517. END ELSE
  518. InOutRes := 1;
  519. end;
  520. {*****************************************************************************
  521. Thread Handling
  522. *****************************************************************************}
  523. const
  524. fpucw : word = $1332;
  525. procedure InitFPU;assembler;
  526. asm
  527. fninit
  528. fldcw fpucw
  529. end;
  530. { include threading stuff, this is os dependend part }
  531. {$I thread.inc}
  532. { if return-value is <> 0, netware shows the message
  533. Unload Anyway ?
  534. To Disable unload at all, SetNLMDontUnloadFlag can be used on
  535. Netware >= 4.0 }
  536. function CheckFunction : longint; CDECL; [public,alias: 'FPC_NW_CHECKFUNCTION'];
  537. var oldTG:longint;
  538. oldPtr: pointer;
  539. begin
  540. if assigned (NetwareCheckFunction) then
  541. begin
  542. { this function is called without clib context, to allow clib
  543. calls, we set the thread group id before calling the
  544. user-function }
  545. oldTG := _SetThreadGroupID (NetwareMainThreadGroupID);
  546. { to allow use of threadvars, we simply set the threadvar-memory
  547. from the main thread }
  548. oldPtr:= _GetThreadDataAreaPtr;
  549. _SaveThreadDataAreaPtr (thredvarsmainthread);
  550. result := 0;
  551. NetwareCheckFunction (result);
  552. _SaveThreadDataAreaPtr (oldPtr);
  553. _SetThreadGroupID (oldTG);
  554. end else
  555. result := 0;
  556. end;
  557. {$ifdef StdErrToConsole}
  558. var ConsoleBuff : array [0..512] of char;
  559. Function ConsoleWrite(Var F: TextRec): Integer;
  560. var
  561. i : longint;
  562. Begin
  563. if F.BufPos>0 then
  564. begin
  565. if F.BufPos>sizeof(ConsoleBuff)-1 then
  566. i:=sizeof(ConsoleBuff)-1
  567. else
  568. i:=F.BufPos;
  569. Move(F.BufPtr^,ConsoleBuff,i);
  570. ConsoleBuff[i] := #0;
  571. ConsolePrintf(@ConsoleBuff[0]);
  572. end;
  573. F.BufPos:=0;
  574. ConsoleWrite := 0;
  575. End;
  576. Function ConsoleClose(Var F: TextRec): Integer;
  577. begin
  578. ConsoleClose:=0;
  579. end;
  580. Function ConsoleOpen(Var F: TextRec): Integer;
  581. Begin
  582. TextRec(F).InOutFunc:=@ConsoleWrite;
  583. TextRec(F).FlushFunc:=@ConsoleWrite;
  584. TextRec(F).CloseFunc:=@ConsoleClose;
  585. ConsoleOpen:=0;
  586. End;
  587. procedure AssignStdErrConsole(Var T: Text);
  588. begin
  589. Assign(T,'');
  590. TextRec(T).OpenFunc:=@ConsoleOpen;
  591. Rewrite(T);
  592. end;
  593. {$endif}
  594. { this will be called if the nlm is unloaded. It will NOT be
  595. called if the program exits i.e. with halt.
  596. Halt (or _exit) can not be called from this callback procedure }
  597. procedure TermSigHandler (Sig:longint); CDecl;
  598. var oldTG : longint;
  599. oldPtr: pointer;
  600. begin
  601. oldTG := _SetThreadGroupID (NetwareMainThreadGroupID); { this is only needed for nw 3.11 }
  602. { _GetThreadDataAreaPtr will not be valid because the signal
  603. handler is called by netware with a differnt thread. To avoid
  604. problems in the exit routines, we set the data of the main thread
  605. here }
  606. oldPtr:= _GetThreadDataAreaPtr;
  607. _SaveThreadDataAreaPtr (thredvarsmainthread);
  608. SigTermHandlerActive := true; { to avoid that system_exit calls _exit }
  609. do_exit; { calls finalize units }
  610. _SaveThreadDataAreaPtr (oldPtr);
  611. _SetThreadGroupID (oldTG);
  612. end;
  613. {*****************************************************************************
  614. SystemUnit Initialization
  615. *****************************************************************************}
  616. Begin StackBottom := SPtr - StackLength;
  617. {$ifdef MT}
  618. { the exceptions use threadvars so do this _before_ initexceptions }
  619. AllocateThreadVars;
  620. {$endif MT}
  621. SigTermHandlerActive := false;
  622. NetwareCheckFunction := nil;
  623. NetwareMainThreadGroupID := _GetThreadGroupID;
  624. _Signal (_SIGTERM, @TermSigHandler);
  625. { Setup heap }
  626. InitHeap;
  627. InitExceptions;
  628. { Setup stdin, stdout and stderr }
  629. StdInputHandle := _fileno (LONGINT (_GetStdIn^)); // GetStd** returns **FILE !
  630. StdOutputHandle:= _fileno (LONGINT (_GetStdOut^));
  631. StdErrorHandle := _fileno (LONGINT (_GetStdErr^));
  632. OpenStdIO(Input,fmInput,StdInputHandle);
  633. OpenStdIO(Output,fmOutput,StdOutputHandle);
  634. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  635. {$ifdef StdErrToConsole}
  636. AssignStdErrConsole(StdErr);
  637. {$else}
  638. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  639. {$endif}
  640. { Setup environment and arguments }
  641. {Setup_Environment;
  642. Setup_Arguments; }
  643. { Reset IO Error }
  644. InOutRes:=0;
  645. {Delphi Compatible}
  646. IsLibrary := FALSE;
  647. IsConsole := TRUE;
  648. ExitCode := 0;
  649. End.
  650. {
  651. $Log$
  652. Revision 1.13 2002-07-01 16:29:05 peter
  653. * sLineBreak changed to normal constant like Kylix
  654. Revision 1.12 2002/04/15 18:47:34 carl
  655. + reinstate novell stack checking
  656. Revision 1.11 2002/04/12 17:40:11 carl
  657. + generic stack checking
  658. Revision 1.10 2002/04/01 15:20:08 armin
  659. + unload module no longer shows: Module did not release...
  660. + check-function will no longer be removed when smartlink is on
  661. Revision 1.9 2002/04/01 10:47:31 armin
  662. makefile.fpc for netware
  663. stderr to netware console
  664. free all memory (threadvars and heap) to avoid error message while unloading nlm
  665. Revision 1.8 2002/03/30 09:09:47 armin
  666. + support check-function for netware
  667. Revision 1.7 2002/03/17 17:57:33 armin
  668. + threads and winsock2 implemented
  669. Revision 1.5 2001/06/18 14:26:16 jonas
  670. * move platform independent constant declarations after inclusion of
  671. systemh.inc
  672. Revision 1.4 2001/06/13 22:20:11 hajny
  673. + platform specific information
  674. Revision 1.3 2001/04/16 18:39:50 florian
  675. * updates from Armin commited
  676. Revision 1.2 2001/04/11 14:17:00 florian
  677. * added logs, fixed email address of Armin, it is
  678. [email protected]
  679. Revision 1.1 2001/04/11 14:14:12 florian
  680. * initial commit, thanks to Armin Diehl ([email protected])
  681. Revision 1.2 2000/07/13 11:33:56 michael
  682. + removed logs
  683. }