system.pp 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 2004 by Karoly Balogh for Genesi Sarl
  5. System unit for MorphOS/PowerPC
  6. Uses parts of the Amiga/68k port by Carl Eric Codere
  7. and Nils Sjoholm
  8. See the file COPYING.FPC, included in this distribution,
  9. for details about the copyright.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. **********************************************************************}
  14. unit {$ifdef VER1_0}SysMorph{$else}System{$endif};
  15. interface
  16. {$define FPC_IS_SYSTEM}
  17. {$I systemh.inc}
  18. type
  19. THandle = LongInt;
  20. {$I heaph.inc}
  21. const
  22. LineEnding = #10;
  23. LFNSupport = True;
  24. DirectorySeparator = '/';
  25. DriveSeparator = ':';
  26. PathSeparator = ';';
  27. const
  28. UnusedHandle : LongInt = -1;
  29. StdInputHandle : LongInt = 0;
  30. StdOutputHandle : LongInt = 0;
  31. StdErrorHandle : LongInt = 0;
  32. FileNameCaseSensitive : Boolean = False;
  33. sLineBreak : string[1] = LineEnding;
  34. DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsLF;
  35. BreakOn : Boolean = True;
  36. {*****************************************************************************
  37. MorphOS structures
  38. *****************************************************************************}
  39. type
  40. PClockData = ^TClockData;
  41. TClockData = packed Record
  42. sec : Word;
  43. min : Word;
  44. hour : Word;
  45. mday : Word;
  46. month: Word;
  47. year : Word;
  48. wday : Word;
  49. end;
  50. TDateStamp = packed record
  51. ds_Days : LongInt; { Number of days since Jan. 1, 1978 }
  52. ds_Minute : LongInt; { Number of minutes past midnight }
  53. ds_Tick : LongInt; { Number of ticks past minute }
  54. end;
  55. PDateStamp = ^TDateStamp;
  56. PFileInfoBlock = ^TFileInfoBlock;
  57. TFileInfoBlock = packed record
  58. fib_DiskKey : LongInt;
  59. fib_DirEntryType : LongInt;
  60. { Type of Directory. If < 0, then a plain file. If > 0 a directory }
  61. fib_FileName : Array [0..107] of Char;
  62. { Null terminated. Max 30 chars used for now }
  63. fib_Protection : LongInt;
  64. { bit mask of protection, rwxd are 3-0. }
  65. fib_EntryType : LongInt;
  66. fib_Size : LongInt; { Number of bytes in file }
  67. fib_NumBlocks : LongInt; { Number of blocks in file }
  68. fib_Date : TDateStamp; { Date file last changed }
  69. fib_Comment : Array [0..79] of Char;
  70. { Null terminated comment associated with file }
  71. fib_Reserved : Array [0..35] of Char;
  72. end;
  73. PNode = ^TNode;
  74. TNode = packed record
  75. ln_Succ, { Pointer to next (successor) }
  76. ln_Pred: pNode; { Pointer to previous (predecessor) }
  77. ln_Type: Byte;
  78. ln_Pri : Shortint; { Priority, for sorting }
  79. ln_Name: PChar; { ID string, null terminated }
  80. end; { Note: Integer aligned }
  81. PMinNode = ^TMinNode;
  82. tMinNode = packed record
  83. mln_Succ,
  84. mln_Pred: pMinNode;
  85. end;
  86. PList = ^TList;
  87. tList = packed record
  88. lh_Head : pNode;
  89. lh_Tail : pNode;
  90. lh_TailPred: pNode;
  91. lh_Type : Byte;
  92. l_pad : Byte;
  93. end;
  94. PMinList = ^TMinList;
  95. TMinList = packed record
  96. mlh_Head : PMinNode;
  97. mlh_Tail : PMinNode;
  98. mlh_TailPred: PMinNode;
  99. end;
  100. PMsgPort = ^TMsgPort;
  101. TMsgPort = packed record
  102. mp_Node : TNode;
  103. mp_Flags : Byte;
  104. mp_SigBit : Byte; { signal bit number }
  105. mp_SigTask: Pointer; { task to be signalled (TaskPtr) }
  106. mp_MsgList: TList; { message linked list }
  107. end;
  108. PMessage = ^TMessage;
  109. TMessage = packed record
  110. mn_Node : TNode;
  111. mn_ReplyPort: PMsgPort;
  112. mn_Length : Word;
  113. end;
  114. PTask = ^TTask;
  115. TTask = packed record
  116. tc_Node : TNode;
  117. tc_Flags : Byte;
  118. tc_State : Byte;
  119. tc_IDNestCnt : Shortint; { intr disabled nesting }
  120. tc_TDNestCnt : Shortint; { task disabled nesting }
  121. tc_SigAlloc : DWord; { sigs allocated }
  122. tc_SigWait : DWord; { sigs we are waiting for }
  123. tc_SigRecvd : DWord; { sigs we have received }
  124. tc_SigExcept : DWord; { sigs we will take excepts for }
  125. tc_TrapAlloc : Word; { traps allocated }
  126. tc_TrapAble : Word; { traps enabled }
  127. tc_ExceptData: Pointer; { points to except data }
  128. tc_ExceptCode: Pointer; { points to except code }
  129. tc_TrapData : Pointer; { points to trap data }
  130. tc_TrapCode : Pointer; { points to trap code }
  131. tc_SPReg : Pointer; { stack pointer }
  132. tc_SPLower : Pointer; { stack lower bound }
  133. tc_SPUpper : Pointer; { stack upper bound + 2 }
  134. tc_Switch : Pointer; { task losing CPU }
  135. tc_Launch : Pointer; { task getting CPU }
  136. tc_MemEntry : TList; { allocated memory }
  137. tc_UserData : Pointer; { per task data }
  138. end;
  139. PProcess = ^TProcess;
  140. TProcess = packed record
  141. pr_Task : TTask;
  142. pr_MsgPort : TMsgPort; { This is BPTR address from DOS functions }
  143. pr_Pad : Word; { Remaining variables on 4 byte boundaries }
  144. pr_SegList : Pointer; { Array of seg lists used by this process }
  145. pr_StackSize : Longint; { Size of process stack in bytes }
  146. pr_GlobVec : Pointer; { Global vector for this process (BCPL) }
  147. pr_TaskNum : Longint; { CLI task number of zero if not a CLI }
  148. pr_StackBase : DWord; { Ptr to high memory end of process stack }
  149. pr_Result2 : Longint; { Value of secondary result from last call }
  150. pr_CurrentDir : DWord; { Lock associated with current directory }
  151. pr_CIS : DWord; { Current CLI Input Stream }
  152. pr_COS : DWord; { Current CLI Output Stream }
  153. pr_ConsoleTask : Pointer; { Console handler process for current window }
  154. pr_FileSystemTask: Pointer; { File handler process for current drive }
  155. pr_CLI : DWord; { pointer to ConsoleLineInterpreter }
  156. pr_ReturnAddr : Pointer; { pointer to previous stack frame }
  157. pr_PktWait : Pointer; { Function to be called when awaiting msg }
  158. pr_WindowPtr : Pointer; { Window for error printing }
  159. { following definitions are new with 2.0 }
  160. pr_HomeDir : DWord; { Home directory of executing program }
  161. pr_Flags : Longint; { flags telling dos about process }
  162. pr_ExitCode : Pointer; { code to call on exit of program OR NULL }
  163. pr_ExitData : Longint; { Passed as an argument to pr_ExitCode. }
  164. pr_Arguments : PChar; { Arguments passed to the process at start }
  165. pr_LocalVars : TMinList; { Local environment variables }
  166. pr_ShellPrivate : Longint; { for the use of the current shell }
  167. pr_CES : DWord; { Error stream - IF NULL, use pr_COS }
  168. end;
  169. PLibrary = ^TLibrary;
  170. TLibrary = packed record
  171. lib_Node : tNode;
  172. lib_Flags,
  173. lib_pad : Byte;
  174. lib_NegSize, { number of bytes before library }
  175. lib_PosSize, { number of bytes after library }
  176. lib_Version, { major }
  177. lib_Revision: Word; { minor }
  178. lib_IdString: PChar; { ASCII identification }
  179. lib_Sum : LongInt; { the checksum itself }
  180. lib_OpenCnt : Word; { number of current opens }
  181. end; { * Warning: size is not a longword multiple ! * }
  182. PDevice = ^TDevice;
  183. tDevice = record
  184. dd_Library: TLibrary;
  185. end;
  186. PUnit = ^tUnit;
  187. TUnit = record
  188. unit_MsgPort: TMsgPort; { queue for unprocessed messages }
  189. { instance of msgport is recommended }
  190. unit_flags,
  191. unit_pad : Byte;
  192. unit_OpenCnt: Word; { number of active opens }
  193. end;
  194. PIORequest = ^TIORequest;
  195. TIORequest = packed record
  196. io_Message: TMessage;
  197. io_Device : PDevice; { device node pointer }
  198. io_Unit : PUnit; { unit (driver private)}
  199. io_Command: Word; { device command }
  200. io_Flags : Byte;
  201. io_Error : Shortint; { error or warning num }
  202. end;
  203. PInfoData = ^TInfoData;
  204. TInfoData = packed record
  205. id_NumSoftErrors: LongInt; { number of soft errors on disk }
  206. id_UnitNumber : LongInt; { Which unit disk is (was) mounted on }
  207. id_DiskState : LongInt; { See defines below }
  208. id_NumBlocks : LongInt; { Number of blocks on disk }
  209. id_NumBlocksUsed: LongInt; { Number of block in use }
  210. id_BytesPerBlock: LongInt;
  211. id_DiskType : LongInt; { Disk Type code }
  212. id_VolumeNode : LongInt; { BCPL pointer to volume node }
  213. id_InUse : LongInt; { Flag, zero if not in use }
  214. end;
  215. PChain = ^TChain;
  216. TChain = packed record
  217. an_Child : PChain;
  218. an_Parent: PChain;
  219. an_Lock : LongInt;
  220. an_info : TFileInfoBlock;
  221. an_Flags : ShortInt;
  222. an_string: Array[0..0] of char;
  223. end;
  224. PAnchorPath = ^TAnchorPath;
  225. TAnchorPath = packed record
  226. ap_Base : PChain; { pointer to first anchor }
  227. ap_First : PChain; { pointer to last anchor }
  228. ap_BreakBits: LongInt; { Bits we want to break on }
  229. ap_FondBreak: LongInt; { Bits we broke on. Also returns ERROR_BREAK }
  230. ap_Flags : ShortInt; { New use for extra word. }
  231. ap_reserved : Byte;
  232. ap_StrLen : Word;
  233. ap_Info : TFileInfoBlock;
  234. ap_Buf : array[0..0] of Char; { Buffer for path name, allocated by user }
  235. end;
  236. PDOSList = ^TDOSList;
  237. TDOSList = packed record
  238. dol_Next: LongInt; { bptr to next device on list }
  239. dol_Type: LongInt; { see DLT below }
  240. dol_Task: Pointer; { ptr to handler task }
  241. dol_Lock: LongInt;
  242. dol_Misc: array[0..23] of ShortInt;
  243. dol_Name: LongInt; { bptr to bcpl name }
  244. end;
  245. var
  246. MOS_ExecBase : Pointer; external name '_ExecBase';
  247. MOS_DOSBase : Pointer;
  248. MOS_UtilityBase: Pointer;
  249. MOS_heapPool: Pointer; { pointer for the OS pool for growing the heap }
  250. MOS_origDir : LongInt; { original directory on startup }
  251. MOS_ambMsg : PMessage;
  252. MOS_ConName : PChar ='CON:10/30/620/100/FPC Console Output/AUTO/CLOSE/WAIT';
  253. MOS_argc: LongInt;
  254. MOS_argv: PPChar;
  255. {*****************************************************************************
  256. MorphOS functions
  257. *****************************************************************************}
  258. { exec.library functions }
  259. function exec_OpenLibrary(libname: PChar location 'a1';
  260. libver: LongInt location 'd0'): Pointer; SysCall MOS_ExecBase 552;
  261. procedure exec_CloseLibrary(libhandle: Pointer location 'a1'); SysCall MOS_ExecBase 414;
  262. function exec_CreatePool(memflags: LongInt location 'd0';
  263. puddleSize: LongInt location 'd1';
  264. threshSize: LongInt location 'd2'): Pointer; SysCall MOS_ExecBase 696;
  265. procedure exec_DeletePool(poolHeader: Pointer location 'a0'); SysCall MOS_ExecBase 702;
  266. function exec_AllocPooled(poolHeader: Pointer location 'a0';
  267. memSize: LongInt location 'd0'): Pointer; SysCall MOS_ExecBase 708;
  268. function exec_SetSignal(newSignals: LongInt location 'd0';
  269. signalMask: LongInt location 'd1'): LongInt; SysCall MOS_ExecBase 306;
  270. function exec_FindTask(tname: PChar location 'a1'): PTask; SysCall MOS_ExecBase 294;
  271. function exec_GetMsg(port: PMsgPort location 'a0'): PMessage; SysCall MOS_ExecBase 372;
  272. function exec_WaitPort(port: PMsgPort location 'a0'): PMessage; SysCall MOS_ExecBase 384;
  273. function exec_AllocMem(byteSize: LongInt location 'd0';
  274. requirements: LongInt location 'd1'): Pointer; SysCall MOS_ExecBase 198;
  275. procedure exec_FreeMem(memoryBlock: Pointer location 'a1';
  276. byteSize: LongInt location 'd0'); SysCall MOS_ExecBase 210;
  277. function exec_AllocSignal(signalNum: LongInt location 'd0'): ShortInt; SysCall MOS_ExecBase 330;
  278. procedure exec_FreeSignal(signalNum: LongInt location 'd0'); SysCall MOS_ExecBase 336;
  279. procedure exec_AddPort(port: PMsgPort location 'a1'); SysCall MOS_ExecBase 354;
  280. procedure exec_RemPort(port: PMsgPort location 'a1'); SysCall MOS_ExecBase 360;
  281. function exec_DoIO(ioRequest: PIORequest location 'a1'): ShortInt; SysCall MOS_ExecBase 456;
  282. function exec_OpenDevice(const devName: PChar location 'a0';
  283. unite: LongInt location 'd0';
  284. ioRequest: PIORequest location 'a1';
  285. flags: LongInt location 'd1'): ShortInt; SysCall MOS_ExecBase 444;
  286. procedure exec_CloseDevice(ioRequest: PIORequest location 'a1'); SysCall MOS_ExecBase 450;
  287. { dos.library functions }
  288. function dos_Output: LongInt; SysCall MOS_DOSBase 60;
  289. function dos_Input: LongInt; SysCall MOS_DOSBase 54;
  290. function dos_IoErr: LongInt; SysCall MOS_DOSBase 132;
  291. function dos_GetArgStr: PChar; SysCall MOS_DOSBase 534;
  292. function dos_Open(fname: PChar location 'd1';
  293. accessMode: LongInt location 'd2'): LongInt; SysCall MOS_DOSBase 30;
  294. function dos_Close(fileh: LongInt location 'd1'): Boolean; SysCall MOS_DOSBase 36;
  295. function dos_Seek(fileh: LongInt location 'd1';
  296. position: LongInt location 'd2';
  297. posmode: LongInt location 'd3'): LongInt; SysCall MOS_DOSBase 66;
  298. function dos_SetFileSize(fileh: LongInt location 'd1';
  299. position: LongInt location 'd2';
  300. posmode: LongInt location 'd3'): LongInt; SysCall MOS_DOSBase 456;
  301. function dos_Read(fileh: LongInt location 'd1';
  302. buffer: Pointer location 'd2';
  303. length: LongInt location 'd3'): LongInt; SysCall MOS_DOSBase 40;
  304. function dos_Write(fileh: LongInt location 'd1';
  305. buffer: Pointer location 'd2';
  306. length: LongInt location 'd3'): LongInt; SysCall MOS_DOSBase 48;
  307. function dos_WriteChars(buf: PChar location 'd1';
  308. buflen: LongInt location 'd2'): LongInt; SysCall MOS_DOSBase 942;
  309. function dos_Rename(oldName: PChar location 'd1';
  310. newName: PChar location 'd2'): Boolean; SysCall MOS_DOSBase 78;
  311. function dos_DeleteFile(fname: PChar location 'd1'): Boolean; SysCall MOS_DOSBase 72;
  312. function dos_GetCurrentDirName(buf: PChar location 'd1';
  313. len: LongInt location 'd2'): Boolean; SysCall MOS_DOSBase 564;
  314. function dos_Lock(lname: PChar location 'd1';
  315. accessMode: LongInt location 'd2'): LongInt; SysCall MOS_DOSBase 84;
  316. procedure dos_Unlock(lock: LongInt location 'd1'); SysCall MOS_DOSBase 90;
  317. function dos_CurrentDir(lock: LongInt location 'd1'): LongInt; SysCall MOS_DOSBase 126;
  318. function dos_Examine(lock: LongInt location 'd1';
  319. FileInfoBlock: Pointer location 'd2'): Boolean; SysCall MOS_DOSBase 102;
  320. function dos_NameFromLock(lock: LongInt location 'd1';
  321. buffer: PChar location 'd2';
  322. len: LongInt location 'd3'): Boolean; SysCall MOS_DOSBase 402;
  323. function dos_Info(lock: LongInt location 'd1';
  324. parameterBlock: PInfoData location 'd2'): Boolean; SysCall MOS_DOSBase 114;
  325. function dos_CreateDir(dname: PChar location 'd1'): LongInt; SysCall MOS_DOSBase 120;
  326. function dos_DateStamp(var ds: TDateStamp location 'd1'): LongInt; SysCall MOS_DOSBase 192;
  327. function dos_SystemTagList(command: PChar location 'd1';
  328. tags: Pointer location 'd2'): LongInt; SysCall MOS_DOSBase 606;
  329. function dos_GetVar(vname: PChar location 'd1';
  330. buffer: PChar location 'd2';
  331. size: LongInt location 'd3';
  332. flags: LongInt location 'd4'): LongInt; SysCall MOS_DOSBase 906;
  333. function dos_MatchFirst(pat: PChar location 'd1';
  334. anchor: PAnchorPath location 'd2'): LongInt; SysCall MOS_DOSBase 822;
  335. function dos_MatchNext(anchor: PAnchorPath location 'd1'): LongInt; SysCall MOS_DOSBase 828;
  336. procedure dos_MatchEnd(anchor: PAnchorPath location 'd1') SysCall MOS_DOSBase 834;
  337. function dos_LockDosList(flags: LongInt location 'd1'): PDOSList; SysCall MOS_DOSBase 654;
  338. procedure dos_UnLockDosList(flags: LongInt location 'd2'); SysCall MOS_DOSBase 660;
  339. function dos_NextDosEntry(dlist: PDOSList location 'd1';
  340. flags: LongInt location 'd2'): PDOSList; SysCall MOS_DOSBase 690;
  341. function dos_SetProtection(name: PChar location 'd1';
  342. mask: LongInt location 'd2'): Boolean; SysCall MOS_DOSBase 186;
  343. function dos_SetFileDate(name: PChar location 'd1';
  344. date: PDateStamp location 'd2'): Boolean; SysCall MOS_DOSBase 396;
  345. { utility.library functions }
  346. function util_Date2Amiga(date: PClockData location 'a0'): LongInt; SysCall MOS_UtilityBase 126;
  347. procedure util_Amiga2Date(amigatime: LongInt location 'd0';
  348. resultat: PClockData location 'a0'); SysCall MOS_UtilityBase 120;
  349. implementation
  350. {$I system.inc}
  351. {*****************************************************************************
  352. System Dependent Structures/Consts
  353. *****************************************************************************}
  354. { Errors from dos_IoErr(), etc. }
  355. const
  356. ERROR_NO_FREE_STORE = 103;
  357. ERROR_TASK_TABLE_FULL = 105;
  358. ERROR_BAD_TEMPLATE = 114;
  359. ERROR_BAD_NUMBER = 115;
  360. ERROR_REQUIRED_ARG_MISSING = 116;
  361. ERROR_KEY_NEEDS_ARG = 117;
  362. ERROR_TOO_MANY_ARGS = 118;
  363. ERROR_UNMATCHED_QUOTES = 119;
  364. ERROR_LINE_TOO_LONG = 120;
  365. ERROR_FILE_NOT_OBJECT = 121;
  366. ERROR_INVALID_RESIDENT_LIBRARY = 122;
  367. ERROR_NO_DEFAULT_DIR = 201;
  368. ERROR_OBJECT_IN_USE = 202;
  369. ERROR_OBJECT_EXISTS = 203;
  370. ERROR_DIR_NOT_FOUND = 204;
  371. ERROR_OBJECT_NOT_FOUND = 205;
  372. ERROR_BAD_STREAM_NAME = 206;
  373. ERROR_OBJECT_TOO_LARGE = 207;
  374. ERROR_ACTION_NOT_KNOWN = 209;
  375. ERROR_INVALID_COMPONENT_NAME = 210;
  376. ERROR_INVALID_LOCK = 211;
  377. ERROR_OBJECT_WRONG_TYPE = 212;
  378. ERROR_DISK_NOT_VALIDATED = 213;
  379. ERROR_DISK_WRITE_PROTECTED = 214;
  380. ERROR_RENAME_ACROSS_DEVICES = 215;
  381. ERROR_DIRECTORY_NOT_EMPTY = 216;
  382. ERROR_TOO_MANY_LEVELS = 217;
  383. ERROR_DEVICE_NOT_MOUNTED = 218;
  384. ERROR_SEEK_ERROR = 219;
  385. ERROR_COMMENT_TOO_BIG = 220;
  386. ERROR_DISK_FULL = 221;
  387. ERROR_DELETE_PROTECTED = 222;
  388. ERROR_WRITE_PROTECTED = 223;
  389. ERROR_READ_PROTECTED = 224;
  390. ERROR_NOT_A_DOS_DISK = 225;
  391. ERROR_NO_DISK = 226;
  392. ERROR_NO_MORE_ENTRIES = 232;
  393. { added for AOS 1.4 }
  394. ERROR_IS_SOFT_LINK = 233;
  395. ERROR_OBJECT_LINKED = 234;
  396. ERROR_BAD_HUNK = 235;
  397. ERROR_NOT_IMPLEMENTED = 236;
  398. ERROR_RECORD_NOT_LOCKED = 240;
  399. ERROR_LOCK_COLLISION = 241;
  400. ERROR_LOCK_TIMEOUT = 242;
  401. ERROR_UNLOCK_ERROR = 243;
  402. { DOS file offset modes }
  403. const
  404. OFFSET_BEGINNING = -1;
  405. OFFSET_CURRENT = 0;
  406. OFFSET_END = 1;
  407. { Lock AccessMode }
  408. const
  409. SHARED_LOCK = -2;
  410. ACCESS_READ = SHARED_LOCK;
  411. EXCLUSIVE_LOCK = -1;
  412. ACCESS_WRITE = EXCLUSIVE_LOCK;
  413. { Memory flags }
  414. const
  415. MEMF_ANY = 0;
  416. MEMF_PUBLIC = 1 Shl 0;
  417. MEMF_CHIP = 1 Shl 1;
  418. MEMF_FAST = 1 Shl 2;
  419. MEMF_LOCAL = 1 Shl 8;
  420. MEMF_24BITDMA = 1 Shl 9;
  421. MEMF_KICK = 1 Shl 10;
  422. MEMF_CLEAR = 1 Shl 16;
  423. MEMF_LARGEST = 1 Shl 17;
  424. MEMF_REVERSE = 1 Shl 18;
  425. MEMF_TOTAL = 1 Shl 19;
  426. MEMF_NO_EXPUNGE = 1 Shl 31;
  427. const
  428. CTRL_C = 20; { Error code on CTRL-C press }
  429. SIGBREAKF_CTRL_C = $1000; { CTRL-C signal flags }
  430. {*****************************************************************************
  431. MorphOS File-handling Support Functions
  432. *****************************************************************************}
  433. type
  434. { AmigaOS does not automatically close opened files on exit back to }
  435. { the operating system, therefore as a precuation we close all files }
  436. { manually on exit. }
  437. PFileList = ^TFileList;
  438. TFileList = record { no packed, must be correctly aligned }
  439. handle : LongInt; { Handle to file }
  440. next : PFileList; { Next file in list }
  441. end;
  442. var
  443. MOS_fileList: PFileList; { List pointer to opened files }
  444. { Function to be called at program shutdown, to close all opened files }
  445. procedure CloseList(l: PFileList);
  446. var
  447. tmpNext : PFileList;
  448. tmpHandle : LongInt;
  449. begin
  450. if l=nil then exit;
  451. { First, close all tracked files }
  452. tmpNext:=l^.next;
  453. while tmpNext<>nil do begin
  454. tmpHandle:=tmpNext^.handle;
  455. if (tmpHandle<>StdInputHandle) and (tmpHandle<>StdOutputHandle)
  456. and (tmpHandle<>StdErrorHandle) then begin
  457. dos_Close(tmpHandle);
  458. end;
  459. tmpNext:=tmpNext^.next;
  460. end;
  461. { Next, erase the linked list }
  462. while l<>nil do begin
  463. tmpNext:=l;
  464. l:=l^.next;
  465. dispose(tmpNext);
  466. end;
  467. end;
  468. { Function to be called to add a file to the opened file list }
  469. procedure AddToList(var l: PFileList; h: LongInt);
  470. var
  471. p : PFileList;
  472. inList: Boolean;
  473. begin
  474. inList:=False;
  475. if l<>nil then begin
  476. { if there is a valid filelist, search for the value }
  477. { in the list to avoid double additions }
  478. p:=l;
  479. while (p^.next<>nil) and (not inList) do
  480. if p^.next^.handle=h then inList:=True
  481. else p:=p^.next;
  482. p:=nil;
  483. end else begin
  484. { if the list is not yet allocated, allocate it. }
  485. New(l);
  486. l^.next:=nil;
  487. end;
  488. if not inList then begin
  489. New(p);
  490. p^.handle:=h;
  491. p^.next:=l^.next;
  492. l^.next:=p;
  493. end;
  494. end;
  495. { Function to be called to remove a file from the list }
  496. procedure RemoveFromList(var l: PFileList; h: longint);
  497. var
  498. p : PFileList;
  499. inList: Boolean;
  500. begin
  501. if l=nil then exit;
  502. inList:=False;
  503. p:=l;
  504. while (p^.next<>nil) and (not inList) do
  505. if p^.next^.handle=h then inList:=True
  506. else p:=p^.next;
  507. if p^.next<>nil then begin
  508. dispose(p^.next);
  509. p^.next:=p^.next^.next;
  510. end;
  511. end;
  512. {*****************************************************************************
  513. Misc. System Dependent Functions
  514. *****************************************************************************}
  515. procedure haltproc(e:longint);cdecl;external name '_haltproc';
  516. procedure System_exit;
  517. begin
  518. { We must remove the CTRL-C FALG here because halt }
  519. { may call I/O routines, which in turn might call }
  520. { halt, so a recursive stack crash }
  521. if BreakOn then begin
  522. if (exec_SetSignal(0,0) and SIGBREAKF_CTRL_C)<>0 then
  523. exec_SetSignal(0,SIGBREAKF_CTRL_C);
  524. end;
  525. { Closing opened files }
  526. CloseList(MOS_fileList);
  527. if MOS_UtilityBase<>nil then exec_CloseLibrary(MOS_UtilityBase);
  528. if MOS_DOSBase<>nil then exec_CloseLibrary(MOS_DOSBase);
  529. if MOS_heapPool<>nil then exec_DeletePool(MOS_heapPool);
  530. haltproc(ExitCode);
  531. end;
  532. { Converts a MorphOS dos.library error code to a TP compatible error code }
  533. { Based on 1.0.x Amiga RTL }
  534. procedure dosError2InOut(errno: LongInt);
  535. begin
  536. case errno of
  537. ERROR_BAD_NUMBER,
  538. ERROR_ACTION_NOT_KNOWN,
  539. ERROR_NOT_IMPLEMENTED : InOutRes := 1;
  540. ERROR_OBJECT_NOT_FOUND : InOutRes := 2;
  541. ERROR_DIR_NOT_FOUND : InOutRes := 3;
  542. ERROR_DISK_WRITE_PROTECTED : InOutRes := 150;
  543. ERROR_OBJECT_WRONG_TYPE : InOutRes := 151;
  544. ERROR_OBJECT_EXISTS,
  545. ERROR_DELETE_PROTECTED,
  546. ERROR_WRITE_PROTECTED,
  547. ERROR_READ_PROTECTED,
  548. ERROR_OBJECT_IN_USE,
  549. ERROR_DIRECTORY_NOT_EMPTY : InOutRes := 5;
  550. ERROR_NO_MORE_ENTRIES : InOutRes := 18;
  551. ERROR_RENAME_ACROSS_DEVICES : InOutRes := 17;
  552. ERROR_DISK_FULL : InOutRes := 101;
  553. ERROR_INVALID_RESIDENT_LIBRARY : InoutRes := 153;
  554. ERROR_BAD_HUNK : InOutRes := 153;
  555. ERROR_NOT_A_DOS_DISK : InOutRes := 157;
  556. ERROR_NO_DISK,
  557. ERROR_DISK_NOT_VALIDATED,
  558. ERROR_DEVICE_NOT_MOUNTED : InOutRes := 152;
  559. ERROR_SEEK_ERROR : InOutRes := 156;
  560. ERROR_LOCK_COLLISION,
  561. ERROR_LOCK_TIMEOUT,
  562. ERROR_UNLOCK_ERROR,
  563. ERROR_INVALID_LOCK,
  564. ERROR_INVALID_COMPONENT_NAME,
  565. ERROR_BAD_STREAM_NAME,
  566. ERROR_FILE_NOT_OBJECT : InOutRes := 6;
  567. else
  568. InOutres := errno;
  569. end;
  570. end;
  571. { Used for CTRL_C checking in I/O calls }
  572. procedure checkCTRLC;
  573. begin
  574. if BreakOn then begin
  575. if (exec_SetSignal(0,0) And SIGBREAKF_CTRL_C)<>0 then begin
  576. { Clear CTRL-C signal }
  577. exec_SetSignal(0,SIGBREAKF_CTRL_C);
  578. Halt(CTRL_C);
  579. end;
  580. end;
  581. end;
  582. { Generates correct argument array on startup }
  583. procedure GenerateArgs;
  584. var
  585. argvlen : longint;
  586. procedure allocarg(idx,len:longint);
  587. var
  588. i,oldargvlen : longint;
  589. begin
  590. if idx>=argvlen then
  591. begin
  592. oldargvlen:=argvlen;
  593. argvlen:=(idx+8) and (not 7);
  594. sysreallocmem(MOS_argv,argvlen*sizeof(pointer));
  595. for i:=oldargvlen to argvlen-1 do
  596. MOS_argv[i]:=nil;
  597. end;
  598. { use realloc to reuse already existing memory }
  599. sysreallocmem(MOS_argv[idx],len+1);
  600. end;
  601. var
  602. count: word;
  603. start: word;
  604. localindex: word;
  605. p : pchar;
  606. temp : string;
  607. begin
  608. p:=dos_GetArgStr;
  609. argvlen:=0;
  610. { Set argv[0] }
  611. temp:=paramstr(0);
  612. allocarg(0,length(temp));
  613. move(temp[1],MOS_argv[0]^,length(temp));
  614. MOS_argv[0][length(temp)]:=#0;
  615. { check if we're started from Ambient }
  616. if MOS_ambMsg<>nil then
  617. begin
  618. MOS_argc:=0;
  619. exit;
  620. end;
  621. { Handle the other args }
  622. count:=0;
  623. { first index is one }
  624. localindex:=1;
  625. while (p[count]<>#0) do
  626. begin
  627. while (p[count]=' ') or (p[count]=#9) or (p[count]=LineEnding) do inc(count);
  628. start:=count;
  629. while (p[count]<>#0) and (p[count]<>' ') and (p[count]<>#9) and (p[count]<>LineEnding) do inc(count);
  630. if (count-start>0) then
  631. begin
  632. allocarg(localindex,count-start);
  633. move(p[start],MOS_argv[localindex]^,count-start);
  634. MOS_argv[localindex][count-start]:=#0;
  635. inc(localindex);
  636. end;
  637. end;
  638. MOS_argc:=localindex;
  639. end;
  640. {*****************************************************************************
  641. ParamStr/Randomize
  642. *****************************************************************************}
  643. { number of args }
  644. function paramcount : longint;
  645. begin
  646. if MOS_ambMsg<>nil then
  647. paramcount:=0
  648. else
  649. paramcount:=MOS_argc-1;
  650. end;
  651. { argument number l }
  652. function paramstr(l : longint) : string;
  653. begin
  654. if (l>=0) and (l+1<=MOS_argc) then
  655. paramstr:=strpas(MOS_argv[l])
  656. else
  657. paramstr:='';
  658. end;
  659. { set randseed to a new pseudo random value }
  660. procedure randomize;
  661. var tmpTime: TDateStamp;
  662. begin
  663. dos_DateStamp(tmpTime);
  664. randseed:=tmpTime.ds_tick;
  665. end;
  666. {*****************************************************************************
  667. Heap Management
  668. *****************************************************************************}
  669. var
  670. int_heap : LongInt; external name 'HEAP';
  671. int_heapsize : LongInt; external name 'HEAPSIZE';
  672. { first address of heap }
  673. function getheapstart:pointer;
  674. begin
  675. getheapstart:=@int_heap;
  676. end;
  677. { current length of heap }
  678. function getheapsize:longint;
  679. begin
  680. getheapsize:=int_heapsize;
  681. end;
  682. { function to allocate size bytes more for the program }
  683. { must return the first address of new data space or nil if fail }
  684. function Sbrk(size : longint):pointer;
  685. begin
  686. Sbrk:=exec_AllocPooled(MOS_heapPool,size);
  687. end;
  688. {$I heap.inc}
  689. {*****************************************************************************
  690. Directory Handling
  691. *****************************************************************************}
  692. procedure mkdir(const s : string);[IOCheck];
  693. var
  694. buffer : array[0..255] of char;
  695. j : Integer;
  696. tmpStr : string;
  697. tmpLock : LongInt;
  698. begin
  699. checkCTRLC;
  700. if (s='') or (InOutRes<>0) then exit;
  701. tmpStr:=s;
  702. for j:=1 to length(tmpStr) do
  703. if tmpStr[j]='\' then tmpStr[j]:='/';
  704. move(tmpStr[1],buffer,length(tmpStr));
  705. buffer[length(tmpStr)]:=#0;
  706. tmpLock:=dos_CreateDir(buffer);
  707. if tmpLock=0 then begin
  708. dosError2InOut(dos_IoErr);
  709. exit;
  710. end;
  711. dos_UnLock(tmpLock);
  712. end;
  713. procedure rmdir(const s : string);[IOCheck];
  714. var
  715. buffer : array[0..255] of char;
  716. j : Integer;
  717. tmpStr : string;
  718. begin
  719. checkCTRLC;
  720. if (s='.') then InOutRes:=16;
  721. If (s='') or (InOutRes<>0) then exit;
  722. tmpStr:=s;
  723. for j:=1 to length(tmpStr) do
  724. if tmpStr[j] = '\' then tmpStr[j] := '/';
  725. move(tmpStr[1],buffer,length(tmpStr));
  726. buffer[length(tmpStr)]:=#0;
  727. if not dos_DeleteFile(buffer) then
  728. dosError2InOut(dos_IoErr);
  729. end;
  730. procedure chdir(const s : string);[IOCheck];
  731. var
  732. buffer : array[0..255] of char;
  733. alock : LongInt;
  734. FIB : PFileInfoBlock;
  735. j : Integer;
  736. tmpStr : string;
  737. begin
  738. checkCTRLC;
  739. If (s='') or (InOutRes<>0) then exit;
  740. tmpStr:=s;
  741. for j:=1 to length(tmpStr) do
  742. if tmpStr[j]='\' then tmpStr[j]:='/';
  743. { Return parent directory }
  744. if s='..' then begin
  745. getdir(0,tmpStr);
  746. j:=length(tmpStr);
  747. { Look through the previous paths }
  748. while (tmpStr[j]<>'/') and (tmpStr[j]<>':') and (j>0) do
  749. dec(j);
  750. if j>0 then
  751. tmpStr:=copy(tmpStr,1,j);
  752. end;
  753. alock:=0;
  754. move(tmpStr[1],buffer,length(tmpStr));
  755. buffer[length(tmpStr)]:=#0;
  756. { Changing the directory is a pretty complicated affair }
  757. { 1) Obtain a lock on the directory }
  758. { 2) CurrentDir the lock }
  759. alock:=dos_Lock(buffer,SHARED_LOCK);
  760. if alock=0 then begin
  761. dosError2InOut(dos_IoErr);
  762. exit;
  763. end;
  764. FIB:=nil;
  765. new(FIB);
  766. if (dos_Examine(alock,FIB)=True) and (FIB^.fib_DirEntryType>0) then begin
  767. alock := dos_CurrentDir(alock);
  768. if MOS_OrigDir=0 then begin
  769. MOS_OrigDir:=alock;
  770. alock:=0;
  771. end;
  772. end;
  773. if alock<>0 then dos_Unlock(alock);
  774. if assigned(FIB) then dispose(FIB)
  775. end;
  776. procedure GetDir (DriveNr: byte; var Dir: ShortString);
  777. var tmpbuf: array[0..255] of char;
  778. begin
  779. checkCTRLC;
  780. Dir:='';
  781. if not dos_GetCurrentDirName(tmpbuf,256) then
  782. dosError2InOut(dos_IoErr)
  783. else
  784. Dir:=strpas(tmpbuf);
  785. end;
  786. {****************************************************************************
  787. Low level File Routines
  788. All these functions can set InOutRes on errors
  789. ****************************************************************************}
  790. { close a file from the handle value }
  791. procedure do_close(handle : longint);
  792. begin
  793. RemoveFromList(MOS_fileList,handle);
  794. { Do _NOT_ check CTRL_C on Close, because it will conflict
  795. with System_Exit! }
  796. if not dos_Close(handle) then
  797. dosError2InOut(dos_IoErr);
  798. end;
  799. procedure do_erase(p : pchar);
  800. begin
  801. checkCTRLC;
  802. if not dos_DeleteFile(p) then
  803. dosError2InOut(dos_IoErr);
  804. end;
  805. procedure do_rename(p1,p2 : pchar);
  806. begin
  807. checkCTRLC;
  808. if not dos_Rename(p1,p2) then
  809. dosError2InOut(dos_IoErr);
  810. end;
  811. function do_write(h:longint; addr: pointer; len: longint) : longint;
  812. var dosResult: LongInt;
  813. begin
  814. checkCTRLC;
  815. do_write:=0;
  816. if len<=0 then exit;
  817. dosResult:=dos_Write(h,addr,len);
  818. if dosResult<0 then begin
  819. dosError2InOut(dos_IoErr);
  820. end else begin
  821. do_write:=dosResult;
  822. end;
  823. end;
  824. function do_read(h:longint; addr: pointer; len: longint) : longint;
  825. var dosResult: LongInt;
  826. begin
  827. checkCTRLC;
  828. do_read:=0;
  829. if len<=0 then exit;
  830. dosResult:=dos_Write(h,addr,len);
  831. if dosResult<0 then begin
  832. dosError2InOut(dos_IoErr);
  833. end else begin
  834. do_read:=dosResult;
  835. end
  836. end;
  837. function do_filepos(handle : longint) : longint;
  838. var dosResult: LongInt;
  839. begin
  840. checkCTRLC;
  841. do_filepos:=0;
  842. { Seeking zero from OFFSET_CURRENT to find out where we are }
  843. dosResult:=dos_Seek(handle,0,OFFSET_CURRENT);
  844. if dosResult<0 then begin
  845. dosError2InOut(dos_IoErr);
  846. end else begin
  847. do_filepos:=dosResult;
  848. end;
  849. end;
  850. procedure do_seek(handle,pos : longint);
  851. begin
  852. checkCTRLC;
  853. { Seeking from OFFSET_BEGINNING }
  854. if dos_Seek(handle,pos,OFFSET_BEGINNING)<0 then
  855. dosError2InOut(dos_IoErr);
  856. end;
  857. function do_seekend(handle:longint):longint;
  858. var dosResult: LongInt;
  859. begin
  860. checkCTRLC;
  861. do_seekend:=0;
  862. { Seeking to OFFSET_END }
  863. dosResult:=dos_Seek(handle,0,OFFSET_END);
  864. if dosResult<0 then begin
  865. dosError2InOut(dos_IoErr);
  866. end else begin
  867. do_seekend:=dosResult;
  868. end
  869. end;
  870. function do_filesize(handle : longint) : longint;
  871. var currfilepos: longint;
  872. begin
  873. checkCTRLC;
  874. currfilepos:=do_filepos(handle);
  875. { We have to do this twice, because seek returns the OLD position }
  876. do_filesize:=do_seekend(handle);
  877. do_filesize:=do_seekend(handle);
  878. do_seek(handle,currfilepos)
  879. end;
  880. { truncate at a given position }
  881. procedure do_truncate (handle,pos:longint);
  882. begin
  883. checkCTRLC;
  884. { Seeking from OFFSET_BEGINNING }
  885. if dos_SetFileSize(handle,pos,OFFSET_BEGINNING)<0 then
  886. dosError2InOut(dos_IoErr);
  887. end;
  888. procedure do_open(var f;p:pchar;flags:longint);
  889. {
  890. filerec and textrec have both handle and mode as the first items so
  891. they could use the same routine for opening/creating.
  892. when (flags and $10) the file will be append
  893. when (flags and $100) the file will be truncate/rewritten
  894. when (flags and $1000) there is no check for close (needed for textfiles)
  895. }
  896. var
  897. i,j : LongInt;
  898. openflags : LongInt;
  899. path : String;
  900. buffer : array[0..255] of Char;
  901. index : Integer;
  902. s : String;
  903. begin
  904. path:=strpas(p);
  905. for index:=1 to length(path) do
  906. if path[index]='\' then path[index]:='/';
  907. { remove any dot characters and replace by their current }
  908. { directory equivalent. }
  909. { look for parent directory }
  910. if pos('../',path) = 1 then
  911. begin
  912. delete(path,1,3);
  913. getdir(0,s);
  914. j:=length(s);
  915. while (s[j]<>'/') and (s[j]<>':') and (j>0) do
  916. dec(j);
  917. if j > 0 then
  918. s:=copy(s,1,j);
  919. path:=s+path;
  920. end
  921. else
  922. { look for current directory }
  923. if pos('./',path) = 1 then
  924. begin
  925. delete(path,1,2);
  926. getdir(0,s);
  927. if (s[length(s)]<>'/') and (s[length(s)]<>':') then
  928. s:=s+'/';
  929. path:=s+path;
  930. end;
  931. move(path[1],buffer,length(path));
  932. buffer[length(path)]:=#0;
  933. { close first if opened }
  934. if ((flags and $10000)=0) then
  935. begin
  936. case filerec(f).mode of
  937. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  938. fmclosed : ;
  939. else begin
  940. inoutres:=102; {not assigned}
  941. exit;
  942. end;
  943. end;
  944. end;
  945. { reset file handle }
  946. filerec(f).handle:=UnusedHandle;
  947. { convert filemode to filerec modes }
  948. { READ/WRITE on existing file }
  949. { RESET/APPEND }
  950. openflags := 1005;
  951. case (flags and 3) of
  952. 0 : filerec(f).mode:=fminput;
  953. 1 : filerec(f).mode:=fmoutput;
  954. 2 : filerec(f).mode:=fminout;
  955. end;
  956. { rewrite (create a new file) }
  957. if (flags and $1000)<>0 then openflags := 1006;
  958. { empty name is special }
  959. if p[0]=#0 then
  960. begin
  961. case filerec(f).mode of
  962. fminput :
  963. filerec(f).handle:=StdInputHandle;
  964. fmappend,
  965. fmoutput : begin
  966. filerec(f).handle:=StdOutputHandle;
  967. filerec(f).mode:=fmoutput; {fool fmappend}
  968. end;
  969. end;
  970. exit;
  971. end;
  972. i:=dos_Open(buffer,openflags);
  973. if i=0 then
  974. begin
  975. dosError2InOut(dos_IoErr);
  976. end else begin
  977. AddToList(MOS_fileList,i);
  978. filerec(f).handle:=i;
  979. end;
  980. { append mode }
  981. if ((Flags and $100)<>0) and (FileRec(F).Handle<>UnusedHandle) then
  982. begin
  983. do_seekend(filerec(f).handle);
  984. filerec(f).mode:=fmoutput; {fool fmappend}
  985. end;
  986. end;
  987. function do_isdevice(handle:longint):boolean;
  988. begin
  989. if (handle=StdOutputHandle) or (handle=StdInputHandle) or
  990. (handle=StdErrorHandle) then
  991. do_isdevice:=True
  992. else
  993. do_isdevice:=False;
  994. end;
  995. {*****************************************************************************
  996. UnTyped File Handling
  997. *****************************************************************************}
  998. {$i file.inc}
  999. {*****************************************************************************
  1000. Typed File Handling
  1001. *****************************************************************************}
  1002. {$i typefile.inc}
  1003. {*****************************************************************************
  1004. Text File Handling
  1005. *****************************************************************************}
  1006. {$I text.inc}
  1007. { MorphOS specific startup }
  1008. procedure SysInitMorphOS;
  1009. var self: PProcess;
  1010. begin
  1011. self:=PProcess(exec_FindTask(nil));
  1012. if self^.pr_CLI=0 then begin
  1013. { if we're running from Ambient/Workbench, we catch its message }
  1014. exec_WaitPort(@self^.pr_MsgPort);
  1015. MOS_ambMsg:=exec_GetMsg(@self^.pr_MsgPort);
  1016. end;
  1017. MOS_DOSBase:=exec_OpenLibrary('dos.library',50);
  1018. if MOS_DOSBase=nil then Halt(1);
  1019. MOS_UtilityBase:=exec_OpenLibrary('utility.library',50);
  1020. if MOS_UtilityBase=nil then Halt(1);
  1021. { Creating the memory pool for growing heap }
  1022. MOS_heapPool:=exec_CreatePool(MEMF_FAST,growheapsize2,growheapsize1);
  1023. if MOS_heapPool=nil then Halt(1);
  1024. StdInputHandle:=dos_Input;
  1025. StdOutputHandle:=dos_Output;
  1026. end;
  1027. procedure SysInitStdIO;
  1028. begin
  1029. OpenStdIO(Input,fmInput,StdInputHandle);
  1030. OpenStdIO(Output,fmOutput,StdOutputHandle);
  1031. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  1032. { * MorphOS doesn't have a separate stderr, just like AmigaOS (???) * }
  1033. StdErrorHandle:=StdOutputHandle;
  1034. // OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  1035. end;
  1036. {procedure SysInitExecPath;
  1037. var
  1038. hs : string[16];
  1039. link : string;
  1040. i : longint;
  1041. begin
  1042. str(Fpgetpid,hs);
  1043. hs:='/proc/'+hs+'/exe'#0;
  1044. i:=Fpreadlink(@hs[1],@link[1],high(link));
  1045. { it must also be an absolute filename, linux 2.0 points to a memory
  1046. location so this will skip that }
  1047. if (i>0) and (link[1]='/') then
  1048. begin
  1049. link[0]:=chr(i);
  1050. ExecPathStr:=link;
  1051. end;
  1052. end;
  1053. }
  1054. Begin
  1055. IsConsole := TRUE;
  1056. IsLibrary := FALSE;
  1057. StackLength := InitialStkLen;
  1058. StackBottom := Sptr - StackLength;
  1059. { OS specific startup }
  1060. MOS_ambMsg:=nil;
  1061. MOS_origDir:=0;
  1062. MOS_fileList:=nil;
  1063. SysInitMorphOS;
  1064. { Set up signals handlers }
  1065. // InstallSignals;
  1066. { Setup heap }
  1067. InitHeap;
  1068. // SysInitExceptions;
  1069. { Setup stdin, stdout and stderr }
  1070. SysInitStdIO;
  1071. { Reset IO Error }
  1072. InOutRes:=0;
  1073. { Arguments }
  1074. // SetupCmdLine;
  1075. // SysInitExecPath;
  1076. GenerateArgs;
  1077. (* This should be changed to a real value during *)
  1078. (* thread driver initialization if appropriate. *)
  1079. ThreadID := 1;
  1080. {$ifdef HASVARIANT}
  1081. initvariantmanager;
  1082. {$endif HASVARIANT}
  1083. End.
  1084. {
  1085. $Log$
  1086. Revision 1.8 2004-05-12 20:26:04 karoly
  1087. + added syscalls and structures necessary for DOS unit
  1088. Revision 1.7 2004/05/12 15:34:16 karoly
  1089. * fixed startup code from endless wait when not started from Ambient
  1090. Revision 1.6 2004/05/09 14:42:59 karoly
  1091. * again, few more new things added
  1092. Revision 1.5 2004/05/09 02:02:42 karoly
  1093. * more things got implemented
  1094. Revision 1.4 2004/05/02 02:06:57 karoly
  1095. + most of file I/O calls implemented
  1096. Revision 1.3 2004/05/01 15:09:47 karoly
  1097. * first working system unit (very limited yet)
  1098. Revision 1.2  2004/04/08 06:28:29  karoly
  1099. * first steps to have a morphos system unit
  1100. Revision 1.1 2004/02/13 07:19:53 karoly
  1101. * quick hack from Linux system unit
  1102. }