system.pas 36 KB

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