system.pp 19 KB

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