system.pp 14 KB

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