system.pas 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520
  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. {.$define IODEBUG}
  24. {.$define DEBUGENVIRONMENT}
  25. {.$define DEBUGARGUMENTS}
  26. {$endif SYSTEMDEBUG}
  27. { $DEFINE OS2EXCEPTIONS}
  28. {$I systemh.inc}
  29. {$IFDEF OS2EXCEPTIONS}
  30. (* Types and constants for exception handler support *)
  31. type
  32. {x} PEXCEPTION_FRAME = ^TEXCEPTION_FRAME;
  33. {x} TEXCEPTION_FRAME = record
  34. {x} next : PEXCEPTION_FRAME;
  35. {x} handler : pointer;
  36. {x} end;
  37. {$ENDIF OS2EXCEPTIONS}
  38. {$I heaph.inc}
  39. {Platform specific information}
  40. type
  41. THandle = Longint;
  42. const
  43. LineEnding = #13#10;
  44. { LFNSupport is defined separately below!!! }
  45. DirectorySeparator = '\';
  46. DriveSeparator = ':';
  47. PathSeparator = ';';
  48. { FileNameCaseSensitive is defined separately below!!! }
  49. type Tos=(osDOS,osOS2,osDPMI);
  50. const os_mode: Tos = osOS2;
  51. first_meg: pointer = nil;
  52. {$IFDEF OS2EXCEPTIONS}
  53. {x} System_exception_frame : PEXCEPTION_FRAME =nil;
  54. {$ENDIF OS2EXCEPTIONS}
  55. type TByteArray = array [0..$ffff] of byte;
  56. PByteArray = ^TByteArray;
  57. TSysThreadIB = record
  58. TID,
  59. Priority,
  60. Version: cardinal;
  61. MCCount,
  62. MCForceFlag: word;
  63. end;
  64. PSysThreadIB = ^TSysThreadIB;
  65. TThreadInfoBlock = record
  66. PExChain,
  67. Stack,
  68. StackLimit: pointer;
  69. TIB2: PSysThreadIB;
  70. Version,
  71. Ordinal: cardinal;
  72. end;
  73. PThreadInfoBlock = ^TThreadInfoBlock;
  74. PPThreadInfoBlock = ^PThreadInfoBlock;
  75. TProcessInfoBlock = record
  76. PID,
  77. ParentPid,
  78. Handle: cardinal;
  79. Cmd,
  80. Env: PByteArray;
  81. Status,
  82. ProcType: cardinal;
  83. end;
  84. PProcessInfoBlock = ^TProcessInfoBlock;
  85. PPProcessInfoBlock = ^PProcessInfoBlock;
  86. const UnusedHandle=-1;
  87. StdInputHandle=0;
  88. StdOutputHandle=1;
  89. StdErrorHandle=2;
  90. LFNSupport: boolean = true;
  91. FileNameCaseSensitive: boolean = false;
  92. sLineBreak = LineEnding;
  93. DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsCRLF;
  94. var
  95. { C-compatible arguments and environment }
  96. argc : longint; //external name '_argc';
  97. argv : ppchar; //external name '_argv';
  98. envp : ppchar; //external name '_environ';
  99. EnvC: cardinal; //external name '_envc';
  100. (* Pointer to the block of environment variables - used e.g. in unit Dos. *)
  101. Environment: PChar;
  102. var
  103. (* Type / run mode of the current process: *)
  104. (* 0 .. full screen OS/2 session *)
  105. (* 1 .. DOS session *)
  106. (* 2 .. VIO windowable OS/2 session *)
  107. (* 3 .. Presentation Manager OS/2 session *)
  108. (* 4 .. detached (background) OS/2 process *)
  109. ApplicationType: cardinal;
  110. implementation
  111. {$I system.inc}
  112. //var
  113. // heap_base: pointer; external name '__heap_base';
  114. // heap_brk: pointer; external name '__heap_brk';
  115. // heap_end: pointer; external name '__heap_end';
  116. (* Maximum heap size - only used if heap is allocated as continuous block. *)
  117. {$IFDEF CONTHEAP}
  118. // BrkLimit: cardinal;
  119. {$ENDIF CONTHEAP}
  120. procedure DosGetInfoBlocks (PATIB: PPThreadInfoBlock;
  121. PAPIB: PPProcessInfoBlock); cdecl;
  122. external 'DOSCALLS' index 312;
  123. function DosLoadModule (ObjName: PChar; ObjLen: cardinal; DLLName: PChar;
  124. var Handle: cardinal): cardinal; cdecl;
  125. external 'DOSCALLS' index 318;
  126. function DosQueryProcAddr (Handle, Ordinal: cardinal; ProcName: PChar;
  127. var Address: pointer): cardinal; cdecl;
  128. external 'DOSCALLS' index 321;
  129. function DosSetRelMaxFH (var ReqCount: longint; var CurMaxFH: cardinal):
  130. cardinal; cdecl;
  131. external 'DOSCALLS' index 382;
  132. function DosSetCurrentDir (Name:PChar): cardinal; cdecl;
  133. external 'DOSCALLS' index 255;
  134. procedure DosQueryCurrentDisk(var DiskNum:cardinal;var Logical:cardinal); cdecl;
  135. external 'DOSCALLS' index 275;
  136. function DosSetDefaultDisk (DiskNum:cardinal): cardinal; cdecl;
  137. external 'DOSCALLS' index 220;
  138. { This is not real prototype, but is close enough }
  139. { for us (the 2nd parameter is actually a pointer }
  140. { to a structure). }
  141. function DosCreateDir (Name: PChar; P: pointer): cardinal; cdecl;
  142. external 'DOSCALLS' index 270;
  143. function DosDeleteDir (Name: PChar): cardinal; cdecl;
  144. external 'DOSCALLS' index 226;
  145. function DosQueryCurrentDir(DiskNum:cardinal;var Buffer;
  146. var BufLen:cardinal): cardinal; cdecl;
  147. external 'DOSCALLS' index 274;
  148. function DosMove(OldFile,NewFile:PChar):cardinal; cdecl;
  149. external 'DOSCALLS' index 271;
  150. function DosDelete(FileName:PChar):cardinal; cdecl;
  151. external 'DOSCALLS' index 259;
  152. procedure DosExit(Action, Result: cardinal); cdecl;
  153. external 'DOSCALLS' index 234;
  154. // EAs not used in System unit
  155. function DosOpen(FileName:PChar;var Handle:longint;var Action:cardinal;
  156. InitSize,Attrib,OpenFlags,FileMode:cardinal;
  157. EA:Pointer):longint; cdecl;
  158. external 'DOSCALLS' index 273;
  159. function DosClose(Handle:longint): longint; cdecl;
  160. external 'DOSCALLS' index 257;
  161. function DosRead(Handle:longint; Buffer: Pointer;Count:longint;
  162. var ActCount:longint):longint; cdecl;
  163. external 'DOSCALLS' index 281;
  164. function DosWrite(Handle:longint; Buffer: Pointer;Count:longint;
  165. var ActCount:longint):longint; cdecl;
  166. external 'DOSCALLS' index 282;
  167. function DosSetFilePtr(Handle:longint;Pos:longint;Method:cardinal;
  168. var PosActual:longint):longint; cdecl;
  169. external 'DOSCALLS' index 256;
  170. function DosSetFileSize(Handle:longint;Size:cardinal):longint; cdecl;
  171. external 'DOSCALLS' index 272;
  172. function DosQueryHType(Handle:longint;var HandType:longint;
  173. var Attr:longint):longint; cdecl;
  174. external 'DOSCALLS' index 224;
  175. type
  176. TSysDateTime=packed record
  177. Hour,
  178. Minute,
  179. Second,
  180. Sec100,
  181. Day,
  182. Month: byte;
  183. Year: word;
  184. TimeZone: smallint;
  185. WeekDay: byte;
  186. end;
  187. function DosGetDateTime(var Buf:TSysDateTime):longint; cdecl;
  188. external 'DOSCALLS' index 230;
  189. { converts an OS/2 error code to a TP compatible error }
  190. { code. Same thing exists under most other supported }
  191. { systems. }
  192. { Only call for OS/2 DLL imported routines }
  193. Procedure Errno2InOutRes;
  194. Begin
  195. { errors 1..18 are the same as in DOS }
  196. case InOutRes of
  197. { simple offset to convert these error codes }
  198. { exactly like the error codes in Win32 }
  199. 19..31 : InOutRes := InOutRes + 131;
  200. { gets a bit more complicated ... }
  201. 32..33 : InOutRes := 5;
  202. 38 : InOutRes := 100;
  203. 39 : InOutRes := 101;
  204. 112 : InOutRes := 101;
  205. 110 : InOutRes := 5;
  206. 114 : InOutRes := 6;
  207. 290 : InOutRes := 290;
  208. end;
  209. { all other cases ... we keep the same error code }
  210. end;
  211. {$IFDEF OS2EXCEPTIONS}
  212. (*
  213. 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.
  214. Exception values have the following 32-bit format:
  215. 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
  216. 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
  217. ÚÄÄÄÂÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
  218. ³Sev³C³ Facility ³ Code ³
  219. ÀÄÄÄÁÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
  220. Sev Severity code. Possible values are described in the following list:
  221. 00 Success
  222. 01 Informational
  223. 10 Warning
  224. 11 Error
  225. C Customer code flag.
  226. Facility Facility code.
  227. Code Facility's status code.
  228. Exceptions that are specific to OS/2 Version 2.X (for example, XCPT_SIGNAL) have a facility code of 1.
  229. 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.
  230. 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.
  231. The Ctrl+Break and Ctrl+C exceptions are also known as signals, or as signal exceptions.
  232. The following tables show the symbolic names of system exceptions, their numerical values, and related information fields.
  233. Portable, Non-Fatal, Software-Generated Exceptions
  234. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ¿
  235. ³Exception Name ³Value ³
  236. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
  237. ³XCPT_GUARD_PAGE_VIOLATION ³0x80000001³
  238. ³ ExceptionInfo[0] - R/W flag ³ ³
  239. ³ ExceptionInfo[1] - FaultAddr ³ ³
  240. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
  241. ³XCPT_UNABLE_TO_GROW_STACK ³0x80010001³
  242. ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÙ
  243. Portable, Fatal, Hardware-Generated Exceptions
  244. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
  245. ³Exception Name ³Value ³Related Trap ³
  246. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  247. ³XCPT_ACCESS_VIOLATION ³0xC0000005³0x09, 0x0B, ³
  248. ³ ExceptionInfo[0] - Flags ³ ³0x0C, 0x0D, ³
  249. ³ XCPT_UNKNOWN_ACCESS 0x0 ³ ³0x0E ³
  250. ³ XCPT_READ_ACCESS 0x1 ³ ³ ³
  251. ³ XCPT_WRITE_ACCESS 0x2 ³ ³ ³
  252. ³ XCPT_EXECUTE_ACCESS 0x4 ³ ³ ³
  253. ³ XCPT_SPACE_ACCESS 0x8 ³ ³ ³
  254. ³ XCPT_LIMIT_ACCESS 0x10 ³ ³ ³
  255. ³ ExceptionInfo[1] - FaultAddr ³ ³ ³
  256. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  257. ³XCPT_INTEGER_DIVIDE_BY_ZERO ³0xC000009B³0 ³
  258. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  259. ³XCPT_FLOAT_DIVIDE_BY_ZERO ³0xC0000095³0x10 ³
  260. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  261. ³XCPT_FLOAT_INVALID_OPERATION ³0xC0000097³0x10 ³
  262. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  263. ³XCPT_ILLEGAL_INSTRUCTION ³0xC000001C³0x06 ³
  264. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  265. ³XCPT_PRIVILEGED_INSTRUCTION ³0xC000009D³0x0D ³
  266. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  267. ³XCPT_INTEGER_OVERFLOW ³0xC000009C³0x04 ³
  268. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  269. ³XCPT_FLOAT_OVERFLOW ³0xC0000098³0x10 ³
  270. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  271. ³XCPT_FLOAT_UNDERFLOW ³0xC000009A³0x10 ³
  272. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  273. ³XCPT_FLOAT_DENORMAL_OPERAND ³0xC0000094³0x10 ³
  274. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  275. ³XCPT_FLOAT_INEXACT_RESULT ³0xC0000096³0x10 ³
  276. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  277. ³XCPT_FLOAT_STACK_CHECK ³0xC0000099³0x10 ³
  278. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  279. ³XCPT_DATATYPE_MISALIGNMENT ³0xC000009E³0x11 ³
  280. ³ ExceptionInfo[0] - R/W flag ³ ³ ³
  281. ³ ExceptionInfo[1] - Alignment ³ ³ ³
  282. ³ ExceptionInfo[2] - FaultAddr ³ ³ ³
  283. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  284. ³XCPT_BREAKPOINT ³0xC000009F³0x03 ³
  285. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  286. ³XCPT_SINGLE_STEP ³0xC00000A0³0x01 ³
  287. ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
  288. Portable, Fatal, Software-Generated Exceptions
  289. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
  290. ³Exception Name ³Value ³Related Trap ³
  291. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  292. ³XCPT_IN_PAGE_ERROR ³0xC0000006³0x0E ³
  293. ³ ExceptionInfo[0] - FaultAddr ³ ³ ³
  294. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  295. ³XCPT_PROCESS_TERMINATE ³0xC0010001³ ³
  296. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  297. ³XCPT_ASYNC_PROCESS_TERMINATE ³0xC0010002³ ³
  298. ³ ExceptionInfo[0] - TID of ³ ³ ³
  299. ³ terminating thread ³ ³ ³
  300. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  301. ³XCPT_NONCONTINUABLE_EXCEPTION ³0xC0000024³ ³
  302. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  303. ³XCPT_INVALID_DISPOSITION ³0xC0000025³ ³
  304. ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
  305. Non-Portable, Fatal Exceptions
  306. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
  307. ³Exception Name ³Value ³Related Trap ³
  308. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  309. ³XCPT_INVALID_LOCK_SEQUENCE ³0xC000001D³ ³
  310. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ´
  311. ³XCPT_ARRAY_BOUNDS_EXCEEDED ³0xC0000093³0x05 ³
  312. ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
  313. Unwind Operation Exceptions
  314. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ¿
  315. ³Exception Name ³Value ³
  316. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
  317. ³XCPT_UNWIND ³0xC0000026³
  318. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
  319. ³XCPT_BAD_STACK ³0xC0000027³
  320. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
  321. ³XCPT_INVALID_UNWIND_TARGET ³0xC0000028³
  322. ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÙ
  323. Fatal Signal Exceptions
  324. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ¿
  325. ³Exception Name ³Value ³
  326. ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
  327. ³XCPT_SIGNAL ³0xC0010003³
  328. ³ ExceptionInfo[ 0 ] - Signal ³ ³
  329. ³ Number ³ ³
  330. ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÙ
  331. *)
  332. {$ENDIF OS2EXCEPTIONS}
  333. {****************************************************************************
  334. Miscellaneous related routines.
  335. ****************************************************************************}
  336. procedure system_exit;
  337. begin
  338. DosExit(1{process}, exitcode);
  339. end;
  340. {$ASMMODE ATT}
  341. function paramcount:longint;assembler;
  342. asm
  343. movl argc,%eax
  344. decl %eax
  345. end {['EAX']};
  346. function args:pointer;assembler;
  347. asm
  348. movl argv,%eax
  349. end {['EAX']};
  350. function paramstr(l:longint):string;
  351. var p:^Pchar;
  352. begin
  353. if (l>=0) and (l<=paramcount) then
  354. begin
  355. p:=args;
  356. paramstr:=strpas(p[l]);
  357. end
  358. else paramstr:='';
  359. end;
  360. procedure randomize;
  361. var
  362. dt: TSysDateTime;
  363. begin
  364. // Hmm... Lets use timer
  365. DosGetDateTime(dt);
  366. randseed:=dt.hour+(dt.minute shl 8)+(dt.second shl 16)+(dt.sec100 shl 32);
  367. end;
  368. {$ASMMODE ATT}
  369. {****************************************************************************
  370. Heap management releated routines.
  371. ****************************************************************************}
  372. {Get some memory.
  373. P = Pointer to memory will be returned here.
  374. Size = Number of bytes to get. The size is rounded up to a multiple
  375. of 4096. This is probably not the case on non-intel 386
  376. versions of OS/2.
  377. Flags = One or more of the mfXXXX constants.}
  378. function DosAllocMem(var P:pointer;Size,Flag:cardinal):longint; cdecl;
  379. external 'DOSCALLS' index 299;
  380. function DosSetMem(P:pointer;Size,Flag:cardinal):longint; cdecl;
  381. external 'DOSCALLS' index 305;
  382. var
  383. int_heap: pointer;
  384. int_heap_end: pointer;
  385. function sbrk(size:longint):pointer;
  386. var
  387. p: pointer;
  388. rc: longint;
  389. begin
  390. {$IFDEF DUMPGROW}
  391. WriteLn ('Trying to grow heap by ', Size, ' to ', HeapSize + Size);
  392. {$ENDIF}
  393. p:=int_heap_end;
  394. // commit memory
  395. rc:=DosSetMem(p, size, $10+3);
  396. if rc<>0 then p:=nil;
  397. {$IFDEF DUMPGROW}
  398. WriteLn ('New heap at ', Cardinal(p));
  399. {$ENDIF}
  400. sbrk:=int_heap_end;
  401. inc(int_heap_end, size);
  402. end;
  403. function getheapstart:pointer;
  404. begin
  405. getheapstart:=int_heap;
  406. end;
  407. function getheapsize:longint;
  408. begin
  409. getheapsize:=longint(int_heap_end)-longint(int_heap);
  410. end;
  411. {$i heap.inc}
  412. {****************************************************************************
  413. Low Level File Routines
  414. ****************************************************************************}
  415. procedure allowslash(p:Pchar);
  416. {Allow slash as backslash.}
  417. var i:longint;
  418. begin
  419. for i:=0 to strlen(p) do
  420. if p[i]='/' then p[i]:='\';
  421. end;
  422. procedure do_close(h:longint);
  423. begin
  424. { Only three standard handles under real OS/2 }
  425. if h>2 then
  426. begin
  427. InOutRes:=DosClose(h);
  428. end;
  429. {$ifdef IODEBUG}
  430. writeln('do_close: handle=', H, ', InOutRes=', InOutRes);
  431. {$endif}
  432. end;
  433. procedure do_erase(p:Pchar);
  434. begin
  435. allowslash(p);
  436. inoutres:=DosDelete(p);
  437. end;
  438. procedure do_rename(p1,p2:Pchar);
  439. begin
  440. allowslash(p1);
  441. allowslash(p2);
  442. inoutres:=DosMove(p1, p2);
  443. end;
  444. function do_read(h,addr,len:longint):longint;
  445. Var
  446. T: Longint;
  447. begin
  448. {$ifdef IODEBUG}
  449. write('do_read: handle=', h, ', addr=', addr, ', length=', len);
  450. {$endif}
  451. InOutRes:=DosRead(H, Pointer(Addr), Len, T);
  452. do_read:=T;
  453. {$ifdef IODEBUG}
  454. writeln(', actual_len=', t, ', InOutRes=', InOutRes);
  455. {$endif}
  456. end;
  457. function do_write(h,addr,len:longint) : longint;
  458. Var
  459. T: Longint;
  460. begin
  461. {$ifdef IODEBUG}
  462. write('do_write: handle=', h, ', addr=', addr, ', length=', len);
  463. {$endif}
  464. InOutRes:=DosWrite(H, Pointer(Addr), Len, T);
  465. do_write:=T;
  466. {$ifdef IODEBUG}
  467. writeln(', actual_len=', t, ', InOutRes=', InOutRes);
  468. {$endif}
  469. end;
  470. function do_filepos(handle:longint): longint;
  471. var
  472. PosActual: Longint;
  473. begin
  474. InOutRes:=DosSetFilePtr(Handle, 0, 1, PosActual);
  475. do_filepos:=PosActual;
  476. {$ifdef IODEBUG}
  477. writeln('do_filepos: handle=', Handle, ', actual_pos=', PosActual, ', InOutRes=', InOutRes);
  478. {$endif}
  479. end;
  480. procedure do_seek(handle,pos:longint);
  481. var
  482. PosActual: Longint;
  483. begin
  484. InOutRes:=DosSetFilePtr(Handle, Pos, 0 {ZeroBased}, PosActual);
  485. {$ifdef IODEBUG}
  486. writeln('do_seek: handle=', Handle, ', pos=', pos, ', actual_pos=', PosActual, ', InOutRes=', InOutRes);
  487. {$endif}
  488. end;
  489. function do_seekend(handle:longint):longint;
  490. var
  491. PosActual: Longint;
  492. begin
  493. InOutRes:=DosSetFilePtr(Handle, 0, 2 {EndBased}, PosActual);
  494. do_seekend:=PosActual;
  495. {$ifdef IODEBUG}
  496. writeln('do_seekend: handle=', Handle, ', actual_pos=', PosActual, ', InOutRes=', InOutRes);
  497. {$endif}
  498. end;
  499. function do_filesize(handle:longint):longint;
  500. var aktfilepos:longint;
  501. begin
  502. aktfilepos:=do_filepos(handle);
  503. do_filesize:=do_seekend(handle);
  504. do_seek(handle,aktfilepos);
  505. end;
  506. procedure do_truncate(handle,pos:longint);
  507. begin
  508. InOutRes:=DosSetFileSize(Handle, Pos);
  509. do_seekend(handle);
  510. end;
  511. const
  512. FileHandleCount: cardinal = 20;
  513. function Increase_File_Handle_Count: boolean;
  514. var Err: word;
  515. L1: longint;
  516. L2: cardinal;
  517. begin
  518. L1 := 10;
  519. if DosSetRelMaxFH (L1, L2) <> 0 then
  520. Increase_File_Handle_Count := false
  521. else
  522. if L2 > FileHandleCount then
  523. begin
  524. FileHandleCount := L2;
  525. Increase_File_Handle_Count := true;
  526. end
  527. else
  528. Increase_File_Handle_Count := false;
  529. end;
  530. procedure do_open(var f;p:pchar;flags:longint);
  531. {
  532. filerec and textrec have both handle and mode as the first items so
  533. they could use the same routine for opening/creating.
  534. when (flags and $100) the file will be append
  535. when (flags and $1000) the file will be truncate/rewritten
  536. when (flags and $10000) there is no check for close (needed for textfiles)
  537. }
  538. var
  539. Action, Attrib, OpenFlags, FM: Cardinal;
  540. begin
  541. // convert unix slashes to normal slashes
  542. allowslash(p);
  543. // close first if opened
  544. if ((flags and $10000)=0) then
  545. begin
  546. case filerec(f).mode of
  547. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  548. fmclosed:;
  549. else
  550. begin
  551. inoutres:=102; {not assigned}
  552. exit;
  553. end;
  554. end;
  555. end;
  556. // reset file handle
  557. filerec(f).handle := UnusedHandle;
  558. Attrib:=0;
  559. OpenFlags:=0;
  560. // convert filesharing
  561. FM := Flags and $FF and not (8);
  562. (* DenyNone if sharing not specified. *)
  563. if FM and 112 = 0 then
  564. FM := FM or 64;
  565. // convert filemode to filerec modes and access mode
  566. case (FM and 3) of
  567. 0: filerec(f).mode:=fminput;
  568. 1: filerec(f).mode:=fmoutput;
  569. 2: filerec(f).mode:=fminout;
  570. end;
  571. if (flags and $1000)<>0 then
  572. OpenFlags:=OpenFlags or 2 {doOverwrite} or 16 {doCreate} // Create/overwrite
  573. else
  574. OpenFlags:=OpenFlags or 1 {doOpen}; // Open existing
  575. // Handle Std I/O
  576. if p[0]=#0 then
  577. begin
  578. case FileRec(f).mode of
  579. fminput :
  580. FileRec(f).Handle:=StdInputHandle;
  581. fminout, // this is set by rewrite
  582. fmoutput :
  583. FileRec(f).Handle:=StdOutputHandle;
  584. fmappend :
  585. begin
  586. FileRec(f).Handle:=StdOutputHandle;
  587. FileRec(f).mode:=fmoutput; // fool fmappend
  588. end;
  589. end;
  590. exit;
  591. end;
  592. Attrib:=32 {faArchive};
  593. InOutRes:=DosOpen(p, FileRec(F).Handle, Action, 0, Attrib, OpenFlags, FM, nil);
  594. // If too many open files try to set more file handles and open again
  595. if (InOutRes = 4) then
  596. if Increase_File_Handle_Count then
  597. InOutRes:=DosOpen(p, FileRec(F).Handle, Action, 0, Attrib, OpenFlags, FM, nil);
  598. If InOutRes<>0 then FileRec(F).Handle:=UnusedHandle;
  599. // If Handle created -> make some things
  600. if (FileRec(F).Handle <> UnusedHandle) then
  601. begin
  602. // Move to end of file for Append command
  603. if ((Flags and $100) <> 0) then
  604. begin
  605. do_seekend(FileRec(F).Handle);
  606. FileRec(F).Mode := fmOutput;
  607. end;
  608. end;
  609. {$ifdef IODEBUG}
  610. writeln('do_open,', filerec(f).handle, ',', filerec(f).name, ',', filerec(f).mode, ', InOutRes=', InOutRes);
  611. {$endif}
  612. end;
  613. function do_isdevice (Handle: longint): boolean;
  614. var
  615. HT, Attr: longint;
  616. begin
  617. do_isdevice:=false;
  618. If DosQueryHType(Handle, HT, Attr)<>0 then exit;
  619. if ht=1 then do_isdevice:=true;
  620. end;
  621. {$ASMMODE ATT}
  622. {*****************************************************************************
  623. UnTyped File Handling
  624. *****************************************************************************}
  625. {$i file.inc}
  626. {*****************************************************************************
  627. Typed File Handling
  628. *****************************************************************************}
  629. {$i typefile.inc}
  630. {*****************************************************************************
  631. Text File Handling
  632. *****************************************************************************}
  633. {$DEFINE EOF_CTRLZ}
  634. {$i text.inc}
  635. {****************************************************************************
  636. Directory related routines.
  637. ****************************************************************************}
  638. {*****************************************************************************
  639. Directory Handling
  640. *****************************************************************************}
  641. procedure MkDir (const S: string);[IOCHECK];
  642. var buffer:array[0..255] of char;
  643. Rc : word;
  644. begin
  645. If (s='') or (InOutRes <> 0) then
  646. exit;
  647. move(s[1],buffer,length(s));
  648. buffer[length(s)]:=#0;
  649. allowslash(Pchar(@buffer));
  650. Rc := DosCreateDir(buffer,nil);
  651. if Rc <> 0 then
  652. begin
  653. InOutRes := Rc;
  654. Errno2Inoutres;
  655. end;
  656. end;
  657. procedure rmdir(const s : string);[IOCHECK];
  658. var buffer:array[0..255] of char;
  659. Rc : word;
  660. begin
  661. if (s = '.' ) then
  662. InOutRes := 16;
  663. If (s='') or (InOutRes <> 0) then
  664. exit;
  665. move(s[1],buffer,length(s));
  666. buffer[length(s)]:=#0;
  667. allowslash(Pchar(@buffer));
  668. Rc := DosDeleteDir(buffer);
  669. if Rc <> 0 then
  670. begin
  671. InOutRes := Rc;
  672. Errno2Inoutres;
  673. end;
  674. end;
  675. {$ASMMODE INTEL}
  676. procedure ChDir (const S: string);[IOCheck];
  677. var RC: cardinal;
  678. Buffer: array [0..255] of char;
  679. begin
  680. If (s='') or (InOutRes <> 0) then exit;
  681. if (Length (S) >= 2) and (S [2] = ':') then
  682. begin
  683. RC := DosSetDefaultDisk ((Ord (S [1]) and not ($20)) - $40);
  684. if RC <> 0 then
  685. InOutRes := RC
  686. else
  687. if Length (S) > 2 then
  688. begin
  689. Move (S [1], Buffer, Length (S));
  690. Buffer [Length (S)] := #0;
  691. AllowSlash (PChar (@Buffer));
  692. RC := DosSetCurrentDir (@Buffer);
  693. if RC <> 0 then
  694. begin
  695. InOutRes := RC;
  696. Errno2InOutRes;
  697. end;
  698. end;
  699. end else begin
  700. Move (S [1], Buffer, Length (S));
  701. Buffer [Length (S)] := #0;
  702. AllowSlash (PChar (@Buffer));
  703. RC := DosSetCurrentDir (@Buffer);
  704. if RC <> 0 then
  705. begin
  706. InOutRes:= RC;
  707. Errno2InOutRes;
  708. end;
  709. end;
  710. end;
  711. {$ASMMODE ATT}
  712. procedure GetDir (DriveNr: byte; var Dir: ShortString);
  713. {Written by Michael Van Canneyt.}
  714. var sof: Pchar;
  715. i:byte;
  716. l,l2:cardinal;
  717. begin
  718. Dir [4] := #0;
  719. { Used in case the specified drive isn't available }
  720. sof:=pchar(@dir[4]);
  721. { dir[1..3] will contain '[drivenr]:\', but is not }
  722. { supplied by DOS, so we let dos string start at }
  723. { dir[4] }
  724. { Get dir from drivenr : 0=default, 1=A etc... }
  725. l:=255-3;
  726. InOutRes:=longint (DosQueryCurrentDir(DriveNr, sof^, l));
  727. {$WARNING Result code should be translated in some cases!}
  728. { Now Dir should be filled with directory in ASCIIZ, }
  729. { starting from dir[4] }
  730. dir[0]:=#3;
  731. dir[2]:=':';
  732. dir[3]:='\';
  733. i:=4;
  734. {Conversion to Pascal string }
  735. while (dir[i]<>#0) do
  736. begin
  737. { convert path name to DOS }
  738. if dir[i]='/' then
  739. dir[i]:='\';
  740. dir[0]:=char(i);
  741. inc(i);
  742. end;
  743. { upcase the string (FPC function) }
  744. if drivenr<>0 then { Drive was supplied. We know it }
  745. dir[1]:=chr(64+drivenr)
  746. else
  747. begin
  748. { We need to get the current drive from DOS function 19H }
  749. { because the drive was the default, which can be unknown }
  750. DosQueryCurrentDisk(l, l2);
  751. dir[1]:=chr(64+l);
  752. end;
  753. if not (FileNameCaseSensitive) then dir:=upcase(dir);
  754. end;
  755. {*****************************************************************************
  756. System unit initialization.
  757. ****************************************************************************}
  758. {****************************************************************************
  759. Error Message writing using messageboxes
  760. ****************************************************************************}
  761. type
  762. TWinMessageBox = function (Parent, Owner: cardinal;
  763. BoxText, BoxTitle: PChar; Identity, Style: cardinal): cardinal; cdecl;
  764. TWinInitialize = function (Options: cardinal): cardinal; cdecl;
  765. TWinCreateMsgQueue = function (Handle: cardinal; cmsg: longint): cardinal;
  766. cdecl;
  767. const
  768. ErrorBufferLength = 1024;
  769. mb_OK = $0000;
  770. mb_Error = $0040;
  771. mb_Moveable = $4000;
  772. MBStyle = mb_OK or mb_Error or mb_Moveable;
  773. WinInitialize: TWinInitialize = nil;
  774. WinCreateMsgQueue: TWinCreateMsgQueue = nil;
  775. WinMessageBox: TWinMessageBox = nil;
  776. EnvSize: cardinal = 0;
  777. var
  778. ErrorBuf: array [0..ErrorBufferLength] of char;
  779. ErrorLen: longint;
  780. PMWinHandle: cardinal;
  781. function ErrorWrite (var F: TextRec): integer;
  782. {
  783. An error message should always end with #13#10#13#10
  784. }
  785. var
  786. P: PChar;
  787. I: longint;
  788. begin
  789. if F.BufPos > 0 then
  790. begin
  791. if F.BufPos + ErrorLen > ErrorBufferLength then
  792. I := ErrorBufferLength - ErrorLen
  793. else
  794. I := F.BufPos;
  795. Move (F.BufPtr^, ErrorBuf [ErrorLen], I);
  796. Inc (ErrorLen, I);
  797. ErrorBuf [ErrorLen] := #0;
  798. end;
  799. if ErrorLen > 3 then
  800. begin
  801. P := @ErrorBuf [ErrorLen];
  802. for I := 1 to 4 do
  803. begin
  804. Dec (P);
  805. if not (P^ in [#10, #13]) then
  806. break;
  807. end;
  808. end;
  809. if ErrorLen = ErrorBufferLength then
  810. I := 4;
  811. if (I = 4) then
  812. begin
  813. WinMessageBox (0, 0, @ErrorBuf, PChar ('Error'), 0, MBStyle);
  814. ErrorLen := 0;
  815. end;
  816. F.BufPos := 0;
  817. ErrorWrite := 0;
  818. end;
  819. function ErrorClose (var F: TextRec): integer;
  820. begin
  821. if ErrorLen > 0 then
  822. begin
  823. WinMessageBox (0, 0, @ErrorBuf, PChar ('Error'), 0, MBStyle);
  824. ErrorLen := 0;
  825. end;
  826. ErrorLen := 0;
  827. ErrorClose := 0;
  828. end;
  829. function ErrorOpen (var F: TextRec): integer;
  830. begin
  831. TextRec(F).InOutFunc := @ErrorWrite;
  832. TextRec(F).FlushFunc := @ErrorWrite;
  833. TextRec(F).CloseFunc := @ErrorClose;
  834. ErrorOpen := 0;
  835. end;
  836. procedure AssignError (var T: Text);
  837. begin
  838. Assign (T, '');
  839. TextRec (T).OpenFunc := @ErrorOpen;
  840. Rewrite (T);
  841. end;
  842. procedure SysInitStdIO;
  843. begin
  844. { Setup stdin, stdout and stderr, for GUI apps redirect stderr,stdout to be
  845. displayed in a messagebox }
  846. (*
  847. StdInputHandle := longint(GetStdHandle(cardinal(STD_INPUT_HANDLE)));
  848. StdOutputHandle := longint(GetStdHandle(cardinal(STD_OUTPUT_HANDLE)));
  849. StdErrorHandle := longint(GetStdHandle(cardinal(STD_ERROR_HANDLE)));
  850. if not IsConsole then
  851. begin
  852. if (DosLoadModule (nil, 0, 'PMWIN', PMWinHandle) = 0) and
  853. (DosQueryProcAddr (PMWinHandle, 789, nil, pointer (WinMessageBox)) = 0)
  854. and
  855. (DosQueryProcAddr (PMWinHandle, 763, nil, pointer (WinInitialize)) = 0)
  856. and
  857. (DosQueryProcAddr (PMWinHandle, 716, nil, pointer (WinCreateMsgQueue))
  858. = 0)
  859. then
  860. begin
  861. WinInitialize (0);
  862. WinCreateMsgQueue (0, 0);
  863. end
  864. else
  865. HandleError (2);
  866. AssignError (StdErr);
  867. AssignError (StdOut);
  868. Assign (Output, '');
  869. Assign (Input, '');
  870. end
  871. else
  872. begin
  873. *)
  874. OpenStdIO (Input, fmInput, StdInputHandle);
  875. OpenStdIO (Output, fmOutput, StdOutputHandle);
  876. OpenStdIO (StdOut, fmOutput, StdOutputHandle);
  877. OpenStdIO (StdErr, fmOutput, StdErrorHandle);
  878. (*
  879. end;
  880. *)
  881. end;
  882. function strcopy(dest,source : pchar) : pchar;assembler;
  883. asm
  884. pushl %esi
  885. pushl %edi
  886. cld
  887. movl 12(%ebp),%edi
  888. movl $0xffffffff,%ecx
  889. xorb %al,%al
  890. repne
  891. scasb
  892. not %ecx
  893. movl 8(%ebp),%edi
  894. movl 12(%ebp),%esi
  895. movl %ecx,%eax
  896. shrl $2,%ecx
  897. rep
  898. movsl
  899. movl %eax,%ecx
  900. andl $3,%ecx
  901. rep
  902. movsb
  903. movl 8(%ebp),%eax
  904. popl %edi
  905. popl %esi
  906. end;
  907. procedure InitEnvironment;
  908. var env_count : longint;
  909. dos_env,cp : pchar;
  910. begin
  911. env_count:=0;
  912. cp:=environment;
  913. while cp ^ <> #0 do
  914. begin
  915. inc(env_count);
  916. while (cp^ <> #0) do inc(longint(cp)); { skip to NUL }
  917. inc(longint(cp)); { skip to next character }
  918. end;
  919. envp := sysgetmem((env_count+1) * sizeof(pchar));
  920. envc := env_count;
  921. if (envp = nil) then exit;
  922. cp:=environment;
  923. env_count:=0;
  924. while cp^ <> #0 do
  925. begin
  926. envp[env_count] := sysgetmem(strlen(cp)+1);
  927. strcopy(envp[env_count], cp);
  928. {$IfDef DEBUGENVIRONMENT}
  929. Writeln(stderr,'env ',env_count,' = "',envp[env_count],'"');
  930. {$EndIf}
  931. inc(env_count);
  932. while (cp^ <> #0) do
  933. inc(longint(cp)); { skip to NUL }
  934. inc(longint(cp)); { skip to next character }
  935. end;
  936. envp[env_count]:=nil;
  937. end;
  938. procedure InitArguments;
  939. var
  940. arglen,
  941. count : longint;
  942. argstart,
  943. pc,arg : pchar;
  944. quote : char;
  945. argvlen : longint;
  946. procedure allocarg(idx,len:longint);
  947. begin
  948. if idx>=argvlen then
  949. begin
  950. argvlen:=(idx+8) and (not 7);
  951. sysreallocmem(argv,argvlen*sizeof(pointer));
  952. end;
  953. { use realloc to reuse already existing memory }
  954. { always allocate, even if length is zero, since }
  955. { the arg. is still present! }
  956. sysreallocmem(argv[idx],len+1);
  957. end;
  958. begin
  959. count:=0;
  960. argv:=nil;
  961. argvlen:=0;
  962. // Get argv[0]
  963. pc:=cmdline;
  964. Arglen:=0;
  965. repeat
  966. Inc(Arglen);
  967. until (pc[Arglen]=#0);
  968. allocarg(count,arglen);
  969. move(pc^,argv[count]^,arglen);
  970. { ReSetup cmdline variable }
  971. repeat
  972. Inc(Arglen);
  973. until (pc[Arglen]=#0);
  974. Inc(Arglen);
  975. pc:=GetMem(ArgLen);
  976. move(cmdline^, pc^, arglen);
  977. Arglen:=0;
  978. repeat
  979. Inc(Arglen);
  980. until (pc[Arglen]=#0);
  981. pc[Arglen]:=' '; // combine argv[0] and command line
  982. CmdLine:=pc;
  983. { process arguments }
  984. pc:=cmdline;
  985. {$IfDef DEBUGARGUMENTS}
  986. Writeln(stderr,'GetCommandLine is #',pc,'#');
  987. {$EndIf }
  988. while pc^<>#0 do
  989. begin
  990. { skip leading spaces }
  991. while pc^ in [#1..#32] do
  992. inc(pc);
  993. if pc^=#0 then
  994. break;
  995. { calc argument length }
  996. quote:=' ';
  997. argstart:=pc;
  998. arglen:=0;
  999. while (pc^<>#0) do
  1000. begin
  1001. case pc^ of
  1002. #1..#32 :
  1003. begin
  1004. if quote<>' ' then
  1005. inc(arglen)
  1006. else
  1007. break;
  1008. end;
  1009. '"' :
  1010. begin
  1011. if quote<>'''' then
  1012. begin
  1013. if pchar(pc+1)^<>'"' then
  1014. begin
  1015. if quote='"' then
  1016. quote:=' '
  1017. else
  1018. quote:='"';
  1019. end
  1020. else
  1021. inc(pc);
  1022. end
  1023. else
  1024. inc(arglen);
  1025. end;
  1026. '''' :
  1027. begin
  1028. if quote<>'"' then
  1029. begin
  1030. if pchar(pc+1)^<>'''' then
  1031. begin
  1032. if quote='''' then
  1033. quote:=' '
  1034. else
  1035. quote:='''';
  1036. end
  1037. else
  1038. inc(pc);
  1039. end
  1040. else
  1041. inc(arglen);
  1042. end;
  1043. else
  1044. inc(arglen);
  1045. end;
  1046. inc(pc);
  1047. end;
  1048. { copy argument }
  1049. { Don't copy the first one, it is already there.}
  1050. If Count<>0 then
  1051. begin
  1052. allocarg(count,arglen);
  1053. quote:=' ';
  1054. pc:=argstart;
  1055. arg:=argv[count];
  1056. while (pc^<>#0) do
  1057. begin
  1058. case pc^ of
  1059. #1..#32 :
  1060. begin
  1061. if quote<>' ' then
  1062. begin
  1063. arg^:=pc^;
  1064. inc(arg);
  1065. end
  1066. else
  1067. break;
  1068. end;
  1069. '"' :
  1070. begin
  1071. if quote<>'''' then
  1072. begin
  1073. if pchar(pc+1)^<>'"' then
  1074. begin
  1075. if quote='"' then
  1076. quote:=' '
  1077. else
  1078. quote:='"';
  1079. end
  1080. else
  1081. inc(pc);
  1082. end
  1083. else
  1084. begin
  1085. arg^:=pc^;
  1086. inc(arg);
  1087. end;
  1088. end;
  1089. '''' :
  1090. begin
  1091. if quote<>'"' then
  1092. begin
  1093. if pchar(pc+1)^<>'''' then
  1094. begin
  1095. if quote='''' then
  1096. quote:=' '
  1097. else
  1098. quote:='''';
  1099. end
  1100. else
  1101. inc(pc);
  1102. end
  1103. else
  1104. begin
  1105. arg^:=pc^;
  1106. inc(arg);
  1107. end;
  1108. end;
  1109. else
  1110. begin
  1111. arg^:=pc^;
  1112. inc(arg);
  1113. end;
  1114. end;
  1115. inc(pc);
  1116. end;
  1117. arg^:=#0;
  1118. end;
  1119. {$IfDef DEBUGARGUMENTS}
  1120. Writeln(stderr,'dos arg ',count,' #',arglen,'#',argv[count],'#');
  1121. {$EndIf}
  1122. inc(count);
  1123. end;
  1124. { get argc and create an nil entry }
  1125. argc:=count;
  1126. allocarg(argc,0);
  1127. { free unused memory }
  1128. sysreallocmem(argv,(argc+1)*sizeof(pointer));
  1129. end;
  1130. function GetFileHandleCount: longint;
  1131. var L1: longint;
  1132. L2: cardinal;
  1133. begin
  1134. L1 := 0; (* Don't change the amount, just check. *)
  1135. if DosSetRelMaxFH (L1, L2) <> 0 then GetFileHandleCount := 50
  1136. else GetFileHandleCount := L2;
  1137. end;
  1138. var TIB: PThreadInfoBlock;
  1139. PIB: PProcessInfoBlock;
  1140. begin
  1141. IsLibrary := FALSE;
  1142. (* Initialize the amount of file handles *)
  1143. FileHandleCount := GetFileHandleCount;
  1144. DosGetInfoBlocks (@TIB, @PIB);
  1145. StackBottom := TIB^.Stack;
  1146. {Set type of application}
  1147. ApplicationType := PIB^.ProcType;
  1148. IsConsole := ApplicationType <> 3;
  1149. exitproc:=nil;
  1150. {Initialize the heap.}
  1151. // Logic is following:
  1152. // Application allocates maximum possible memory array (~512Mb),
  1153. // but without commiting. On heap growing required amount of
  1154. // memory commited. So heap can be grown up to 512Mb.
  1155. // For newer systems maximum ammount of memory block can be
  1156. // 2 Gb, but here used 512 for campatability reasons.
  1157. // Note: Check for higher limit of heap not implemented yet.
  1158. // Note: Check for amount of memory for process not implemented yet.
  1159. // While used hard-coded value of max heapsize (256Mb)
  1160. DosAllocMem(Int_Heap, 256*1024*1024, 3);
  1161. Int_Heap_End:=Int_Heap;
  1162. InitHeap;
  1163. { ... and exceptions }
  1164. SysInitExceptions;
  1165. { ... and I/O }
  1166. SysInitStdIO;
  1167. { no I/O-Error }
  1168. inoutres:=0;
  1169. {Initialize environment (must be after InitHeap because allocates memory)}
  1170. Environment := pointer (PIB^.Env);
  1171. InitEnvironment;
  1172. CmdLine := pointer (PIB^.Cmd);
  1173. InitArguments;
  1174. {$ifdef HASVARIANT}
  1175. initvariantmanager;
  1176. {$endif HASVARIANT}
  1177. {$IFDEF DUMPGROW}
  1178. {$IFDEF CONTHEAP}
  1179. WriteLn ('Initial brk size is ', GetHeapSize);
  1180. // WriteLn ('Brk limit is ', BrkLimit);
  1181. {$ENDIF CONTHEAP}
  1182. {$ENDIF DUMPGROW}
  1183. end.
  1184. {
  1185. $Log$
  1186. Revision 1.60 2003-11-23 07:21:16 yuri
  1187. * native heap
  1188. Revision 1.59 2003/11/19 18:21:11 yuri
  1189. * Memory allocation bug fixed
  1190. Revision 1.58 2003/11/19 16:50:21 yuri
  1191. * Environment and arguments initialization now native
  1192. Revision 1.57 2003/11/06 17:20:44 yuri
  1193. * Unused constants removed
  1194. Revision 1.56 2003/11/03 09:42:28 marco
  1195. * Peter's Cardinal<->Longint fixes patch
  1196. Revision 1.55 2003/11/02 00:51:17 hajny
  1197. * corrections for do_open and os_mode back
  1198. Revision 1.54 2003/10/28 14:57:31 yuri
  1199. * do_* functions now native
  1200. Revision 1.53 2003/10/27 04:33:58 yuri
  1201. * os_mode removed (not required anymore)
  1202. Revision 1.52 2003/10/25 22:45:37 hajny
  1203. * file handling related fixes
  1204. Revision 1.51 2003/10/19 12:13:41 hajny
  1205. * UnusedHandle value made the same as with other targets
  1206. Revision 1.50 2003/10/19 09:37:00 hajny
  1207. * minor fix in non-default sbrk code
  1208. Revision 1.49 2003/10/19 09:06:28 hajny
  1209. * fix for terrible long-time bug in do_open
  1210. Revision 1.48 2003/10/18 16:58:39 hajny
  1211. * stdcall fixes again
  1212. Revision 1.47 2003/10/16 15:43:13 peter
  1213. * THandle is platform dependent
  1214. Revision 1.46 2003/10/14 21:10:06 hajny
  1215. * another longint2cardinal fix
  1216. Revision 1.45 2003/10/13 21:17:31 hajny
  1217. * longint to cardinal corrections
  1218. Revision 1.44 2003/10/12 18:07:30 hajny
  1219. * wrong use of Intel syntax
  1220. Revision 1.43 2003/10/12 17:59:40 hajny
  1221. * wrong use of Intel syntax
  1222. Revision 1.42 2003/10/12 17:52:28 hajny
  1223. * wrong use of Intel syntax
  1224. Revision 1.41 2003/10/12 10:45:36 hajny
  1225. * sbrk error handling corrected
  1226. Revision 1.40 2003/10/07 21:26:35 hajny
  1227. * stdcall fixes and asm routines cleanup
  1228. Revision 1.39 2003/10/06 16:58:27 yuri
  1229. * Another set of native functions.
  1230. Revision 1.38 2003/10/06 14:22:40 yuri
  1231. * Some emx code removed. Now withous so stupid error as with dos ;)
  1232. Revision 1.37 2003/10/04 08:30:59 yuri
  1233. * at&t syntax instead of intel syntax was used
  1234. Revision 1.36 2003/10/03 21:46:41 peter
  1235. * stdcall fixes
  1236. Revision 1.35 2003/10/01 18:42:49 yuri
  1237. * Unclosed comment
  1238. Revision 1.34 2003/09/29 18:39:59 hajny
  1239. * append fix applied to GO32v2, OS/2 and EMX
  1240. Revision 1.33 2003/09/27 11:52:36 peter
  1241. * sbrk returns pointer
  1242. Revision 1.32 2003/03/30 09:20:30 hajny
  1243. * platform extension unification
  1244. Revision 1.31 2003/01/15 22:16:12 hajny
  1245. * default sharing mode changed to DenyNone
  1246. Revision 1.30 2002/12/15 22:41:41 hajny
  1247. * First_Meg fixed + Environment initialization under Dos
  1248. Revision 1.29 2002/12/08 16:39:58 hajny
  1249. - WriteLn in GUI mode support commented out until fixed
  1250. Revision 1.28 2002/12/07 19:17:14 hajny
  1251. * GetEnv correction, better PM support, ...
  1252. Revision 1.27 2002/11/17 22:31:02 hajny
  1253. * type corrections (longint x cardinal)
  1254. Revision 1.26 2002/10/27 14:29:00 hajny
  1255. * heap management (hopefully) fixed
  1256. Revision 1.25 2002/10/14 19:39:17 peter
  1257. * threads unit added for thread support
  1258. Revision 1.24 2002/10/13 09:28:45 florian
  1259. + call to initvariantmanager inserted
  1260. Revision 1.23 2002/09/07 16:01:25 peter
  1261. * old logs removed and tabs fixed
  1262. Revision 1.22 2002/07/01 16:29:05 peter
  1263. * sLineBreak changed to normal constant like Kylix
  1264. Revision 1.21 2002/04/21 15:54:20 carl
  1265. + initialize some global variables
  1266. Revision 1.20 2002/04/12 17:42:16 carl
  1267. + generic stack checking
  1268. Revision 1.19 2002/03/11 19:10:33 peter
  1269. * Regenerated with updated fpcmake
  1270. Revision 1.18 2002/02/10 13:46:20 hajny
  1271. * heap management corrected (heap_brk)
  1272. }