system.pp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by the Free Pascal development team.
  5. This is a prototype file to show all function that need to be implemented
  6. for a new operating system (provided the processor specific
  7. function are already implemented !)
  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. { no stack check in system }
  15. {$S-}
  16. unit System;
  17. interface
  18. { include system-independent routine headers }
  19. {$I systemh.inc}
  20. type
  21. THandle = longint;
  22. { include heap support headers }
  23. {$I heaph.inc}
  24. {Platform specific information}
  25. const
  26. LineEnding = #10;
  27. LFNSupport = true;
  28. DirectorySeparator = '/';
  29. DriveSeparator = ':';
  30. PathSeparator = ':';
  31. { FileNameCaseSensitive is defined separately below!!! }
  32. maxExitCode = 255;
  33. const
  34. FileNameCaseSensitive : boolean = true;
  35. sLineBreak : string[1] = LineEnding;
  36. DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsLF;
  37. var
  38. argc : longint;
  39. argv : ppchar;
  40. envp : ppchar;
  41. errno : longint; // MvdV: yuckie
  42. UnusedHandle:longint;
  43. StdInputHandle:longint;
  44. StdOutputHandle:longint;
  45. StdErrorHandle:longint;
  46. implementation
  47. {$I sysfiles.inc}
  48. function sys_unlink (a:cardinal;name:pchar):longint; cdecl; external name 'sys_unlink';
  49. function sys_rename (a:cardinal;p1:pchar;b:cardinal;p2:pchar):longint; cdecl; external name 'sys_rename';
  50. function sys_create_area (name:pchar; var start:pointer; a,b,c,d:longint):longint; cdecl; external name 'sys_create_area';
  51. function sys_resize_area (handle:cardinal; size:longint):longint; cdecl; external name 'sys_resize_area';
  52. function sys_mkdir (a:cardinal; name:pchar; mode:cardinal):longint; cdecl; external name 'sys_mkdir';
  53. function sys_chdir (a:cardinal; name:pchar):longint; cdecl; external name 'sys_chdir';
  54. function sys_rmdir (a:cardinal; name:pchar):longint; cdecl; external name 'sys_rmdir';
  55. {$I system.inc}
  56. {*****************************************************************************
  57. System Dependent Exit code
  58. *****************************************************************************}
  59. procedure prthaltproc;external name '_haltproc';
  60. procedure system_exit;
  61. begin
  62. asm
  63. jmp prthaltproc
  64. end;
  65. End;
  66. {*****************************************************************************
  67. Stack check code
  68. *****************************************************************************}
  69. { cheking the stack is done system independend in 1.1
  70. procedure int_stackcheck(stack_size:longint);[public,alias:'FPC_STACKCHECK'];
  71. {
  72. called when trying to get local stack if the compiler directive $S
  73. is set this function must preserve esi !!!! because esi is set by
  74. the calling proc for methods it must preserve all registers !!
  75. With a 2048 byte safe area used to write to StdIo without crossing
  76. the stack boundary
  77. }
  78. begin
  79. end;
  80. }
  81. {*****************************************************************************
  82. ParamStr/Randomize
  83. *****************************************************************************}
  84. { number of args }
  85. function paramcount : longint;
  86. begin
  87. paramcount := argc - 1;
  88. end;
  89. { argument number l }
  90. function paramstr(l : longint) : string;
  91. begin
  92. if (l>=0) and (l+1<=argc) then
  93. paramstr:=strpas(argv[l])
  94. else
  95. paramstr:='';
  96. end;
  97. { set randseed to a new pseudo random value }
  98. procedure randomize;
  99. begin
  100. {regs.realeax:=$2c00;
  101. sysrealintr($21,regs);
  102. hl:=regs.realedx and $ffff;
  103. randseed:=hl*$10000+ (regs.realecx and $ffff);}
  104. randseed:=0;
  105. end;
  106. {*****************************************************************************
  107. Heap Management
  108. *****************************************************************************}
  109. var myheapstart:pointer;
  110. myheapsize:longint;
  111. myheaprealsize:longint;
  112. heap_handle:longint;
  113. zero:longint;
  114. { first address of heap }
  115. function getheapstart:pointer;
  116. begin
  117. getheapstart:=myheapstart;
  118. end;
  119. { current length of heap }
  120. function getheapsize:longint;
  121. begin
  122. getheapsize:=myheapsize;
  123. end;
  124. { function to allocate size bytes more for the program }
  125. { must return the first address of new data space or nil if fail }
  126. function Sbrk(size : longint):pointer;
  127. var newsize,newrealsize:longint;
  128. begin
  129. if (myheapsize+size)<=myheaprealsize then begin
  130. Sbrk:=myheapstart+myheapsize;
  131. myheapsize:=myheapsize+size;
  132. exit;
  133. end;
  134. newsize:=myheapsize+size;
  135. newrealsize:=(newsize and $FFFFF000)+$1000;
  136. if sys_resize_area(heap_handle,newrealsize)=0 then begin
  137. Sbrk:=myheapstart+myheapsize;
  138. myheapsize:=newsize;
  139. myheaprealsize:=newrealsize;
  140. exit;
  141. end;
  142. Sbrk:=nil;
  143. end;
  144. {*****************************************************************************
  145. OS Memory allocation / deallocation
  146. ****************************************************************************}
  147. function SysOSAlloc(size: ptrint): pointer;
  148. begin
  149. result := sbrk(size);
  150. end;
  151. { include standard heap management }
  152. {$I heap.inc}
  153. {****************************************************************************
  154. Low level File Routines
  155. All these functions can set InOutRes on errors
  156. ****************************************************************************}
  157. { close a file from the handle value }
  158. procedure do_close(handle : longint);
  159. begin
  160. { writeln ('CLOSE ',handle);}
  161. if handle<=2 then exit;
  162. InOutRes:=sys_close(handle);
  163. end;
  164. procedure do_erase(p : pchar);
  165. begin
  166. if sys_unlink($FF000000,p)<>0 then InOutRes:=1
  167. else InOutRes:=0;
  168. end;
  169. procedure do_rename(p1,p2 : pchar);
  170. begin
  171. InOutRes:=sys_rename($FF000000,p1,$FF000000,p2);
  172. end;
  173. function do_write(h:longint;addr:pointer;len : longint) : longint;
  174. begin
  175. { if h>0 then begin
  176. sys_write ('WRITE handle=%d ',h);
  177. printf ('addr=%x ',addr);
  178. printf ('len=%d',len);
  179. printf ('%c',10);
  180. end;}
  181. do_write:=sys_write (h,addr,len,zero);
  182. if (do_write<0) then begin
  183. InOutRes:=do_write;
  184. do_write:=0;
  185. end else InOutRes:=0;
  186. end;
  187. function do_read(h:longint;addr:pointer;len : longint) : longint;
  188. begin
  189. { if h>2 then begin
  190. printf ('READ handle=%d ',h);
  191. printf ('addr=%x ',addr);
  192. printf ('len=%d',len);
  193. end;}
  194. do_read:=sys_read (h,addr,len,zero);
  195. if (do_read<0) then begin
  196. InOutRes:=do_read;
  197. do_read:=0;
  198. end else InOutRes:=0;
  199. end;
  200. function do_filepos(handle : longint) : longint;
  201. begin
  202. do_filepos:=sys_lseek(handle,0,1); {1=SEEK_CUR}
  203. if (do_filepos<0) then begin
  204. InOutRes:=do_filepos;
  205. do_filepos:=0;
  206. end else InOutRes:=0;
  207. end;
  208. procedure do_seek(handle,pos : longint);
  209. begin
  210. InOutRes:=sys_lseek(handle,pos,0);
  211. if InOutRes>0 then InOutRes:=0;
  212. end;
  213. function do_seekend(handle:longint):longint;
  214. begin
  215. do_seekend:=sys_lseek (handle,0,2); {2=SEEK_END}
  216. if do_seekend<0 then begin
  217. InOutRes:=do_seekend;
  218. do_seekend:=0;
  219. end else InOutRes:=0;
  220. end;
  221. function do_filesize(handle : longint) : longint;
  222. var cur:longint;
  223. begin
  224. cur:=sys_lseek (handle,0,1); {1=SEEK_CUR}
  225. if cur<0 then begin
  226. InOutRes:=cur;
  227. do_filesize:=0;
  228. exit;
  229. end;
  230. do_filesize:=sys_lseek (handle,0,2); {2=SEEK_END}
  231. if do_filesize<0 then begin
  232. InOutRes:=do_filesize;
  233. do_filesize:=0;
  234. exit;
  235. end;
  236. cur:=sys_lseek (handle,cur,0); {0=SEEK_POS}
  237. if cur<0 then begin
  238. InOutRes:=cur;
  239. do_filesize:=0;
  240. exit;
  241. end;
  242. end;
  243. { truncate at a given position }
  244. procedure do_truncate (handle,pos:longint);
  245. begin
  246. InOutRes:=1;
  247. end;
  248. procedure do_open(var f;p:pchar;flags:longint);
  249. {
  250. filerec and textrec have both handle and mode as the first items so
  251. they could use the same routine for opening/creating.
  252. when (flags and $100) the file will be append
  253. when (flags and $1000) the file will be truncate/rewritten
  254. when (flags and $10000) there is no check for close (needed for textfiles)
  255. }
  256. var m:longint;
  257. mode,h:longint;
  258. begin
  259. { printf ('OPEN %d ',longint(f));
  260. printf (' %s',longint(p));
  261. printf (' %x',flags);}
  262. m:=0;
  263. case (flags and $3) of
  264. $0: begin m:=m or O_RDONLY; mode:=fminput; end;
  265. $1: begin m:=m or O_WRONLY; mode:=fmoutput;end;
  266. $2: begin m:=m or O_RDWR; mode:=fminout; end;
  267. end;
  268. if (flags and $100)<>0 then m:=m or O_APPEND;
  269. if (flags and $1000)<>0 then m:=m or O_TRUNC or O_CREAT;
  270. { if (flags and $10000)<>0 then m:=m or O_TEXT else m:=m or O_BINARY;}
  271. h:=sys_open($FF000000,p,m,0,0);
  272. if h<0 then InOutRes:=h
  273. else InOutRes:=0;
  274. if InOutRes=0 then begin
  275. FileRec(f).handle:=h;
  276. FileRec(f).mode:=mode;
  277. end;
  278. end;
  279. function do_isdevice(handle:THandle):boolean;
  280. begin
  281. do_isdevice:=false;
  282. InOutRes:=0;
  283. end;
  284. {*****************************************************************************
  285. UnTyped File Handling
  286. *****************************************************************************}
  287. {$i file.inc}
  288. {*****************************************************************************
  289. Typed File Handling
  290. *****************************************************************************}
  291. {$i typefile.inc}
  292. {*****************************************************************************
  293. Text File Handling
  294. *****************************************************************************}
  295. { should we consider #26 as the end of a file ? }
  296. {?? $DEFINE EOF_CTRLZ}
  297. {$i text.inc}
  298. {*****************************************************************************
  299. Directory Handling
  300. *****************************************************************************}
  301. procedure mkdir(const s : string);[IOCheck];
  302. var t:string;
  303. begin
  304. t:=s+#0;
  305. InOutRes:=sys_mkdir ($FF000000,@t[1],493);
  306. end;
  307. procedure rmdir(const s : string);[IOCheck];
  308. var t:string;
  309. begin
  310. t:=s+#0;
  311. InOutRes:=sys_rmdir ($FF000000,@t[1]);
  312. end;
  313. procedure chdir(const s : string);[IOCheck];
  314. var t:string;
  315. begin
  316. t:=s+#0;
  317. InOutRes:=sys_chdir ($FF000000,@t[1]);
  318. end;
  319. {*****************************************************************************
  320. getdir procedure
  321. *****************************************************************************}
  322. type dirent = packed record
  323. d_dev:longint;
  324. d_pdev:longint;
  325. d_ino:int64;
  326. d_pino:int64;
  327. d_reclen:word;
  328. d_name:array[0..255] of char;
  329. end;
  330. stat = packed record
  331. dev:longint; {"device" that this file resides on}
  332. ino:int64; {this file's inode #, unique per device}
  333. mode:dword; {mode bits (rwx for user, group, etc)}
  334. nlink:longint; {number of hard links to this file}
  335. uid:dword; {user id of the owner of this file}
  336. gid:dword; {group id of the owner of this file}
  337. size:int64; {size of this file (in bytes)}
  338. rdev:longint; {device type (not used)}
  339. blksize:longint; {preferref block size for i/o}
  340. atime:longint; {last access time}
  341. mtime:longint; {last modification time}
  342. ctime:longint; {last change time, not creation time}
  343. crtime:longint; {creation time}
  344. end;
  345. pstat = ^stat;
  346. function sys_stat (a:cardinal;path:pchar;info:pstat;n:longint):longint; cdecl; external name 'sys_stat';
  347. function FStat(Path:String;Var Info:stat):Boolean;
  348. {
  349. Get all information on a file, and return it in Info.
  350. }
  351. var tmp:string;
  352. var p:pchar;
  353. begin
  354. tmp:=path+#0;
  355. p:=@tmp[1];
  356. FStat:=(sys_stat($FF000000,p,@Info,0)=0);
  357. end;
  358. function sys_opendir (a:cardinal;path:pchar;b:longint):longint; cdecl; external name 'sys_opendir';
  359. function sys_readdir (fd:longint;var de:dirent;a:longint;b:byte):longint; cdecl; external name 'sys_readdir';
  360. function parentdir(fd:longint;dev:longint;ino:int64;var err:longint):string;
  361. var len:longint;
  362. ent:dirent;
  363. name:string;
  364. begin
  365. err:=0;
  366. parentdir:='';
  367. if sys_readdir(fd,ent,$11C,1)=0 then begin
  368. err:=1;
  369. exit;
  370. end;
  371. len:=StrLen(@ent.d_name);
  372. Move(ent.d_name,name[1],len);
  373. name[0]:=chr(len);
  374. { writeln ('NAME: "',name,'" = ',ent.d_dev,',',ent.d_ino);}
  375. if (dev=ent.d_dev) and (ino=ent.d_ino) then begin
  376. err:=0;
  377. parentdir:='/'+name;
  378. exit;
  379. end;
  380. err:=0;
  381. end;
  382. function getdir2:string;
  383. var tmp:string;
  384. info:stat;
  385. info2:stat;
  386. fd:longint;
  387. name:string;
  388. cur:string;
  389. res:string;
  390. err:longint;
  391. begin
  392. res:='';
  393. cur:='';
  394. repeat
  395. FStat(cur+'.',info);
  396. FStat(cur+'..',info2);
  397. { writeln ('"." = ',info.dev,',',info.ino);}
  398. if ((info.dev=info2.dev) and (info.ino=info2.ino)) then begin
  399. if res='' then getdir2:='/' else getdir2:=res;
  400. exit;
  401. end;
  402. tmp:=cur+'..'+#0;
  403. fd:=sys_opendir ($FF000000,@tmp[1],0);
  404. repeat
  405. name:=parentdir(fd,info.dev,info.ino,err);
  406. until (err<>0) or (name<>'');
  407. if err<>0 then begin
  408. getdir2:='';
  409. exit;
  410. end;
  411. res:=name+res;
  412. { writeln(res);}
  413. cur:=cur+'../';
  414. until false;
  415. end;
  416. procedure getdir(drivenr : byte;var dir : shortstring);
  417. begin
  418. drivenr:=0;
  419. dir:=getdir2;
  420. end;
  421. {*****************************************************************************
  422. SystemUnit Initialization
  423. *****************************************************************************}
  424. procedure SysInitStdIO;
  425. begin
  426. { Setup stdin, stdout and stderr, for GUI apps redirect stderr,stdout to be
  427. displayed in and messagebox }
  428. StdInputHandle:=0;
  429. StdOutputHandle:=1;
  430. StdErrorHandle:=2;
  431. OpenStdIO(Input,fmInput,StdInputHandle);
  432. OpenStdIO(Output,fmOutput,StdOutputHandle);
  433. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  434. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  435. end;
  436. begin
  437. { Setup heap }
  438. zero:=0;
  439. myheapsize:=$2000;
  440. myheaprealsize:=$2000;
  441. myheapstart:=nil;
  442. heap_handle:=sys_create_area('fpcheap',myheapstart,0,myheaprealsize,0,3);//!!
  443. if heap_handle>0 then begin
  444. InitHeap;
  445. end else system_exit;
  446. SysInitExceptions;
  447. { Setup IO }
  448. SysInitStdIO;
  449. { Reset IO Error }
  450. InOutRes:=0;
  451. (* This should be changed to a real value during *)
  452. (* thread driver initialization if appropriate. *)
  453. ThreadID := 1;
  454. {$ifdef HASVARIANT}
  455. initvariantmanager;
  456. {$endif HASVARIANT}
  457. end.
  458. {
  459. $Log$
  460. Revision 1.16 2004-09-18 11:18:44 hajny
  461. * handle type changed to thandle in do_isdevice
  462. Revision 1.15 2004/09/03 19:25:32 olle
  463. + added maxExitCode to all System.pp
  464. * constrained error code to be below maxExitCode in RunError et. al.
  465. Revision 1.14 2004/06/21 18:50:51 olle
  466. + cleanup
  467. Revision 1.13 2004/06/17 16:16:13 peter
  468. * New heapmanager that releases memory back to the OS, donated
  469. by Micha Nelissen
  470. Revision 1.12 2004/04/22 21:10:56 peter
  471. * do_read/do_write addr argument changed to pointer
  472. Revision 1.11 2004/01/20 23:09:14 hajny
  473. * ExecuteProcess fixes, ProcessID and ThreadID added
  474. Revision 1.10 2003/10/25 23:42:35 hajny
  475. * THandle in sysutils common using System.THandle
  476. Revision 1.9 2003/09/27 11:52:35 peter
  477. * sbrk returns pointer
  478. Revision 1.8 2003/01/08 22:32:28 marco
  479. * Small fixes and quick merge with 1.0.x. At least the compiler builds now,
  480. but it could crash hard, since there are lots of unimplemented funcs.
  481. Revision 1.7 2003/01/05 20:22:24 florian
  482. - removed stack check, it's system independend in 1.1
  483. Revision 1.6 2003/01/05 20:06:30 florian
  484. + fixed missing SysInitStdIO
  485. Revision 1.5 2002/10/13 09:25:31 florian
  486. + call to initvariantmanager inserted
  487. Revision 1.4 2002/09/07 16:01:17 peter
  488. * old logs removed and tabs fixed
  489. }