system.pas 36 KB

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