dos.pp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Michael Van Canneyt and Peter Vreman,
  4. members of the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. Unit Dos;
  12. Interface
  13. Const
  14. FileNameLen = 255;
  15. Type
  16. SearchRec =
  17. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  18. packed
  19. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  20. Record
  21. {Fill : array[1..21] of byte; Fill replaced with below}
  22. // SearchPos : TOff; {directory position}
  23. SearchNum : LongInt; {to track which search this is}
  24. DirPtr : Pointer; {directory pointer for reading directory}
  25. SearchType : Byte; {0=normal, 1=open will close, 2=only 1 file}
  26. SearchAttr : Byte; {attribute we are searching for}
  27. Mode : Word;
  28. Fill : Array[1..1] of Byte; {future use}
  29. {End of fill}
  30. Attr : Byte; {attribute of found file}
  31. Time : LongInt; {last modify date of found file}
  32. Size : LongInt; {file size of found file}
  33. Reserved : Word; {future use}
  34. Name : String[FileNameLen]; {name of found file}
  35. SearchSpec : String[FileNameLen]; {search pattern}
  36. NamePos : Word; {end of path, start of name position}
  37. End;
  38. {$DEFINE HAS_FILENAMELEN}
  39. {$i dosh.inc}
  40. {Extra Utils}
  41. //function weekday(y,m,d : longint) : longint; platform;
  42. Procedure WasiDateToDt(NanoSecsPast: UInt64; Var Dt: DateTime); platform;
  43. //Function DTToUnixDate(DT: DateTime): LongInt; platform;
  44. {Disk}
  45. //Function AddDisk(const path:string) : byte; platform;
  46. Implementation
  47. Uses
  48. WasiAPI;
  49. {$DEFINE HAS_GETMSCOUNT}
  50. {$DEFINE FPC_FEXPAND_TILDE} { Tilde is expanded to home }
  51. {$DEFINE FPC_FEXPAND_GETENVPCHAR} { GetEnv result is a PChar }
  52. {$I dos.inc}
  53. {******************************************************************************
  54. --- Link C Lib if set ---
  55. ******************************************************************************}
  56. {type
  57. RtlInfoType = Record
  58. FMode,
  59. FInode,
  60. FUid,
  61. FGid,
  62. FSize,
  63. FMTime : LongInt;
  64. End;}
  65. {******************************************************************************
  66. --- Info / Date / Time ---
  67. ******************************************************************************}
  68. Function DosVersion:Word;
  69. Begin
  70. End;
  71. (*function WeekDay (y,m,d:longint):longint;
  72. {
  73. Calculates th day of the week. returns -1 on error
  74. }
  75. var
  76. u,v : longint;
  77. begin
  78. if (m<1) or (m>12) or (y<1600) or (y>4000) or
  79. (d<1) or (d>30+((m+ord(m>7)) and 1)-ord(m=2)) or
  80. ((m*d=58) and (((y mod 4>0) or (y mod 100=0)) and (y mod 400>0))) then
  81. WeekDay:=-1
  82. else
  83. begin
  84. u:=m;
  85. v:=y;
  86. if m<3 then
  87. begin
  88. inc(u,12);
  89. dec(v);
  90. end;
  91. WeekDay:=(d+2*u+((3*(u+1)) div 5)+v+(v div 4)-(v div 100)+(v div 400)+1) mod 7;
  92. end;
  93. end;*)
  94. Procedure GetDate(Var Year, Month, MDay, WDay: Word);
  95. begin
  96. end;
  97. procedure SetTime(Hour,Minute,Second,sec100:word);
  98. begin
  99. end;
  100. procedure SetDate(Year,Month,Day:Word);
  101. begin
  102. end;
  103. Function SetDateTime(Year,Month,Day,hour,minute,second:Word) : Boolean;
  104. begin
  105. end;
  106. Procedure GetTime(Var Hour, Minute, Second, Sec100: Word);
  107. begin
  108. end;
  109. Procedure WasiDateToDt(NanoSecsPast: UInt64; Var Dt: DateTime);
  110. const
  111. days_in_month: array [boolean, 1..12] of Byte =
  112. ((31,28,31,30,31,30,31,31,30,31,30,31),
  113. (31,29,31,30,31,30,31,31,30,31,30,31));
  114. var
  115. leap: Boolean;
  116. days_in_year: LongInt;
  117. Begin
  118. { todo: convert UTC to local time, as soon as we can get the local timezone
  119. from WASI: https://github.com/WebAssembly/WASI/issues/239 }
  120. NanoSecsPast:=NanoSecsPast div 1000000000;
  121. Dt.Sec:=NanoSecsPast mod 60;
  122. NanoSecsPast:=NanoSecsPast div 60;
  123. Dt.Min:=NanoSecsPast mod 60;
  124. NanoSecsPast:=NanoSecsPast div 60;
  125. Dt.Hour:=NanoSecsPast mod 24;
  126. NanoSecsPast:=NanoSecsPast div 24;
  127. Dt.Year:=1970;
  128. leap:=false;
  129. days_in_year:=365;
  130. while NanoSecsPast>=days_in_year do
  131. begin
  132. Dec(NanoSecsPast,days_in_year);
  133. Inc(Dt.Year);
  134. leap:=((Dt.Year mod 4)=0) and (((Dt.Year mod 100)<>0) or ((Dt.Year mod 400)=0));
  135. if leap then
  136. days_in_year:=365
  137. else
  138. days_in_year:=366;
  139. end;
  140. Dt.Month:=1;
  141. Inc(NanoSecsPast);
  142. while NanoSecsPast>days_in_month[leap,Dt.Month] do
  143. begin
  144. Dec(NanoSecsPast,days_in_month[leap,Dt.Month]);
  145. Inc(Dt.Month);
  146. end;
  147. Dt.Day:=Word(NanoSecsPast);
  148. End;
  149. Function DTToUnixDate(DT: DateTime): LongInt;
  150. Begin
  151. End;
  152. function GetMsCount: int64;
  153. begin
  154. end;
  155. {******************************************************************************
  156. --- Exec ---
  157. ******************************************************************************}
  158. Procedure Exec (Const Path: PathStr; Const ComLine: ComStr);
  159. Begin
  160. End;
  161. {******************************************************************************
  162. --- Disk ---
  163. ******************************************************************************}
  164. {
  165. The Diskfree and Disksize functions need a file on the specified drive, since this
  166. is required for the fpstatfs system call.
  167. These filenames are set in drivestr[0..26], and have been preset to :
  168. 0 - '.' (default drive - hence current dir is ok.)
  169. 1 - '/fd0/.' (floppy drive 1 - should be adapted to local system )
  170. 2 - '/fd1/.' (floppy drive 2 - should be adapted to local system )
  171. 3 - '/' (C: equivalent of dos is the root partition)
  172. 4..26 (can be set by you're own applications)
  173. ! Use AddDisk() to Add new drives !
  174. They both return -1 when a failure occurs.
  175. }
  176. Const
  177. FixDriveStr : array[0..3] of pchar=(
  178. '.',
  179. '/fd0/.',
  180. '/fd1/.',
  181. '/.'
  182. );
  183. const
  184. Drives : byte = 4;
  185. var
  186. DriveStr : array[4..26] of pchar;
  187. Function AddDisk(const path:string) : byte;
  188. begin
  189. { if not (DriveStr[Drives]=nil) then
  190. FreeMem(DriveStr[Drives]);
  191. GetMem(DriveStr[Drives],length(Path)+1);
  192. StrPCopy(DriveStr[Drives],path);
  193. AddDisk:=Drives;
  194. inc(Drives);
  195. if Drives>26 then
  196. Drives:=4;}
  197. end;
  198. Function DiskFree(Drive: Byte): int64;
  199. {var
  200. fs : tstatfs;}
  201. Begin
  202. { if ((Drive<4) and (not (fixdrivestr[Drive]=nil)) and (fpStatFS(fixdrivestr[drive],@fs)<>-1)) or
  203. ((not (drivestr[Drive]=nil)) and (fpStatFS(drivestr[drive],@fs)<>-1)) then
  204. Diskfree:=int64(fs.bavail)*int64(fs.bsize)
  205. else
  206. Diskfree:=-1;}
  207. End;
  208. Function DiskSize(Drive: Byte): int64;
  209. {var
  210. fs : tstatfs;}
  211. Begin
  212. { if ((Drive<4) and (not (fixdrivestr[Drive]=nil)) and (fpStatFS(fixdrivestr[drive],@fs)<>-1)) or
  213. ((not (drivestr[Drive]=nil)) and (fpStatFS(drivestr[drive],@fs)<>-1)) then
  214. DiskSize:=int64(fs.blocks)*int64(fs.bsize)
  215. else
  216. DiskSize:=-1;}
  217. End;
  218. Procedure FreeDriveStr;
  219. {var
  220. i: longint;}
  221. begin
  222. { for i:=low(drivestr) to high(drivestr) do
  223. if assigned(drivestr[i]) then
  224. begin
  225. freemem(drivestr[i]);
  226. drivestr[i]:=nil;
  227. end;}
  228. end;
  229. {******************************************************************************
  230. --- Findfirst FindNext ---
  231. ******************************************************************************}
  232. (*Function FNMatch(const Pattern,Name:string):Boolean;
  233. Var
  234. LenPat,LenName : longint;
  235. Function DoFNMatch(i,j:longint):Boolean;
  236. Var
  237. Found : boolean;
  238. Begin
  239. Found:=true;
  240. While Found and (i<=LenPat) Do
  241. Begin
  242. Case Pattern[i] of
  243. '?' : Found:=(j<=LenName);
  244. '*' : Begin
  245. {find the next character in pattern, different of ? and *}
  246. while Found do
  247. begin
  248. inc(i);
  249. if i>LenPat then Break;
  250. case Pattern[i] of
  251. '*' : ;
  252. '?' : begin
  253. if j>LenName then begin DoFNMatch:=false; Exit; end;
  254. inc(j);
  255. end;
  256. else
  257. Found:=false;
  258. end;
  259. end;
  260. Assert((i>LenPat) or ( (Pattern[i]<>'*') and (Pattern[i]<>'?') ));
  261. {Now, find in name the character which i points to, if the * or ?
  262. wasn't the last character in the pattern, else, use up all the
  263. chars in name}
  264. Found:=false;
  265. if (i<=LenPat) then
  266. begin
  267. repeat
  268. {find a letter (not only first !) which maches pattern[i]}
  269. while (j<=LenName) and (name[j]<>pattern[i]) do
  270. inc (j);
  271. if (j<LenName) then
  272. begin
  273. if DoFnMatch(i+1,j+1) then
  274. begin
  275. i:=LenPat;
  276. j:=LenName;{we can stop}
  277. Found:=true;
  278. Break;
  279. end else
  280. inc(j);{We didn't find one, need to look further}
  281. end else
  282. if j=LenName then
  283. begin
  284. Found:=true;
  285. Break;
  286. end;
  287. { This 'until' condition must be j>LenName, not j>=LenName.
  288. That's because when we 'need to look further' and
  289. j = LenName then loop must not terminate. }
  290. until (j>LenName);
  291. end else
  292. begin
  293. j:=LenName;{we can stop}
  294. Found:=true;
  295. end;
  296. end;
  297. else {not a wildcard character in pattern}
  298. Found:=(j<=LenName) and (pattern[i]=name[j]);
  299. end;
  300. inc(i);
  301. inc(j);
  302. end;
  303. DoFnMatch:=Found and (j>LenName);
  304. end;
  305. Begin {start FNMatch}
  306. LenPat:=Length(Pattern);
  307. LenName:=Length(Name);
  308. FNMatch:=DoFNMatch(1,1);
  309. End;*)
  310. Const
  311. RtlFindSize = 15;
  312. Type
  313. RtlFindRecType = Record
  314. DirPtr : Pointer;
  315. SearchNum,
  316. LastUsed : LongInt;
  317. End;
  318. Var
  319. RtlFindRecs : Array[1..RtlFindSize] of RtlFindRecType;
  320. CurrSearchNum : LongInt;
  321. Procedure FindClose(Var f: SearchRec);
  322. {
  323. Closes dirptr if it is open
  324. }
  325. {Var
  326. i : longint;}
  327. Begin
  328. { if f.SearchType=0 then
  329. begin
  330. i:=1;
  331. repeat
  332. if (RtlFindRecs[i].SearchNum=f.SearchNum) then
  333. break;
  334. inc(i);
  335. until (i>RtlFindSize);
  336. If i<=RtlFindSize Then
  337. Begin
  338. RtlFindRecs[i].SearchNum:=0;
  339. if f.dirptr<>nil then
  340. fpclosedir(pdir(f.dirptr)^);
  341. End;
  342. end;
  343. f.dirptr:=nil;}
  344. End;
  345. Function FindGetFileInfo(const s:string;var f:SearchRec):boolean;
  346. {var
  347. DT : DateTime;
  348. Info : RtlInfoType;
  349. st : baseunix.stat;}
  350. begin
  351. { FindGetFileInfo:=false;
  352. if not fpstat(s,st)>=0 then
  353. exit;
  354. info.FSize:=st.st_Size;
  355. info.FMTime:=st.st_mtime;
  356. if (st.st_mode and STAT_IFMT)=STAT_IFDIR then
  357. info.fmode:=$10
  358. else
  359. info.fmode:=$0;
  360. if (st.st_mode and STAT_IWUSR)=0 then
  361. info.fmode:=info.fmode or 1;
  362. if s[f.NamePos+1]='.' then
  363. info.fmode:=info.fmode or $2;
  364. If ((Info.FMode and Not(f.searchattr))=0) Then
  365. Begin
  366. f.Name:=Copy(s,f.NamePos+1,255);
  367. f.Attr:=Info.FMode;
  368. f.Size:=Info.FSize;
  369. f.mode:=st.st_mode;
  370. UnixDateToDT(Info.FMTime, DT);
  371. PackTime(DT,f.Time);
  372. FindGetFileInfo:=true;
  373. End;}
  374. end;
  375. Function FindLastUsed: Longint;
  376. {
  377. Find unused or least recently used dirpointer slot in findrecs array
  378. }
  379. {Var
  380. BestMatch,i : Longint;
  381. Found : Boolean;}
  382. Begin
  383. { BestMatch:=1;
  384. i:=1;
  385. Found:=False;
  386. While (i <= RtlFindSize) And (Not Found) Do
  387. Begin
  388. If (RtlFindRecs[i].SearchNum = 0) Then
  389. Begin
  390. BestMatch := i;
  391. Found := True;
  392. End
  393. Else
  394. Begin
  395. If RtlFindRecs[i].LastUsed > RtlFindRecs[BestMatch].LastUsed Then
  396. BestMatch := i;
  397. End;
  398. Inc(i);
  399. End;
  400. FindLastUsed := BestMatch;}
  401. End;
  402. Procedure FindNext(Var f: SearchRec);
  403. {
  404. re-opens dir if not already in array and calls FindWorkProc
  405. }
  406. {Var
  407. DirName : Array[0..256] of Char;
  408. i,
  409. ArrayPos : Longint;
  410. FName,
  411. SName : string;
  412. Found,
  413. Finished : boolean;
  414. p : pdirent;}
  415. Begin
  416. (* If f.SearchType=0 Then
  417. Begin
  418. ArrayPos:=0;
  419. For i:=1 to RtlFindSize Do
  420. Begin
  421. If RtlFindRecs[i].SearchNum = f.SearchNum Then
  422. ArrayPos:=i;
  423. Inc(RtlFindRecs[i].LastUsed);
  424. End;
  425. If ArrayPos=0 Then
  426. Begin
  427. If f.NamePos = 0 Then
  428. Begin
  429. DirName[0] := '.';
  430. DirName[1] := '/';
  431. DirName[2] := #0;
  432. End
  433. Else
  434. Begin
  435. Move(f.SearchSpec[1], DirName[0], f.NamePos);
  436. DirName[f.NamePos] := #0;
  437. End;
  438. f.DirPtr := fpopendir(@DirName[0]);
  439. If f.DirPtr <> nil Then
  440. begin
  441. ArrayPos:=FindLastUsed;
  442. If RtlFindRecs[ArrayPos].SearchNum > 0 Then
  443. FpCloseDir((pdir(rtlfindrecs[arraypos].dirptr)^));
  444. RtlFindRecs[ArrayPos].SearchNum := f.SearchNum;
  445. RtlFindRecs[ArrayPos].DirPtr := f.DirPtr;
  446. if f.searchpos>0 then
  447. seekdir(pdir(f.dirptr), f.searchpos);
  448. end;
  449. End;
  450. if ArrayPos>0 then
  451. RtlFindRecs[ArrayPos].LastUsed:=0;
  452. end;
  453. {Main loop}
  454. SName:=Copy(f.SearchSpec,f.NamePos+1,255);
  455. Found:=False;
  456. Finished:=(f.dirptr=nil);
  457. While Not Finished Do
  458. Begin
  459. p:=fpreaddir(pdir(f.dirptr)^);
  460. if p=nil then
  461. FName:=''
  462. else
  463. FName:=Strpas(@p^.d_name[0]);
  464. If FName='' Then
  465. Finished:=True
  466. Else
  467. Begin
  468. If FNMatch(SName,FName) Then
  469. Begin
  470. Found:=FindGetFileInfo(Copy(f.SearchSpec,1,f.NamePos)+FName,f);
  471. if Found then
  472. Finished:=true;
  473. End;
  474. End;
  475. End;
  476. {Shutdown}
  477. If Found Then
  478. Begin
  479. f.searchpos:=telldir(pdir(f.dirptr));
  480. DosError:=0;
  481. End
  482. Else
  483. Begin
  484. FindClose(f);
  485. DosError:=18;
  486. End;*)
  487. End;
  488. Procedure FindFirst(Const Path: PathStr; Attr: Word; Var f: SearchRec);
  489. {
  490. opens dir and calls FindWorkProc
  491. }
  492. Begin
  493. (* fillchar(f,sizeof(f),0);
  494. if Path='' then
  495. begin
  496. DosError:=3;
  497. exit;
  498. end;
  499. {Create Info}
  500. f.SearchSpec := Path;
  501. {We always also search for readonly and archive, regardless of Attr:}
  502. f.SearchAttr := Attr or archive or readonly;
  503. f.SearchPos := 0;
  504. f.NamePos := Length(f.SearchSpec);
  505. while (f.NamePos>0) and (f.SearchSpec[f.NamePos]<>'/') do
  506. dec(f.NamePos);
  507. {Wildcards?}
  508. if (Pos('?',Path)=0) and (Pos('*',Path)=0) then
  509. begin
  510. if FindGetFileInfo(Path,f) then
  511. DosError:=0
  512. else
  513. begin
  514. { According to tdos2 test it should return 18
  515. if ErrNo=Sys_ENOENT then
  516. DosError:=3
  517. else }
  518. DosError:=18;
  519. end;
  520. f.DirPtr:=nil;
  521. f.SearchType:=1;
  522. f.searchnum:=-1;
  523. end
  524. else
  525. {Find Entry}
  526. begin
  527. Inc(CurrSearchNum);
  528. f.SearchNum:=CurrSearchNum;
  529. f.SearchType:=0;
  530. FindNext(f);
  531. end;*)
  532. End;
  533. {******************************************************************************
  534. --- File ---
  535. ******************************************************************************}
  536. Function FSearch(path : pathstr;dirlist : string) : pathstr;
  537. {Var
  538. info : BaseUnix.stat;}
  539. Begin
  540. { if (length(Path)>0) and (path[1]='/') and (fpStat(path,info)>=0) and (not fpS_ISDIR(Info.st_Mode)) then
  541. FSearch:=path
  542. else
  543. FSearch:=Unix.FSearch(path,dirlist);}
  544. End;
  545. Procedure GetFAttr(var f; var attr : word);
  546. (*Var
  547. info : baseunix.stat;
  548. LinAttr : longint;
  549. p : pchar;
  550. {$ifndef FPC_ANSI_TEXTFILEREC}
  551. r : RawByteString;
  552. {$endif not FPC_ANSI_TEXTFILEREC}*)
  553. Begin
  554. (* DosError:=0;
  555. {$ifdef FPC_ANSI_TEXTFILEREC}
  556. { encoding is already correct }
  557. p:=@textrec(f).name;
  558. {$else}
  559. r:=ToSingleByteFileSystemEncodedFileName(textrec(f).name);
  560. p:=pchar(r);
  561. {$endif}
  562. { use the pchar rather than the rawbytestring version so that we don't check
  563. a second time whether the string needs to be converted to the right code
  564. page
  565. }
  566. if FPStat(p,info)<0 then
  567. begin
  568. Attr:=0;
  569. DosError:=3;
  570. exit;
  571. end
  572. else
  573. LinAttr:=Info.st_Mode;
  574. if fpS_ISDIR(LinAttr) then
  575. Attr:=$10
  576. else
  577. Attr:=$0;
  578. if fpAccess(p,W_OK)<0 then
  579. Attr:=Attr or $1;
  580. if filerec(f).name[0]='.' then
  581. Attr:=Attr or $2;*)
  582. end;
  583. Procedure getftime (var f; var time : longint);
  584. Var
  585. Info: __wasi_filestat_t;
  586. DT: DateTime;
  587. Begin
  588. doserror:=0;
  589. if __wasi_fd_filestat_get(filerec(f).handle,@Info)<>__WASI_ERRNO_SUCCESS then
  590. begin
  591. Time:=0;
  592. doserror:=6;
  593. exit
  594. end
  595. else
  596. WasiDateToDt(Info.mtim,DT);
  597. PackTime(DT,Time);
  598. End;
  599. Procedure setftime(var f; time : longint);
  600. (*
  601. Var
  602. utim: utimbuf;
  603. DT: DateTime;
  604. p : pchar;
  605. {$ifndef FPC_ANSI_TEXTFILEREC}
  606. r : Rawbytestring;
  607. {$endif not FPC_ANSI_TEXTFILEREC}*)
  608. Begin
  609. (* doserror:=0;
  610. with utim do
  611. begin
  612. actime:=fptime;
  613. UnPackTime(Time,DT);
  614. modtime:=DTToUnixDate(DT);
  615. end;
  616. {$ifdef FPC_ANSI_TEXTFILEREC}
  617. { encoding is already correct }
  618. p:=@textrec(f).name;
  619. {$else}
  620. r:=ToSingleByteFileSystemEncodedFileName(textrec(f).name);
  621. p:=pchar(r);
  622. {$endif}
  623. { use the pchar rather than the rawbytestring version so that we don't check
  624. a second time whether the string needs to be converted to the right code
  625. page
  626. }
  627. if fputime(p,@utim)<0 then
  628. begin
  629. Time:=0;
  630. doserror:=3;
  631. end;*)
  632. End;
  633. {******************************************************************************
  634. --- Environment ---
  635. ******************************************************************************}
  636. Function EnvCount: Longint;
  637. {var
  638. envcnt : longint;
  639. p : ppchar;}
  640. Begin
  641. (* envcnt:=0;
  642. p:=envp; {defined in syslinux}
  643. while (p^<>nil) do
  644. begin
  645. inc(envcnt);
  646. inc(p);
  647. end;
  648. EnvCount := envcnt*)
  649. End;
  650. Function EnvStr (Index: longint): String;
  651. {Var
  652. i : longint;
  653. p : ppchar;}
  654. Begin
  655. (* if Index <= 0 then
  656. envstr:=''
  657. else
  658. begin
  659. p:=envp; {defined in syslinux}
  660. i:=1;
  661. while (i<Index) and (p^<>nil) do
  662. begin
  663. inc(i);
  664. inc(p);
  665. end;
  666. if p=nil then
  667. envstr:=''
  668. else
  669. envstr:=strpas(p^)
  670. end;*)
  671. end;
  672. Function GetEnv(EnvVar: String): String;
  673. {var
  674. p : pchar;}
  675. Begin
  676. { p:=BaseUnix.fpGetEnv(EnvVar);
  677. if p=nil then
  678. GetEnv:=''
  679. else
  680. GetEnv:=StrPas(p);}
  681. End;
  682. Procedure setfattr (var f;attr : word);
  683. Begin
  684. (* {! No Unix equivalent !}
  685. { Fail for setting VolumeId }
  686. if (attr and VolumeID)<>0 then
  687. doserror:=5;*)
  688. End;
  689. {******************************************************************************
  690. --- Initialization ---
  691. ******************************************************************************}
  692. //Finalization
  693. // FreeDriveStr;
  694. End.