system.pas 44 KB

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