dos.pp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  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. Dos unit for BP7 compatible RTL
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit dos;
  13. interface
  14. uses beos;
  15. const
  16. FileNameLen=255;
  17. type
  18. ComStr = String[FileNameLen];
  19. PathStr = String[FileNameLen];
  20. DirStr = String[FileNameLen];
  21. NameStr = String[FileNameLen];
  22. ExtStr = String[FileNameLen];
  23. Const
  24. {Bitmasks for CPU Flags}
  25. fcarry = $0001;
  26. fparity = $0004;
  27. fauxiliary = $0010;
  28. fzero = $0040;
  29. fsign = $0080;
  30. foverflow = $0800;
  31. {Bitmasks for file attribute}
  32. readonly = $01;
  33. hidden = $02;
  34. sysfile = $04;
  35. volumeid = $08;
  36. directory = $10;
  37. archive = $20;
  38. anyfile = $3F;
  39. {File Status}
  40. fmclosed = $D7B0;
  41. fminput = $D7B1;
  42. fmoutput = $D7B2;
  43. fminout = $D7B3;
  44. S_IFMT = $F000; { type of file }
  45. S_IFLNK = $A000; { symbolic link }
  46. S_IFREG = $8000; { regular }
  47. S_IFBLK = $6000; { block special }
  48. S_IFDIR = $4000; { directory }
  49. S_IFCHR = $2000; { character special }
  50. S_IFIFO = $1000; { fifo }
  51. {
  52. filerec.inc contains the definition of the filerec.
  53. textrec.inc contains the definition of the textrec.
  54. It is in a separate file to make it available in other units without
  55. having to use the DOS unit for it.
  56. }
  57. {$i filerec.inc}
  58. {$i textrec.inc}
  59. DateTime = packed record
  60. Year,
  61. Month,
  62. Day,
  63. Hour,
  64. Min,
  65. Sec : word;
  66. End;
  67. searchrec = record
  68. fd : longint;
  69. path : string;
  70. fname : string;
  71. attr : byte;
  72. time : longint;
  73. size : longint;
  74. name : string[255];
  75. end;
  76. Var
  77. DosError : integer;
  78. {Info/Date/Time}
  79. Procedure GetDate(var year, month, mday, wday: word);
  80. procedure GetTime(var hour,min,sec,msec,usec:word);
  81. procedure GetTime(var hour,min,sec,sec100:word);
  82. procedure GetTime(Var Hour,Min,Sec:Word);
  83. Procedure UnpackTime(p: longint; var t: datetime);
  84. Procedure PackTime(var t: datetime; var p: longint);
  85. {Exec}
  86. Procedure Exec(const path: pathstr; const comline: comstr);
  87. Function DosExitCode: word;
  88. {Disk}
  89. Procedure FindFirst(const path: pathstr; attr: word; var f: searchRec);
  90. Procedure FindNext(var f: searchRec);
  91. Procedure FindClose(var f: searchRec);
  92. {File}
  93. {Procedure GetFAttr(var f:File; var attr: word);}
  94. procedure GetFTime(var f:File; var time: longint);
  95. procedure GetFTime(f:string; var time: longint);
  96. Procedure SetFTime(var f:File; time : longint);
  97. Function FSearch(path: pathstr; dirlist: string): pathstr;
  98. Function FExpand(const path: pathstr): pathstr;
  99. Procedure FSplit(path: pathstr; var dir: dirstr; var name: namestr; var ext: extstr);
  100. {Environment}
  101. {Function EnvCount: longint;
  102. Function EnvStr(index: integer): string;}
  103. {Misc}
  104. {Procedure SetFAttr(var f; attr: word);
  105. Procedure SetFTime(var f; time: longint);
  106. Procedure GetVerify(var verify: boolean);
  107. Procedure SetVerify(verify: boolean);}
  108. {Do Nothing Functions}
  109. Procedure SwapVectors;
  110. {Procedure GetIntVec(intno: byte; var vector: pointer);
  111. Procedure SetIntVec(intno: byte; vector: pointer);
  112. Procedure Keep(exitcode: word);}
  113. function GetEnv(EnvVar: String): String;
  114. Procedure EpochToLocal(epoch:longint;var year,month,day,hour,minute,second:Word);
  115. implementation
  116. uses strings;
  117. procedure GetFTime(var f:file; var time: longint);
  118. var info:stat;
  119. t:longint;
  120. dt:DateTime;
  121. begin
  122. if not FStat(F,Info) then begin
  123. t:=0;
  124. doserror:=3;
  125. exit;
  126. end else t:=info.ctime;
  127. EpochToLocal(t,dt.year,dt.month,dt.day,dt.hour,dt.min,dt.sec);
  128. packtime(dt,time);
  129. end;
  130. procedure GetFTime(f:string; var time: longint);
  131. var info:stat;
  132. t:longint;
  133. dt:DateTime;
  134. begin
  135. if not FStat(F,Info) then begin
  136. t:=0;
  137. doserror:=3;
  138. exit;
  139. end else t:=info.ctime;
  140. EpochToLocal(t,dt.year,dt.month,dt.day,dt.hour,dt.min,dt.sec);
  141. packtime(dt,time);
  142. end;
  143. type utimbuf=record actime,modtime:longint; end;
  144. {function _utime (path:pchar;var buf:utimbuf):longint; cdecl; external name 'utime';}
  145. Procedure setftime(var f:file; time : longint);
  146. {var buf:utimbuf;}
  147. begin
  148. { buf.actime:=time;
  149. buf.modtime:=time;}
  150. { writeln ('SetFTime ',PChar(@FileRec(f).Name),' := ',time);}
  151. { if _utime(PChar(@FileRec(f).Name),buf)<>0 then doserror:=3;}
  152. end;
  153. {******************************************************************************
  154. --- Info / Date / Time ---
  155. ******************************************************************************}
  156. procedure getdate(var year,month,mday,wday : word);
  157. begin
  158. end;
  159. function sys_time:longint; cdecl; external name 'sys_time';
  160. procedure GetTime(var hour,min,sec,msec,usec:word);
  161. {
  162. Gets the current time, adjusted to local time
  163. }
  164. var
  165. year,day,month:Word;
  166. t : longint;
  167. begin
  168. t:=sys_time;
  169. EpochToLocal(t,year,month,day,hour,min,sec);
  170. msec:=0;
  171. usec:=0;
  172. end;
  173. procedure GetTime(var hour,min,sec,sec100:word);
  174. { Gets the current time, adjusted to local time }
  175. var usec : word;
  176. begin
  177. gettime(hour,min,sec,sec100,usec);
  178. sec100:=sec100 div 10;
  179. end;
  180. procedure GetTime(Var Hour,Min,Sec:Word);
  181. {
  182. Gets the current time, adjusted to local time
  183. }
  184. var
  185. msec,usec : Word;
  186. Begin
  187. gettime(hour,min,sec,msec,usec);
  188. end;
  189. Procedure packtime(var t : datetime;var p : longint);
  190. Begin
  191. p:=(t.sec shr 1)+(t.min shl 5)+(t.hour shl 11)+(t.day shl 16)+(t.month shl 21)+((t.year-1980) shl 25);
  192. End;
  193. Procedure unpacktime(p : longint;var t : datetime);
  194. Begin
  195. with t do
  196. begin
  197. sec:=(p and 31) shl 1;
  198. min:=(p shr 5) and 63;
  199. hour:=(p shr 11) and 31;
  200. day:=(p shr 16) and 31;
  201. month:=(p shr 21) and 15;
  202. year:=(p shr 25)+1980;
  203. end;
  204. End;
  205. {******************************************************************************
  206. --- Exec ---
  207. ******************************************************************************}
  208. Procedure Exec(const path: pathstr; const comline: comstr);
  209. var p:string;
  210. begin
  211. p:=path+' '+comline;
  212. doserror:=beos.shell(p);
  213. end;
  214. Function DosExitCode: word;
  215. begin
  216. dosexitcode:=doserror;
  217. end;
  218. {******************************************************************************
  219. --- File ---
  220. ******************************************************************************}
  221. Procedure FSplit(Path: PathStr; Var Dir: DirStr; Var Name: NameStr;Var Ext: ExtStr);
  222. Begin
  223. beos.FSplit(Path,Dir,Name,Ext);
  224. End;
  225. Function FExpand(Const Path: PathStr): PathStr;
  226. Begin
  227. FExpand:=beos.FExpand(Path);
  228. End;
  229. Function FSearch(path : pathstr;dirlist : string) : pathstr;
  230. Var info:stat;
  231. Begin
  232. if (length(Path)>0) and (path[1]='/') and FStat(path,info) then
  233. FSearch:=path
  234. else
  235. FSearch:=beos.FSearch(path,dirlist);
  236. End;
  237. {******************************************************************************
  238. --- Findfirst FindNext ---
  239. ******************************************************************************}
  240. {procedure dossearchrec2searchrec(var f : searchrec);
  241. var
  242. len : longint;
  243. begin
  244. len:=StrLen(@f.Name);
  245. Move(f.Name[0],f.Name[1],Len);
  246. f.Name[0]:=chr(len);
  247. end;}
  248. type dirent = packed record
  249. d_dev:longint;
  250. d_pdev:longint;
  251. d_ino:int64;
  252. d_pino:int64;
  253. d_reclen:word;
  254. d_name:array[0..255] of char;
  255. end;
  256. function sys_opendir (a:dword;path:pchar;b:longint):longint; cdecl; external name 'sys_opendir';
  257. function sys_readdir (fd:longint;var de:dirent;a:longint;b:byte):longint; cdecl; external name 'sys_readdir';
  258. procedure findnext(var f : searchRec);
  259. var len:longint;
  260. ent:dirent;
  261. info:stat;
  262. dt:DateTime;
  263. begin
  264. if sys_readdir(f.fd,ent,$11C,1)=0 then begin
  265. doserror:=3;
  266. exit;
  267. end;
  268. { writeln ('NAME: ',pchar(@ent.d_name[0]));}
  269. len:=StrLen(@ent.d_name);
  270. Move(ent.d_name,f.name[1],len);
  271. f.name[0]:=chr(len);
  272. { writeln ('NAME: "',f.path+f.name,'"');}
  273. if not FStat(f.path+f.name,info) then begin
  274. writeln ('NOT FOUND');
  275. doserror:=3;
  276. exit;
  277. end;
  278. writeln ('OK');
  279. f.size:=info.size;
  280. f.attr:=0;
  281. if (info.mode and S_IFMT)=S_IFDIR then f.attr:=directory;
  282. EpochToLocal(info.mtime,dt.year,dt.month,dt.day,dt.hour,dt.min,dt.sec);
  283. packtime(dt,f.time);
  284. doserror:=0;
  285. end;
  286. procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
  287. var tmp:string;
  288. info:stat;
  289. ext:string;
  290. begin
  291. tmp:=path;
  292. if tmp='' then tmp:='.';
  293. if FStat(tmp,info) then begin
  294. if ((info.mode and S_IFMT)=S_IFDIR) and (tmp[length(tmp)]<>'/') then tmp:=tmp+'/';
  295. end;
  296. FSplit (tmp,f.path,f.fname,ext);
  297. { f.path:=FExpand(f.path);}
  298. f.fname:=f.fname+ext;
  299. if length(f.fname)=0 then f.fname:='*';
  300. tmp:=tmp+#0;
  301. f.fd:=sys_opendir ($FF000000,@tmp[1],0);
  302. writeln ('F.PATH=',f.path,' ; ',f.fname);
  303. findnext(f);
  304. end;
  305. Procedure FindClose(Var f: SearchRec);
  306. begin
  307. DosError:=0;
  308. end;
  309. procedure swapvectors;
  310. begin
  311. { no beos equivalent }
  312. DosError:=0;
  313. end;
  314. {******************************************************************************
  315. --- Environment ---
  316. ******************************************************************************}
  317. function envcount : longint;
  318. var
  319. hp : ppchar;
  320. begin
  321. hp:=envp;
  322. envcount:=0;
  323. while assigned(hp^) do
  324. begin
  325. inc(envcount);
  326. hp:=hp+4;
  327. end;
  328. end;
  329. function envstr(index : integer) : string;
  330. begin
  331. if (index<=0) or (index>envcount) then
  332. begin
  333. envstr:='';
  334. exit;
  335. end;
  336. envstr:=strpas(ppchar(envp+4*(index-1))^);
  337. end;
  338. {******************************************************************************
  339. --- Not Supported ---
  340. ******************************************************************************}
  341. Procedure keep(exitcode : word);
  342. Begin
  343. End;
  344. Procedure getintvec(intno : byte;var vector : pointer);
  345. Begin
  346. End;
  347. Procedure setintvec(intno : byte;vector : pointer);
  348. Begin
  349. End;
  350. {******************************************************************************
  351. Date and Time related calls
  352. ******************************************************************************}
  353. Const
  354. {Date Translation}
  355. C1970=2440588;
  356. D0 = 1461;
  357. D1 = 146097;
  358. D2 =1721119;
  359. Procedure JulianToGregorian(JulianDN:LongInt;Var Year,Month,Day:Word);
  360. Var
  361. YYear,XYear,Temp,TempMonth : LongInt;
  362. Begin
  363. Temp:=((JulianDN-D2) shl 2)-1;
  364. JulianDN:=Temp Div D1;
  365. XYear:=(Temp Mod D1) or 3;
  366. YYear:=(XYear Div D0);
  367. Temp:=((((XYear mod D0)+4) shr 2)*5)-3;
  368. Day:=((Temp Mod 153)+5) Div 5;
  369. TempMonth:=Temp Div 153;
  370. If TempMonth>=10 Then
  371. Begin
  372. inc(YYear);
  373. dec(TempMonth,12);
  374. End;
  375. inc(TempMonth,3);
  376. Month := TempMonth;
  377. Year:=YYear+(JulianDN*100);
  378. end;
  379. Procedure EpochToLocal(epoch:longint;var year,month,day,hour,minute,second:Word);
  380. { Transforms Epoch time into local time (hour, minute,seconds) }
  381. Var
  382. DateNum: LongInt;
  383. Begin
  384. Datenum:=(Epoch Div 86400) + c1970;
  385. JulianToGregorian(DateNum,Year,Month,day);
  386. Epoch:=Epoch Mod 86400;
  387. Hour:=Epoch Div 3600;
  388. Epoch:=Epoch Mod 3600;
  389. Minute:=Epoch Div 60;
  390. Second:=Epoch Mod 60;
  391. End;
  392. {
  393. $Log$
  394. Revision 1.2 2001-06-19 20:46:07 hajny
  395. * platform specific constants moved after systemh.inc, BeOS omission corrected
  396. Revision 1.1 2001/06/02 19:26:03 peter
  397. * BeOS target!
  398. Revision 1.5 2000/01/07 16:41:29 daniel
  399. * copyright 2000
  400. Revision 1.4 2000/01/07 16:32:23 daniel
  401. * copyright 2000 added
  402. Revision 1.3 1999/01/22 16:22:09 pierre
  403. * Daniel removal of findclose reverted
  404. Revision 1.2 1999/01/22 10:07:02 daniel
  405. - Findclose removed: This is TP incompatible!!
  406. Revision 1.1 1998/12/21 13:07:02 peter
  407. * use -FE
  408. Revision 1.19 1998/11/23 13:53:59 peter
  409. * more fexpand fixes from marco van de voort
  410. Revision 1.18 1998/11/23 12:48:02 peter
  411. * fexpand('o:') fixed to return o:\ (from the mailinglist)
  412. Revision 1.17 1998/11/22 09:33:21 florian
  413. * fexpand bug (temp. strings were too shoort) fixed, was reported
  414. by Marco van de Voort
  415. Revision 1.16 1998/11/17 09:37:41 pierre
  416. * explicit conversion from word dosreg.ax to integer doserror
  417. Revision 1.15 1998/11/01 20:27:18 peter
  418. * fixed some doserror settings
  419. Revision 1.14 1998/10/22 15:05:28 pierre
  420. * fsplit adapted to long filenames
  421. Revision 1.13 1998/09/16 16:47:24 peter
  422. * merged fixes
  423. Revision 1.11.2.2 1998/09/16 16:16:04 peter
  424. * go32v1 compiles again
  425. Revision 1.12 1998/09/11 12:46:44 pierre
  426. * range check problem with LFN attr removed
  427. Revision 1.11.2.1 1998/09/11 12:38:41 pierre
  428. * conversion from LFN attr to Dos attr did not respect range checking
  429. Revision 1.11 1998/08/28 10:45:58 peter
  430. * fixed path buffer in findfirst
  431. Revision 1.10 1998/08/27 10:30:48 pierre
  432. * go32v1 RTL did not compile (LFNsupport outside go32v2 defines !)
  433. I renamed tb_selector to tb_segment because
  434. it is a real mode segment as opposed to
  435. a protected mode selector
  436. Fixed it for go32v1 (remove the $E0000000 offset !)
  437. Revision 1.9 1998/08/26 10:04:01 peter
  438. * new lfn check from mailinglist
  439. * renamed win95 -> LFNSupport
  440. + tb_selector, tb_offset for easier access to transferbuffer
  441. Revision 1.8 1998/08/16 20:39:49 peter
  442. + LFN Support
  443. Revision 1.7 1998/08/16 09:12:13 michael
  444. Corrected fexpand behaviour.
  445. Revision 1.6 1998/08/05 21:01:50 michael
  446. applied bugfix from maillist to fsearch
  447. Revision 1.5 1998/05/31 14:18:13 peter
  448. * force att or direct assembling
  449. * cleanup of some files
  450. Revision 1.4 1998/05/22 00:39:22 peter
  451. * go32v1, go32v2 recompiles with the new objects
  452. * remake3 works again with go32v2
  453. - removed some "optimizes" from daniel which were wrong
  454. Revision 1.3 1998/05/21 19:30:47 peter
  455. * objects compiles for linux
  456. + assign(pchar), assign(char), rename(pchar), rename(char)
  457. * fixed read_text_as_array
  458. + read_text_as_pchar which was not yet in the rtl
  459. }
  460. Function StringToPPChar(Var S:STring):ppchar;
  461. {
  462. Create a PPChar to structure of pchars which are the arguments specified
  463. in the string S. Especially usefull for creating an ArgV for Exec-calls
  464. }
  465. var
  466. nr : longint;
  467. Buf : ^char;
  468. p : ppchar;
  469. begin
  470. s:=s+#0;
  471. buf:=@s[1];
  472. nr:=0;
  473. while(buf^<>#0) do
  474. begin
  475. while (buf^ in [' ',#8,#10]) do
  476. inc(buf);
  477. inc(nr);
  478. while not (buf^ in [' ',#0,#8,#10]) do
  479. inc(buf);
  480. end;
  481. getmem(p,nr*4);
  482. StringToPPChar:=p;
  483. if p=nil then
  484. begin
  485. { LinuxError:=sys_enomem;}
  486. exit;
  487. end;
  488. buf:=@s[1];
  489. while (buf^<>#0) do
  490. begin
  491. while (buf^ in [' ',#8,#10]) do
  492. begin
  493. buf^:=#0;
  494. inc(buf);
  495. end;
  496. p^:=buf;
  497. inc(p);
  498. p^:=nil;
  499. while not (buf^ in [' ',#0,#8,#10]) do
  500. inc(buf);
  501. end;
  502. end;
  503. Function Dirname(Const path:pathstr):pathstr;
  504. {
  505. This function returns the directory part of a complete path.
  506. Unless the directory is root '/', The last character is not
  507. a slash.
  508. }
  509. var
  510. Dir : PathStr;
  511. Name : NameStr;
  512. Ext : ExtStr;
  513. begin
  514. FSplit(Path,Dir,Name,Ext);
  515. if length(Dir)>1 then
  516. Delete(Dir,length(Dir),1);
  517. DirName:=Dir;
  518. end;
  519. Function Basename(Const path:pathstr;Const suf:pathstr):pathstr;
  520. {
  521. This function returns the filename part of a complete path. If suf is
  522. supplied, it is cut off the filename.
  523. }
  524. var
  525. Dir : PathStr;
  526. Name : NameStr;
  527. Ext : ExtStr;
  528. begin
  529. FSplit(Path,Dir,Name,Ext);
  530. if Suf<>Ext then
  531. Name:=Name+Ext;
  532. BaseName:=Name;
  533. end;
  534. function GetEnv(EnvVar: String): String;
  535. var p:pchar;
  536. begin
  537. p:=beos.GetEnv(EnvVar);
  538. if p=nil then
  539. GetEnv:=''
  540. else
  541. GetEnv:=StrPas(p);
  542. end;
  543. end.