system.pp 19 KB

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