dos.pp 15 KB

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