system.pp 14 KB

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