system.pas 44 KB

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