system.pas 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222
  1. {
  2. $Id$
  3. ****************************************************************************
  4. This file is part of the Free Pascal run time library.
  5. Copyright (c) 1999-2002 by Free Pascal development team
  6. Free Pascal - OS/2 runtime library
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. ****************************************************************************}
  13. unit {$ifdef VER1_0}sysos2{$else}System{$endif};
  14. interface
  15. {Link the startup code.}
  16. {$ifdef VER1_0}
  17. {$l prt1.oo2}
  18. {$else}
  19. {$l prt1.o}
  20. {$endif}
  21. {$ifdef SYSTEMDEBUG}
  22. {$define SYSTEMEXCEPTIONDEBUG}
  23. {$endif SYSTEMDEBUG}
  24. { $DEFINE OS2EXCEPTIONS}
  25. {$I systemh.inc}
  26. {$IFDEF OS2EXCEPTIONS}
  27. (* Types and constants for exception handler support *)
  28. type
  29. {x} PEXCEPTION_FRAME = ^TEXCEPTION_FRAME;
  30. {x} TEXCEPTION_FRAME = record
  31. {x} next : PEXCEPTION_FRAME;
  32. {x} handler : pointer;
  33. {x} end;
  34. {$ENDIF OS2EXCEPTIONS}
  35. {$I heaph.inc}
  36. {Platform specific information}
  37. const
  38. LineEnding = #13#10;
  39. { LFNSupport is defined separately below!!! }
  40. DirectorySeparator = '\';
  41. DriveSeparator = ':';
  42. PathSeparator = ';';
  43. { FileNameCaseSensitive is defined separately below!!! }
  44. {$IFDEF OS2EXCEPTIONS}
  45. {x} System_exception_frame : PEXCEPTION_FRAME =nil;
  46. {$ENDIF OS2EXCEPTIONS}
  47. type Tos=(osDOS,osOS2,osDPMI);
  48. var os_mode:Tos;
  49. type TByteArray = array [0..$ffff] of byte;
  50. PByteArray = ^TByteArray;
  51. TSysThreadIB = record
  52. TID,
  53. Priority,
  54. Version: cardinal;
  55. MCCount,
  56. MCForceFlag: word;
  57. end;
  58. PSysThreadIB = ^TSysThreadIB;
  59. TThreadInfoBlock = record
  60. PExChain,
  61. Stack,
  62. StackLimit: pointer;
  63. TIB2: PSysThreadIB;
  64. Version,
  65. Ordinal: cardinal;
  66. end;
  67. PThreadInfoBlock = ^TThreadInfoBlock;
  68. PPThreadInfoBlock = ^PThreadInfoBlock;
  69. TProcessInfoBlock = record
  70. PID,
  71. ParentPid,
  72. Handle: cardinal;
  73. Cmd,
  74. Env: PByteArray;
  75. Status,
  76. ProcType: cardinal;
  77. end;
  78. PProcessInfoBlock = ^TProcessInfoBlock;
  79. PPProcessInfoBlock = ^PProcessInfoBlock;
  80. const UnusedHandle=$ffff;
  81. StdInputHandle=0;
  82. StdOutputHandle=1;
  83. StdErrorHandle=2;
  84. LFNSupport: boolean = true;
  85. FileNameCaseSensitive: boolean = false;
  86. sLineBreak = LineEnding;
  87. DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsCRLF;
  88. var
  89. { C-compatible arguments and environment }
  90. argc : longint;external name '_argc';
  91. argv : ppchar;external name '_argv';
  92. envp : ppchar;external name '_environ';
  93. EnvC: cardinal; external name '_envc';
  94. (* Pointer to the block of environment variables - used e.g. in unit Dos. *)
  95. Environment: PChar;
  96. var
  97. (* Type / run mode of the current process: *)
  98. (* 0 .. full screen OS/2 session *)
  99. (* 1 .. DOS session *)
  100. (* 2 .. VIO windowable OS/2 session *)
  101. (* 3 .. Presentation Manager OS/2 session *)
  102. (* 4 .. detached (background) OS/2 process *)
  103. ApplicationType: cardinal;
  104. implementation
  105. {$I system.inc}
  106. var
  107. heap_base: pointer; external name '__heap_base';
  108. heap_brk: pointer; external name '__heap_brk';
  109. heap_end: pointer; external name '__heap_end';
  110. (* Maximum heap size - only used if heap is allocated as continuous block. *)
  111. {$IFDEF CONTHEAP}
  112. BrkLimit: cardinal;
  113. {$ENDIF CONTHEAP}
  114. procedure DosGetInfoBlocks (PATIB: PPThreadInfoBlock;
  115. PAPIB: PPProcessInfoBlock); cdecl;
  116. external 'DOSCALLS' index 312;
  117. function DosLoadModule (ObjName: PChar; ObjLen: cardinal; DLLName: PChar;
  118. var Handle: cardinal): longint; cdecl;
  119. external 'DOSCALLS' index 318;
  120. function DosQueryProcAddr (Handle, Ordinal: cardinal; ProcName: PChar;
  121. var Address: pointer): longint; cdecl;
  122. external 'DOSCALLS' index 321;
  123. function DosSetRelMaxFH (var ReqCount, CurMaxFH: longint): longint; cdecl;
  124. external 'DOSCALLS' index 382;
  125. function DosSetCurrentDir (Name:PChar): longint; cdecl;
  126. external 'DOSCALLS' index 255;
  127. procedure DosQueryCurrentDisk(var DiskNum:longint;var Logical:longint); cdecl;
  128. external 'DOSCALLS' index 275;
  129. function DosSetDefaultDisk (DiskNum:longint): longint; cdecl;
  130. external 'DOSCALLS' index 220;
  131. { This is not real prototype, but is close enough }
  132. { for us (the 2nd parameter is actually a pointer }
  133. { to a structure). }
  134. function DosCreateDir( Name : pchar; p : pointer): longint; cdecl;
  135. external 'DOSCALLS' index 270;
  136. function DosDeleteDir( Name : pchar) : longint; cdecl;
  137. external 'DOSCALLS' index 226;
  138. function DosQueryCurrentDir(DiskNum:longint;var Buffer;
  139. var BufLen:longint):longint; cdecl;
  140. external 'DOSCALLS' index 274;
  141. function DosMove(OldFile,NewFile:PChar):longint; cdecl;
  142. external 'DOSCALLS' index 271;
  143. function DosDelete(FileName:PChar):longint; cdecl;
  144. external 'DOSCALLS' index 259;
  145. procedure DosExit(Action, Result: longint); cdecl;
  146. external 'DOSCALLS' index 234;
  147. {This is the correct way to call external assembler procedures.}
  148. procedure syscall; external name '___SYSCALL';
  149. { converts an OS/2 error code to a TP compatible error }
  150. { code. Same thing exists under most other supported }
  151. { systems. }
  152. { Only call for OS/2 DLL imported routines }
  153. Procedure Errno2InOutRes;
  154. Begin
  155. { errors 1..18 are the same as in DOS }
  156. case InOutRes of
  157. { simple offset to convert these error codes }
  158. { exactly like the error codes in Win32 }
  159. 19..31 : InOutRes := InOutRes + 131;
  160. { gets a bit more complicated ... }
  161. 32..33 : InOutRes := 5;
  162. 38 : InOutRes := 100;
  163. 39 : InOutRes := 101;
  164. 112 : InOutRes := 101;
  165. 110 : InOutRes := 5;
  166. 114 : InOutRes := 6;
  167. 290 : InOutRes := 290;
  168. end;
  169. { all other cases ... we keep the same error code }
  170. end;
  171. {$IFDEF OS2EXCEPTIONS}
  172. (*
  173. The operating system defines a class of error conditions called exceptions, and specifies the default actions that are taken when these exceptions occur. The system default action in most cases is to terminate the thread that caused the exception.
  174. Exception values have the following 32-bit format:
  175. 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
  176. 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  177. ÚÄÄÄÂÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
  178. ³Sev³C³ Facility ³ Code ³
  179. ÀÄÄÄÁÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
  180. Sev Severity code. Possible values are described in the following list:
  181. 00 Success
  182. 01 Informational
  183. 10 Warning
  184. 11 Error
  185. C Customer code flag.
  186. Facility Facility code.
  187. Code Facility's status code.
  188. Exceptions that are specific to OS/2 Version 2.X (for example, XCPT_SIGNAL) have a facility code of 1.
  189. System exceptions include both synchronous and asynchronous exceptions. Synchronous exceptions are caused by events that are internal to a thread's execution. For example, synchronous exceptions could be caused by invalid parameters, or by a thread's request to end its own execution.
  190. Asynchronous exceptions are caused by events that are external to a thread's execution. For example, an asynchronous exception can be caused by a user's entering a Ctrl+C or Ctrl+Break key sequence, or by a process' issuing DosKillProcess to end the execution of another process.
  191. The Ctrl+Break and Ctrl+C exceptions are also known as signals, or as signal exceptions.
  192. The following tables show the symbolic names of system exceptions, their numerical values, and related information fields.
  193. Portable, Non-Fatal, Software-Generated Exceptions
  194. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ¿
  195. ³Exception Name ³Value ³
  196. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
  197. ³XCPT_GUARD_PAGE_VIOLATION ³0x80000001³
  198. ³ ExceptionInfo[0] - R/W flag ³ ³
  199. ³ ExceptionInfo[1] - FaultAddr ³ ³
  200. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
  201. ³XCPT_UNABLE_TO_GROW_STACK ³0x80010001³
  202. ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÙ
  203. Portable, Fatal, Hardware-Generated Exceptions
  204. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
  205. ³Exception Name ³Value ³Related Trap ³
  206. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  207. ³XCPT_ACCESS_VIOLATION ³0xC0000005³0x09, 0x0B, ³
  208. ³ ExceptionInfo[0] - Flags ³ ³0x0C, 0x0D, ³
  209. ³ XCPT_UNKNOWN_ACCESS 0x0 ³ ³0x0E ³
  210. ³ XCPT_READ_ACCESS 0x1 ³ ³ ³
  211. ³ XCPT_WRITE_ACCESS 0x2 ³ ³ ³
  212. ³ XCPT_EXECUTE_ACCESS 0x4 ³ ³ ³
  213. ³ XCPT_SPACE_ACCESS 0x8 ³ ³ ³
  214. ³ XCPT_LIMIT_ACCESS 0x10 ³ ³ ³
  215. ³ ExceptionInfo[1] - FaultAddr ³ ³ ³
  216. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  217. ³XCPT_INTEGER_DIVIDE_BY_ZERO ³0xC000009B³0 ³
  218. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  219. ³XCPT_FLOAT_DIVIDE_BY_ZERO ³0xC0000095³0x10 ³
  220. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  221. ³XCPT_FLOAT_INVALID_OPERATION ³0xC0000097³0x10 ³
  222. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  223. ³XCPT_ILLEGAL_INSTRUCTION ³0xC000001C³0x06 ³
  224. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  225. ³XCPT_PRIVILEGED_INSTRUCTION ³0xC000009D³0x0D ³
  226. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  227. ³XCPT_INTEGER_OVERFLOW ³0xC000009C³0x04 ³
  228. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  229. ³XCPT_FLOAT_OVERFLOW ³0xC0000098³0x10 ³
  230. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  231. ³XCPT_FLOAT_UNDERFLOW ³0xC000009A³0x10 ³
  232. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  233. ³XCPT_FLOAT_DENORMAL_OPERAND ³0xC0000094³0x10 ³
  234. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  235. ³XCPT_FLOAT_INEXACT_RESULT ³0xC0000096³0x10 ³
  236. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  237. ³XCPT_FLOAT_STACK_CHECK ³0xC0000099³0x10 ³
  238. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  239. ³XCPT_DATATYPE_MISALIGNMENT ³0xC000009E³0x11 ³
  240. ³ ExceptionInfo[0] - R/W flag ³ ³ ³
  241. ³ ExceptionInfo[1] - Alignment ³ ³ ³
  242. ³ ExceptionInfo[2] - FaultAddr ³ ³ ³
  243. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  244. ³XCPT_BREAKPOINT ³0xC000009F³0x03 ³
  245. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  246. ³XCPT_SINGLE_STEP ³0xC00000A0³0x01 ³
  247. ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
  248. Portable, Fatal, Software-Generated Exceptions
  249. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
  250. ³Exception Name ³Value ³Related Trap ³
  251. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  252. ³XCPT_IN_PAGE_ERROR ³0xC0000006³0x0E ³
  253. ³ ExceptionInfo[0] - FaultAddr ³ ³ ³
  254. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  255. ³XCPT_PROCESS_TERMINATE ³0xC0010001³ ³
  256. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  257. ³XCPT_ASYNC_PROCESS_TERMINATE ³0xC0010002³ ³
  258. ³ ExceptionInfo[0] - TID of ³ ³ ³
  259. ³ terminating thread ³ ³ ³
  260. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  261. ³XCPT_NONCONTINUABLE_EXCEPTION ³0xC0000024³ ³
  262. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  263. ³XCPT_INVALID_DISPOSITION ³0xC0000025³ ³
  264. ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
  265. Non-Portable, Fatal Exceptions
  266. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
  267. ³Exception Name ³Value ³Related Trap ³
  268. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  269. ³XCPT_INVALID_LOCK_SEQUENCE ³0xC000001D³ ³
  270. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  271. ³XCPT_ARRAY_BOUNDS_EXCEEDED ³0xC0000093³0x05 ³
  272. ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
  273. Unwind Operation Exceptions
  274. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ¿
  275. ³Exception Name ³Value ³
  276. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
  277. ³XCPT_UNWIND ³0xC0000026³
  278. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
  279. ³XCPT_BAD_STACK ³0xC0000027³
  280. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
  281. ³XCPT_INVALID_UNWIND_TARGET ³0xC0000028³
  282. ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÙ
  283. Fatal Signal Exceptions
  284. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ¿
  285. ³Exception Name ³Value ³
  286. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
  287. ³XCPT_SIGNAL ³0xC0010003³
  288. ³ ExceptionInfo[ 0 ] - Signal ³ ³
  289. ³ Number ³ ³
  290. ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÙ
  291. *)
  292. {$ENDIF OS2EXCEPTIONS}
  293. {****************************************************************************
  294. Miscellaneous related routines.
  295. ****************************************************************************}
  296. procedure system_exit;
  297. begin
  298. DosExit(1{process}, exitcode);
  299. end;
  300. {$ASMMODE ATT}
  301. function paramcount:longint;assembler;
  302. asm
  303. movl argc,%eax
  304. decl %eax
  305. end ['EAX'];
  306. function args:pointer;assembler;
  307. asm
  308. movl argv,%eax
  309. end ['EAX'];
  310. function paramstr(l:longint):string;
  311. var p:^Pchar;
  312. begin
  313. if L = 0 then
  314. begin
  315. GetMem (P, 260);
  316. p[0] := #0; { in case of error, initialize to empty string }
  317. {$ASMMODE INTEL}
  318. asm
  319. mov edx, P
  320. mov ecx, 260
  321. mov eax, 7F33h
  322. call syscall { error handle already with empty string }
  323. end ['eax', 'ecx', 'edx'];
  324. ParamStr := StrPas (PChar (P));
  325. FreeMem (P, 260);
  326. end
  327. else
  328. if (l>0) and (l<=paramcount) then
  329. begin
  330. p:=args;
  331. paramstr:=strpas(p[l]);
  332. end
  333. else paramstr:='';
  334. end;
  335. procedure randomize; assembler;
  336. asm
  337. mov ah, 2Ch
  338. call syscall
  339. mov word ptr [randseed], cx
  340. mov word ptr [randseed + 2], dx
  341. end ['eax', 'ecx', 'edx'];
  342. {$ASMMODE ATT}
  343. {****************************************************************************
  344. Heap management releated routines.
  345. ****************************************************************************}
  346. { this function allows to extend the heap by calling
  347. syscall $7f00 resizes the brk area}
  348. function sbrk(size:longint):pointer;
  349. {$IFDEF DUMPGROW}
  350. var
  351. L: longword;
  352. begin
  353. WriteLn ('Trying to grow heap by ', Size, ' to ', HeapSize + Size);
  354. {$IFDEF CONTHEAP}
  355. WriteLn ('BrkLimit is ', BrkLimit);
  356. {$ENDIF CONTHEAP}
  357. asm
  358. movl size,%edx
  359. movw $0x7f00,%ax
  360. call syscall { result directly in EAX }
  361. mov %eax,L
  362. end ['eax', 'edx'];
  363. WriteLn ('New heap at ', L);
  364. Sbrk := pointer(L);
  365. end;
  366. {$ELSE DUMPGROW}
  367. assembler;
  368. asm
  369. movl size,%edx
  370. movw $0x7f00,%ax
  371. call syscall { result directly in EAX }
  372. end ['eax', 'edx'];
  373. {$ENDIF DUMPGROW}
  374. function getheapstart:pointer;assembler;
  375. asm
  376. movl heap_base,%eax
  377. end ['EAX'];
  378. function getheapsize:longint;assembler;
  379. asm
  380. movl heap_brk,%eax
  381. end ['EAX'];
  382. {$i heap.inc}
  383. {****************************************************************************
  384. Low Level File Routines
  385. ****************************************************************************}
  386. procedure allowslash(p:Pchar);
  387. {Allow slash as backslash.}
  388. var i:longint;
  389. begin
  390. for i:=0 to strlen(p) do
  391. if p[i]='/' then p[i]:='\';
  392. end;
  393. procedure do_close(h:longint);
  394. begin
  395. { Only three standard handles under real OS/2 }
  396. if h>2 then
  397. begin
  398. asm
  399. pushl %ebx
  400. movb $0x3e,%ah
  401. movl h,%ebx
  402. call syscall
  403. jnc .Lnoerror { error code? }
  404. movw %ax, InOutRes { yes, then set InOutRes }
  405. .Lnoerror:
  406. popl %ebx
  407. end ['eax'];
  408. end;
  409. end;
  410. procedure do_erase(p:Pchar);
  411. begin
  412. allowslash(p);
  413. inoutres:=DosDelete(p);
  414. end;
  415. procedure do_rename(p1,p2:Pchar);
  416. begin
  417. allowslash(p1);
  418. allowslash(p2);
  419. inoutres:=DosMove(p1, p2);
  420. end;
  421. function do_read(h,addr,len:longint):longint; assembler;
  422. asm
  423. movl len,%ecx
  424. movl addr,%edx
  425. movl h,%ebx
  426. movb $0x3f,%ah
  427. call syscall
  428. jnc .LDOSREAD1
  429. movw %ax,inoutres;
  430. xorl %eax,%eax
  431. .LDOSREAD1:
  432. end ['eax', 'ebx', 'ecx', 'edx'];
  433. function do_write(h,addr,len:longint) : longint; assembler;
  434. asm
  435. xorl %eax,%eax
  436. cmpl $0,len { 0 bytes to write is undefined behavior }
  437. jz .LDOSWRITE1
  438. movl len,%ecx
  439. movl addr,%edx
  440. movl h,%ebx
  441. movb $0x40,%ah
  442. call syscall
  443. jnc .LDOSWRITE1
  444. movw %ax,inoutres;
  445. .LDOSWRITE1:
  446. end ['eax', 'ebx', 'ecx', 'edx'];
  447. function do_filepos(handle:longint): longint; assembler;
  448. asm
  449. movw $0x4201,%ax
  450. movl handle,%ebx
  451. xorl %edx,%edx
  452. call syscall
  453. jnc .LDOSFILEPOS
  454. movw %ax,inoutres;
  455. xorl %eax,%eax
  456. .LDOSFILEPOS:
  457. end ['eax', 'ebx', 'ecx', 'edx'];
  458. procedure do_seek(handle,pos:longint); assembler;
  459. asm
  460. movw $0x4200,%ax
  461. movl handle,%ebx
  462. movl pos,%edx
  463. call syscall
  464. jnc .LDOSSEEK1
  465. movw %ax,inoutres;
  466. .LDOSSEEK1:
  467. end ['eax', 'ebx', 'ecx', 'edx'];
  468. function do_seekend(handle:longint):longint; assembler;
  469. asm
  470. movw $0x4202,%ax
  471. movl handle,%ebx
  472. xorl %edx,%edx
  473. call syscall
  474. jnc .Lset_at_end1
  475. movw %ax,inoutres;
  476. xorl %eax,%eax
  477. .Lset_at_end1:
  478. end ['eax', 'ebx', 'ecx', 'edx'];
  479. function do_filesize(handle:longint):longint;
  480. var aktfilepos:longint;
  481. begin
  482. aktfilepos:=do_filepos(handle);
  483. do_filesize:=do_seekend(handle);
  484. do_seek(handle,aktfilepos);
  485. end;
  486. procedure do_truncate(handle,pos:longint); assembler;
  487. asm
  488. (* DOS function 40h isn't safe for this according to EMX documentation *)
  489. movl $0x7F25,%eax
  490. movl Handle,%ebx
  491. movl Pos,%edx
  492. call syscall
  493. incl %eax
  494. movl %ecx, %eax
  495. jnz .LTruncate1 { compare the value of EAX to verify error }
  496. (* File position is undefined after truncation, move to the end. *)
  497. movl $0x4202,%eax
  498. movl Handle,%ebx
  499. movl $0,%edx
  500. call syscall
  501. jnc .LTruncate2
  502. .LTruncate1:
  503. movw %ax,inoutres;
  504. .LTruncate2:
  505. end ['eax', 'ebx', 'ecx', 'edx'];
  506. const
  507. FileHandleCount: longint = 20;
  508. function Increase_File_Handle_Count: boolean;
  509. var Err: word;
  510. L1, L2: longint;
  511. begin
  512. L1 := 10;
  513. if DosSetRelMaxFH (L1, L2) <> 0 then
  514. Increase_File_Handle_Count := false
  515. else
  516. if L2 > FileHandleCount then
  517. begin
  518. FileHandleCount := L2;
  519. Increase_File_Handle_Count := true;
  520. end
  521. else
  522. Increase_File_Handle_Count := false;
  523. end;
  524. procedure do_open(var f;p:pchar;flags:longint);
  525. {
  526. filerec and textrec have both handle and mode as the first items so
  527. they could use the same routine for opening/creating.
  528. when (flags and $100) the file will be append
  529. when (flags and $1000) the file will be truncate/rewritten
  530. when (flags and $10000) there is no check for close (needed for textfiles)
  531. }
  532. var Action: longint;
  533. begin
  534. allowslash(p);
  535. { close first if opened }
  536. if ((flags and $10000)=0) then
  537. begin
  538. case filerec(f).mode of
  539. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  540. fmclosed:;
  541. else
  542. begin
  543. inoutres:=102; {not assigned}
  544. exit;
  545. end;
  546. end;
  547. end;
  548. { reset file handle }
  549. filerec(f).handle := UnusedHandle;
  550. Action := 0;
  551. { convert filemode to filerec modes }
  552. case (flags and 3) of
  553. 0 : filerec(f).mode:=fminput;
  554. 1 : filerec(f).mode:=fmoutput;
  555. 2 : filerec(f).mode:=fminout;
  556. end;
  557. if (flags and $1000)<>0 then
  558. Action := $50000; (* Create / replace *)
  559. { empty name is special }
  560. if p[0]=#0 then
  561. begin
  562. case FileRec(f).mode of
  563. fminput :
  564. FileRec(f).Handle:=StdInputHandle;
  565. fminout, { this is set by rewrite }
  566. fmoutput :
  567. FileRec(f).Handle:=StdOutputHandle;
  568. fmappend :
  569. begin
  570. FileRec(f).Handle:=StdOutputHandle;
  571. FileRec(f).mode:=fmoutput; {fool fmappend}
  572. end;
  573. end;
  574. exit;
  575. end;
  576. Action := Action or (Flags and $FF);
  577. (* DenyNone if sharing not specified. *)
  578. if Flags and 112 = 0 then
  579. Action := Action or 64;
  580. asm
  581. pushl %ebx
  582. movl $0x7f2b, %eax
  583. movl Action, %ecx
  584. movl p, %edx
  585. call syscall
  586. cmpl $0xffffffff, %eax
  587. jnz .LOPEN1
  588. movw %cx, InOutRes
  589. movw UnusedHandle, %ax
  590. .LOPEN1:
  591. movl f,%edx { Warning : This assumes Handle is first }
  592. movw %ax,(%edx) { field of FileRec }
  593. popl %ebx
  594. end ['eax', 'ecx', 'edx'];
  595. if (InOutRes = 4) and Increase_File_Handle_Count then
  596. (* Trying again after increasing amount of file handles *)
  597. asm
  598. movl $0x7f2b, %eax
  599. movl Action, %ecx
  600. movl p, %edx
  601. call syscall
  602. cmpl $0xffffffff, %eax
  603. jnz .LOPEN2
  604. movw %cx, InOutRes
  605. movw UnusedHandle, %ax
  606. .LOPEN2:
  607. movl f,%edx
  608. movw %ax,(%edx)
  609. end ['eax', 'ecx', 'edx'];
  610. { for systems that have more handles }
  611. if FileRec (F).Handle > FileHandleCount then
  612. FileHandleCount := FileRec (F).Handle;
  613. if ((Flags and $100) <> 0) and
  614. (FileRec (F).Handle <> UnusedHandle) then
  615. begin
  616. do_seekend (FileRec (F).Handle);
  617. FileRec (F).Mode := fmOutput; {fool fmappend}
  618. end;
  619. end;
  620. {$ASMMODE INTEL}
  621. function do_isdevice (Handle: longint): boolean; assembler;
  622. (*
  623. var HT, Attr: longint;
  624. begin
  625. if os_mode = osOS2 then
  626. begin
  627. if DosQueryHType (Handle, HT, Attr) <> 0 then HT := 1;
  628. end
  629. else
  630. *)
  631. asm
  632. mov ebx, Handle
  633. mov eax, 4400h
  634. call syscall
  635. mov eax, 1
  636. jc @IsDevEnd
  637. test edx, 80h { verify if it is a file }
  638. jnz @IsDevEnd
  639. dec eax { nope, so result is zero }
  640. @IsDevEnd:
  641. end ['eax', 'ebx', 'edx'];
  642. {$ASMMODE ATT}
  643. {*****************************************************************************
  644. UnTyped File Handling
  645. *****************************************************************************}
  646. {$i file.inc}
  647. {*****************************************************************************
  648. Typed File Handling
  649. *****************************************************************************}
  650. {$i typefile.inc}
  651. {*****************************************************************************
  652. Text File Handling
  653. *****************************************************************************}
  654. {$DEFINE EOF_CTRLZ}
  655. {$i text.inc}
  656. {****************************************************************************
  657. Directory related routines.
  658. ****************************************************************************}
  659. {*****************************************************************************
  660. Directory Handling
  661. *****************************************************************************}
  662. procedure MkDir (const S: string);[IOCHECK];
  663. var buffer:array[0..255] of char;
  664. Rc : word;
  665. begin
  666. If (s='') or (InOutRes <> 0) then
  667. exit;
  668. move(s[1],buffer,length(s));
  669. buffer[length(s)]:=#0;
  670. allowslash(Pchar(@buffer));
  671. Rc := DosCreateDir(buffer,nil);
  672. if Rc <> 0 then
  673. begin
  674. InOutRes := Rc;
  675. Errno2Inoutres;
  676. end;
  677. end;
  678. procedure rmdir(const s : string);[IOCHECK];
  679. var buffer:array[0..255] of char;
  680. Rc : word;
  681. begin
  682. if (s = '.' ) then
  683. InOutRes := 16;
  684. If (s='') or (InOutRes <> 0) then
  685. exit;
  686. move(s[1],buffer,length(s));
  687. buffer[length(s)]:=#0;
  688. allowslash(Pchar(@buffer));
  689. Rc := DosDeleteDir(buffer);
  690. if Rc <> 0 then
  691. begin
  692. InOutRes := Rc;
  693. Errno2Inoutres;
  694. end;
  695. end;
  696. {$ASMMODE INTEL}
  697. procedure ChDir (const S: string);[IOCheck];
  698. var RC: longint;
  699. Buffer: array [0..255] of char;
  700. begin
  701. If (s='') or (InOutRes <> 0) then exit;
  702. if (Length (S) >= 2) and (S [2] = ':') then
  703. begin
  704. RC := DosSetDefaultDisk ((Ord (S [1]) and not ($20)) - $40);
  705. if RC <> 0 then
  706. InOutRes := RC
  707. else
  708. if Length (S) > 2 then
  709. begin
  710. Move (S [1], Buffer, Length (S));
  711. Buffer [Length (S)] := #0;
  712. AllowSlash (PChar (@Buffer));
  713. RC := DosSetCurrentDir (@Buffer);
  714. if RC <> 0 then
  715. begin
  716. InOutRes := RC;
  717. Errno2InOutRes;
  718. end;
  719. end;
  720. end else begin
  721. Move (S [1], Buffer, Length (S));
  722. Buffer [Length (S)] := #0;
  723. AllowSlash (PChar (@Buffer));
  724. RC := DosSetCurrentDir (@Buffer);
  725. if RC <> 0 then
  726. begin
  727. InOutRes:= RC;
  728. Errno2InOutRes;
  729. end;
  730. end;
  731. end;
  732. {$ASMMODE ATT}
  733. procedure GetDir (DriveNr: byte; var Dir: ShortString);
  734. {Written by Michael Van Canneyt.}
  735. var sof: Pchar;
  736. i:byte;
  737. l, l2: Longint;
  738. begin
  739. Dir [4] := #0;
  740. { Used in case the specified drive isn't available }
  741. sof:=pchar(@dir[4]);
  742. { dir[1..3] will contain '[drivenr]:\', but is not }
  743. { supplied by DOS, so we let dos string start at }
  744. { dir[4] }
  745. { Get dir from drivenr : 0=default, 1=A etc... }
  746. l:=255-3;
  747. InOutRes:=DosQueryCurrentDir(DriveNr, sof^, l);
  748. { Now Dir should be filled with directory in ASCIIZ, }
  749. { starting from dir[4] }
  750. dir[0]:=#3;
  751. dir[2]:=':';
  752. dir[3]:='\';
  753. i:=4;
  754. {Conversion to Pascal string }
  755. while (dir[i]<>#0) do
  756. begin
  757. { convert path name to DOS }
  758. if dir[i]='/' then
  759. dir[i]:='\';
  760. dir[0]:=char(i);
  761. inc(i);
  762. end;
  763. { upcase the string (FPC function) }
  764. if drivenr<>0 then { Drive was supplied. We know it }
  765. dir[1]:=chr(64+drivenr)
  766. else
  767. begin
  768. { We need to get the current drive from DOS function 19H }
  769. { because the drive was the default, which can be unknown }
  770. DosQueryCurrentDisk(l, l2);
  771. dir[1]:=chr(64+l);
  772. end;
  773. if not (FileNameCaseSensitive) then dir:=upcase(dir);
  774. end;
  775. {*****************************************************************************
  776. System unit initialization.
  777. ****************************************************************************}
  778. {****************************************************************************
  779. Error Message writing using messageboxes
  780. ****************************************************************************}
  781. type
  782. TWinMessageBox = function (Parent, Owner: cardinal;
  783. BoxText, BoxTitle: PChar; Identity, Style: cardinal): cardinal; cdecl;
  784. TWinInitialize = function (Options: cardinal): cardinal; cdecl;
  785. TWinCreateMsgQueue = function (Handle: cardinal; cmsg: longint): cardinal;
  786. cdecl;
  787. const
  788. ErrorBufferLength = 1024;
  789. mb_OK = $0000;
  790. mb_Error = $0040;
  791. mb_Moveable = $4000;
  792. MBStyle = mb_OK or mb_Error or mb_Moveable;
  793. WinInitialize: TWinInitialize = nil;
  794. WinCreateMsgQueue: TWinCreateMsgQueue = nil;
  795. WinMessageBox: TWinMessageBox = nil;
  796. EnvSize: cardinal = 0;
  797. var
  798. ErrorBuf: array [0..ErrorBufferLength] of char;
  799. ErrorLen: longint;
  800. PMWinHandle: cardinal;
  801. function ErrorWrite (var F: TextRec): integer;
  802. {
  803. An error message should always end with #13#10#13#10
  804. }
  805. var
  806. P: PChar;
  807. I: longint;
  808. begin
  809. if F.BufPos > 0 then
  810. begin
  811. if F.BufPos + ErrorLen > ErrorBufferLength then
  812. I := ErrorBufferLength - ErrorLen
  813. else
  814. I := F.BufPos;
  815. Move (F.BufPtr^, ErrorBuf [ErrorLen], I);
  816. Inc (ErrorLen, I);
  817. ErrorBuf [ErrorLen] := #0;
  818. end;
  819. if ErrorLen > 3 then
  820. begin
  821. P := @ErrorBuf [ErrorLen];
  822. for I := 1 to 4 do
  823. begin
  824. Dec (P);
  825. if not (P^ in [#10, #13]) then
  826. break;
  827. end;
  828. end;
  829. if ErrorLen = ErrorBufferLength then
  830. I := 4;
  831. if (I = 4) then
  832. begin
  833. WinMessageBox (0, 0, @ErrorBuf, PChar ('Error'), 0, MBStyle);
  834. ErrorLen := 0;
  835. end;
  836. F.BufPos := 0;
  837. ErrorWrite := 0;
  838. end;
  839. function ErrorClose (var F: TextRec): integer;
  840. begin
  841. if ErrorLen > 0 then
  842. begin
  843. WinMessageBox (0, 0, @ErrorBuf, PChar ('Error'), 0, MBStyle);
  844. ErrorLen := 0;
  845. end;
  846. ErrorLen := 0;
  847. ErrorClose := 0;
  848. end;
  849. function ErrorOpen (var F: TextRec): integer;
  850. begin
  851. TextRec(F).InOutFunc := @ErrorWrite;
  852. TextRec(F).FlushFunc := @ErrorWrite;
  853. TextRec(F).CloseFunc := @ErrorClose;
  854. ErrorOpen := 0;
  855. end;
  856. procedure AssignError (var T: Text);
  857. begin
  858. Assign (T, '');
  859. TextRec (T).OpenFunc := @ErrorOpen;
  860. Rewrite (T);
  861. end;
  862. procedure SysInitStdIO;
  863. begin
  864. { Setup stdin, stdout and stderr, for GUI apps redirect stderr,stdout to be
  865. displayed in a messagebox }
  866. (*
  867. StdInputHandle := longint(GetStdHandle(cardinal(STD_INPUT_HANDLE)));
  868. StdOutputHandle := longint(GetStdHandle(cardinal(STD_OUTPUT_HANDLE)));
  869. StdErrorHandle := longint(GetStdHandle(cardinal(STD_ERROR_HANDLE)));
  870. if not IsConsole then
  871. begin
  872. if (DosLoadModule (nil, 0, 'PMWIN', PMWinHandle) = 0) and
  873. (DosQueryProcAddr (PMWinHandle, 789, nil, pointer (WinMessageBox)) = 0)
  874. and
  875. (DosQueryProcAddr (PMWinHandle, 763, nil, pointer (WinInitialize)) = 0)
  876. and
  877. (DosQueryProcAddr (PMWinHandle, 716, nil, pointer (WinCreateMsgQueue))
  878. = 0)
  879. then
  880. begin
  881. WinInitialize (0);
  882. WinCreateMsgQueue (0, 0);
  883. end
  884. else
  885. HandleError (2);
  886. AssignError (StdErr);
  887. AssignError (StdOut);
  888. Assign (Output, '');
  889. Assign (Input, '');
  890. end
  891. else
  892. begin
  893. *)
  894. OpenStdIO (Input, fmInput, StdInputHandle);
  895. OpenStdIO (Output, fmOutput, StdOutputHandle);
  896. OpenStdIO (StdOut, fmOutput, StdOutputHandle);
  897. OpenStdIO (StdErr, fmOutput, StdErrorHandle);
  898. (*
  899. end;
  900. *)
  901. end;
  902. function GetFileHandleCount: longint;
  903. var L1, L2: longint;
  904. begin
  905. L1 := 0; (* Don't change the amount, just check. *)
  906. if DosSetRelMaxFH (L1, L2) <> 0 then GetFileHandleCount := 50
  907. else GetFileHandleCount := L2;
  908. end;
  909. var TIB: PThreadInfoBlock;
  910. PIB: PProcessInfoBlock;
  911. begin
  912. IsLibrary := FALSE;
  913. os_mode:=OsOs2;
  914. {$ASMMODE INTEL}
  915. asm
  916. {Enable the brk area by initializing it with the initial heap size.}
  917. mov eax, 7F01h
  918. mov edx, heap_brk
  919. add edx, heap_base
  920. call syscall
  921. cmp eax, -1
  922. jnz @heapok
  923. push dword 204
  924. call HandleError
  925. @heapok:
  926. {$IFDEF CONTHEAP}
  927. { Find out brk limit }
  928. mov eax, 7F02h
  929. mov ecx, 3
  930. call syscall
  931. jcxz @heaplimitknown
  932. mov eax, 0
  933. @heaplimitknown:
  934. mov BrkLimit, eax
  935. {$ELSE CONTHEAP}
  936. { Change sbrk behaviour to allocate arbitrary (non-contiguous) memory blocks }
  937. mov eax, 7F0Fh
  938. mov ecx, 0Ch
  939. mov edx, 8
  940. call syscall
  941. {$ENDIF CONTHEAP}
  942. end;
  943. {Now request, if we are running under DOS,
  944. read-access to the first meg. of memory.}
  945. (* Initialize the amount of file handles *)
  946. FileHandleCount := GetFileHandleCount;
  947. DosGetInfoBlocks (@TIB, @PIB);
  948. StackBottom := cardinal (TIB^.Stack);
  949. Environment := pointer (PIB^.Env);
  950. ApplicationType := PIB^.ProcType;
  951. IsConsole := ApplicationType <> 3;
  952. exitproc:=nil;
  953. {Initialize the heap.}
  954. initheap;
  955. { ... and exceptions }
  956. SysInitExceptions;
  957. { ... and I/O }
  958. SysInitStdIO;
  959. { no I/O-Error }
  960. inoutres:=0;
  961. {$ifdef HASVARIANT}
  962. initvariantmanager;
  963. {$endif HASVARIANT}
  964. {$IFDEF DUMPGROW}
  965. {$IFDEF CONTHEAP}
  966. WriteLn ('Initial brk size is ', GetHeapSize);
  967. WriteLn ('Brk limit is ', BrkLimit);
  968. {$ENDIF CONTHEAP}
  969. {$ENDIF DUMPGROW}
  970. end.
  971. {
  972. $Log$
  973. Revision 1.40 2003-10-07 21:26:35 hajny
  974. * stdcall fixes and asm routines cleanup
  975. Revision 1.39 2003/10/06 16:58:27 yuri
  976. * Another set of native functions.
  977. Revision 1.38 2003/10/06 14:22:40 yuri
  978. * Some emx code removed. Now withous so stupid error as with dos ;)
  979. Revision 1.37 2003/10/04 08:30:59 yuri
  980. * at&t syntax instead of intel syntax was used
  981. Revision 1.36 2003/10/03 21:46:41 peter
  982. * stdcall fixes
  983. Revision 1.35 2003/10/01 18:42:49 yuri
  984. * Unclosed comment
  985. Revision 1.34 2003/09/29 18:39:59 hajny
  986. * append fix applied to GO32v2, OS/2 and EMX
  987. Revision 1.33 2003/09/27 11:52:36 peter
  988. * sbrk returns pointer
  989. Revision 1.32 2003/03/30 09:20:30 hajny
  990. * platform extension unification
  991. Revision 1.31 2003/01/15 22:16:12 hajny
  992. * default sharing mode changed to DenyNone
  993. Revision 1.30 2002/12/15 22:41:41 hajny
  994. * First_Meg fixed + Environment initialization under Dos
  995. Revision 1.29 2002/12/08 16:39:58 hajny
  996. - WriteLn in GUI mode support commented out until fixed
  997. Revision 1.28 2002/12/07 19:17:14 hajny
  998. * GetEnv correction, better PM support, ...
  999. Revision 1.27 2002/11/17 22:31:02 hajny
  1000. * type corrections (longint x cardinal)
  1001. Revision 1.26 2002/10/27 14:29:00 hajny
  1002. * heap management (hopefully) fixed
  1003. Revision 1.25 2002/10/14 19:39:17 peter
  1004. * threads unit added for thread support
  1005. Revision 1.24 2002/10/13 09:28:45 florian
  1006. + call to initvariantmanager inserted
  1007. Revision 1.23 2002/09/07 16:01:25 peter
  1008. * old logs removed and tabs fixed
  1009. Revision 1.22 2002/07/01 16:29:05 peter
  1010. * sLineBreak changed to normal constant like Kylix
  1011. Revision 1.21 2002/04/21 15:54:20 carl
  1012. + initialize some global variables
  1013. Revision 1.20 2002/04/12 17:42:16 carl
  1014. + generic stack checking
  1015. Revision 1.19 2002/03/11 19:10:33 peter
  1016. * Regenerated with updated fpcmake
  1017. Revision 1.18 2002/02/10 13:46:20 hajny
  1018. * heap management corrected (heap_brk)
  1019. }