system.pas 43 KB

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