system.pas 44 KB

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