system.pas 35 KB

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