system.pas 45 KB

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