sysutils.pp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2021 by the Free Pascal development team.
  4. Sysutils unit for The WebAssembly System Interface (WASI).
  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. {$inline on}
  12. unit sysutils;
  13. interface
  14. {$MODE objfpc}
  15. {$MODESWITCH out}
  16. { force ansistrings }
  17. {$H+}
  18. {$modeswitch typehelpers}
  19. {$modeswitch advancedrecords}
  20. uses
  21. wasiapi;
  22. {$DEFINE OS_FILESETDATEBYNAME}
  23. {$DEFINE HAS_SLEEP}
  24. {$DEFINE HAS_GETTICKCOUNT64}
  25. { used OS file system APIs use ansistring }
  26. {$define SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
  27. { OS has an ansistring/single byte environment variable API }
  28. {$define SYSUTILS_HAS_ANSISTR_ENVVAR_IMPL}
  29. { Include platform independent interface part }
  30. {$i sysutilh.inc}
  31. implementation
  32. uses
  33. sysconst;
  34. {$DEFINE FPC_FEXPAND_UNC} (* UNC paths are supported *)
  35. {$DEFINE FPC_FEXPAND_DRIVES} (* Full paths begin with drive specification *)
  36. {$DEFINE HAS_LOCALTIMEZONEOFFSET}
  37. {$DEFINE executeprocuni} (* Only 1 byte version of ExecuteProcess is provided by the OS *)
  38. Function UniversalToEpoch(year,month,day,hour,minute,second:Word):int64;
  39. const
  40. days_in_month: array [boolean, 1..12] of Byte =
  41. ((31,28,31,30,31,30,31,31,30,31,30,31),
  42. (31,29,31,30,31,30,31,31,30,31,30,31));
  43. days_before_month: array [boolean, 1..12] of Byte =
  44. ((0,
  45. 0+31,
  46. 0+31+28,
  47. 0+31+28+31,
  48. 0+31+28+31+30,
  49. 0+31+28+31+30+31,
  50. 0+31+28+31+30+31+30,
  51. 0+31+28+31+30+31+30+31,
  52. 0+31+28+31+30+31+30+31+31,
  53. 0+31+28+31+30+31+30+31+31+30,
  54. 0+31+28+31+30+31+30+31+31+30+31,
  55. 0+31+28+31+30+31+30+31+31+30+31+30),
  56. (0,
  57. 0+31,
  58. 0+31+29,
  59. 0+31+29+31,
  60. 0+31+29+31+30,
  61. 0+31+29+31+30+31,
  62. 0+31+29+31+30+31+30,
  63. 0+31+29+31+30+31+30+31,
  64. 0+31+29+31+30+31+30+31+31,
  65. 0+31+29+31+30+31+30+31+31+30,
  66. 0+31+29+31+30+31+30+31+31+30+31,
  67. 0+31+29+31+30+31+30+31+31+30+31+30));
  68. var
  69. leap: Boolean;
  70. days_in_year: LongInt;
  71. y,m: LongInt;
  72. begin
  73. if (year<1970) or (month<1) or (month>12) or (day<1) or (day>31) or
  74. (hour>=24) or (minute>=60) or (second>=60) then
  75. begin
  76. result:=-1;
  77. exit;
  78. end;
  79. leap:=((year mod 4)=0) and (((year mod 100)<>0) or ((year mod 400)=0));
  80. if day>days_in_month[leap,month] then
  81. begin
  82. result:=-1;
  83. exit;
  84. end;
  85. result:=0;
  86. for y:=1970 to year-1 do
  87. if ((y mod 4)=0) and (((y mod 100)<>0) or ((y mod 400)=0)) then
  88. Inc(result,366)
  89. else
  90. Inc(result,365);
  91. Inc(result,days_before_month[leap,month]);
  92. Inc(result,day-1);
  93. result:=(((result*24+hour)*60+minute)*60)+second;
  94. end;
  95. Function LocalToEpoch(year,month,day,hour,minute,second:Word):int64;
  96. begin
  97. { todo: convert UTC to local time, as soon as we can get the local timezone
  98. from WASI: https://github.com/WebAssembly/WASI/issues/239 }
  99. result:=UniversalToEpoch(year,month,day,hour,minute,second);
  100. end;
  101. Procedure EpochToUniversal(epoch:int64;var year,month,day,hour,minute,second:Word);
  102. const
  103. days_in_month: array [boolean, 1..12] of Byte =
  104. ((31,28,31,30,31,30,31,31,30,31,30,31),
  105. (31,29,31,30,31,30,31,31,30,31,30,31));
  106. var
  107. leap: Boolean;
  108. days_in_year: LongInt;
  109. begin
  110. if epoch<0 then
  111. begin
  112. year:=0;
  113. month:=0;
  114. day:=0;
  115. hour:=0;
  116. minute:=0;
  117. second:=0;
  118. exit;
  119. end;
  120. second:=epoch mod 60;
  121. epoch:=epoch div 60;
  122. minute:=epoch mod 60;
  123. epoch:=epoch div 60;
  124. hour:=epoch mod 24;
  125. epoch:=epoch div 24;
  126. year:=1970;
  127. leap:=false;
  128. days_in_year:=365;
  129. while epoch>=days_in_year do
  130. begin
  131. Dec(epoch,days_in_year);
  132. Inc(year);
  133. leap:=((year mod 4)=0) and (((year mod 100)<>0) or ((year mod 400)=0));
  134. if leap then
  135. days_in_year:=366
  136. else
  137. days_in_year:=365;
  138. end;
  139. month:=1;
  140. Inc(epoch);
  141. while epoch>days_in_month[leap,month] do
  142. begin
  143. Dec(epoch,days_in_month[leap,month]);
  144. Inc(month);
  145. end;
  146. day:=Word(epoch);
  147. end;
  148. Procedure EpochToLocal(epoch:int64;var year,month,day,hour,minute,second:Word);
  149. begin
  150. { todo: convert UTC to local time, as soon as we can get the local timezone
  151. from WASI: https://github.com/WebAssembly/WASI/issues/239 }
  152. EpochToUniversal(epoch,year,month,day,hour,minute,second);
  153. end;
  154. { Include platform independent implementation part }
  155. {$i sysutils.inc}
  156. function GetTickCount64: QWord;
  157. var
  158. NanoSecsPast: __wasi_timestamp_t;
  159. begin
  160. if __wasi_clock_time_get(__WASI_CLOCKID_MONOTONIC,1000000,@NanoSecsPast)=__WASI_ERRNO_SUCCESS then
  161. Result:=NanoSecsPast div 1000000
  162. else
  163. Result:=0;
  164. end;
  165. {****************************************************************************
  166. File Functions
  167. ****************************************************************************}
  168. Function WasiToWinAttr (const FN : RawByteString; fd: __wasi_fd_t; pr: PChar; pr_len: size_t; Const Info : __wasi_filestat_t) : Longint;
  169. Var
  170. LinkInfo : __wasi_filestat_t;
  171. nm : RawByteString;
  172. begin
  173. Result:=faArchive;
  174. if Info.filetype=__WASI_FILETYPE_DIRECTORY then
  175. Result:=Result or faDirectory;
  176. nm:=ExtractFileName(FN);
  177. If (Length(nm)>=2) and
  178. (nm[1]='.') and
  179. (nm[2]<>'.') then
  180. Result:=Result or faHidden;
  181. If (Info.filetype=__WASI_FILETYPE_BLOCK_DEVICE) or
  182. (Info.filetype=__WASI_FILETYPE_CHARACTER_DEVICE) or
  183. (Info.filetype=__WASI_FILETYPE_SOCKET_DGRAM) or
  184. (Info.filetype=__WASI_FILETYPE_SOCKET_STREAM) then
  185. Result:=Result or faSysFile;
  186. if Info.filetype=__WASI_FILETYPE_SYMBOLIC_LINK then
  187. begin
  188. Result:=Result or faSymLink;
  189. // Windows reports if the link points to a directory.
  190. if (__wasi_path_filestat_get(fd,__WASI_LOOKUPFLAGS_SYMLINK_FOLLOW,pr,pr_len,@LinkInfo)=__WASI_ERRNO_SUCCESS) and
  191. (LinkInfo.filetype=__WASI_FILETYPE_DIRECTORY) then
  192. Result := Result or faDirectory;
  193. end;
  194. end;
  195. Function FileOpen (Const FileName : RawByteString; Mode : Integer) : THandle;
  196. Var
  197. fs_rights_base: __wasi_rights_t = 0;
  198. ourfd: __wasi_fd_t;
  199. res: __wasi_errno_t;
  200. pr: RawByteString;
  201. fd: __wasi_fd_t;
  202. Begin
  203. case (Mode and (fmOpenRead or fmOpenWrite or fmOpenReadWrite)) of
  204. fmOpenRead:
  205. fs_rights_base :=__WASI_RIGHTS_FD_READ or
  206. __WASI_RIGHTS_FD_FILESTAT_GET or
  207. __WASI_RIGHTS_FD_SEEK or
  208. __WASI_RIGHTS_FD_TELL or
  209. __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS or
  210. __WASI_RIGHTS_FD_ADVISE or
  211. __WASI_RIGHTS_POLL_FD_READWRITE;
  212. fmOpenWrite:
  213. fs_rights_base :=__WASI_RIGHTS_FD_WRITE or
  214. __WASI_RIGHTS_FD_FILESTAT_GET or
  215. __WASI_RIGHTS_FD_SEEK or
  216. __WASI_RIGHTS_FD_TELL or
  217. __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS or
  218. __WASI_RIGHTS_FD_ADVISE or
  219. __WASI_RIGHTS_POLL_FD_READWRITE or
  220. __WASI_RIGHTS_FD_FILESTAT_SET_SIZE or
  221. __WASI_RIGHTS_FD_FILESTAT_SET_TIMES or
  222. __WASI_RIGHTS_FD_ALLOCATE or
  223. __WASI_RIGHTS_FD_DATASYNC or
  224. __WASI_RIGHTS_FD_SYNC;
  225. fmOpenReadWrite:
  226. fs_rights_base :=__WASI_RIGHTS_FD_READ or
  227. __WASI_RIGHTS_FD_WRITE or
  228. __WASI_RIGHTS_FD_FILESTAT_GET or
  229. __WASI_RIGHTS_FD_SEEK or
  230. __WASI_RIGHTS_FD_TELL or
  231. __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS or
  232. __WASI_RIGHTS_FD_ADVISE or
  233. __WASI_RIGHTS_POLL_FD_READWRITE or
  234. __WASI_RIGHTS_FD_FILESTAT_SET_SIZE or
  235. __WASI_RIGHTS_FD_FILESTAT_SET_TIMES or
  236. __WASI_RIGHTS_FD_ALLOCATE or
  237. __WASI_RIGHTS_FD_DATASYNC or
  238. __WASI_RIGHTS_FD_SYNC;
  239. end;
  240. if ConvertToFdRelativePath(FileName,fd,pr)<>0 then
  241. begin
  242. result:=-1;
  243. exit;
  244. end;
  245. repeat
  246. res:=__wasi_path_open(fd,
  247. 0,
  248. PChar(pr),
  249. length(pr),
  250. 0,
  251. fs_rights_base,
  252. fs_rights_base,
  253. 0,
  254. @ourfd);
  255. until (res=__WASI_ERRNO_SUCCESS) or (res<>__WASI_ERRNO_INTR);
  256. If res=__WASI_ERRNO_SUCCESS Then
  257. Result:=ourfd
  258. else
  259. Result:=-1;
  260. end;
  261. Function FileCreate (Const FileName : RawByteString) : THandle;
  262. Const
  263. fs_rights_base: __wasi_rights_t =
  264. __WASI_RIGHTS_FD_READ or
  265. __WASI_RIGHTS_FD_WRITE or
  266. __WASI_RIGHTS_FD_FILESTAT_GET or
  267. __WASI_RIGHTS_FD_SEEK or
  268. __WASI_RIGHTS_FD_TELL or
  269. __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS or
  270. __WASI_RIGHTS_FD_ADVISE or
  271. __WASI_RIGHTS_POLL_FD_READWRITE or
  272. __WASI_RIGHTS_FD_FILESTAT_SET_SIZE or
  273. __WASI_RIGHTS_FD_FILESTAT_SET_TIMES or
  274. __WASI_RIGHTS_FD_ALLOCATE or
  275. __WASI_RIGHTS_FD_DATASYNC or
  276. __WASI_RIGHTS_FD_SYNC;
  277. Var
  278. ourfd: __wasi_fd_t;
  279. res: __wasi_errno_t;
  280. pr: RawByteString;
  281. fd: __wasi_fd_t;
  282. Begin
  283. if ConvertToFdRelativePath(FileName,fd,pr)<>0 then
  284. begin
  285. result:=-1;
  286. exit;
  287. end;
  288. repeat
  289. res:=__wasi_path_open(fd,
  290. 0,
  291. PChar(pr),
  292. length(pr),
  293. __WASI_OFLAGS_CREAT or __WASI_OFLAGS_TRUNC,
  294. fs_rights_base,
  295. fs_rights_base,
  296. 0,
  297. @ourfd);
  298. until (res=__WASI_ERRNO_SUCCESS) or (res<>__WASI_ERRNO_INTR);
  299. If res=__WASI_ERRNO_SUCCESS Then
  300. Result:=ourfd
  301. else
  302. Result:=-1;
  303. end;
  304. Function FileCreate (Const FileName : RawByteString; ShareMode:integer; Rights : integer) : THandle;
  305. begin
  306. FileCreate:=FileCreate(FileName);
  307. end;
  308. Function FileCreate (Const FileName : RawByteString; Rights:integer) : THandle;
  309. begin
  310. FileCreate:=FileCreate(FileName);
  311. end;
  312. Function FileRead (Handle : THandle; Out Buffer; Count : longint) : Longint;
  313. var
  314. our_iov: __wasi_iovec_t;
  315. our_nread: __wasi_size_t;
  316. res: __wasi_errno_t;
  317. begin
  318. repeat
  319. our_iov.buf:=@Buffer;
  320. our_iov.buf_len:=Count;
  321. res:=__wasi_fd_read(Handle,@our_iov,1,@our_nread);
  322. until (res=__WASI_ERRNO_SUCCESS) or ((res<>__WASI_ERRNO_INTR) and (res<>__WASI_ERRNO_AGAIN));
  323. if res=__WASI_ERRNO_SUCCESS then
  324. Result:=our_nread
  325. else
  326. Result:=-1;
  327. end;
  328. Function FileWrite (Handle : THandle; const Buffer; Count : Longint) : Longint;
  329. var
  330. our_iov: __wasi_ciovec_t;
  331. our_nwritten: longint;
  332. res: __wasi_errno_t;
  333. begin
  334. repeat
  335. our_iov.buf:=@Buffer;
  336. our_iov.buf_len:=Count;
  337. res:=__wasi_fd_write(Handle,@our_iov,1,@our_nwritten);
  338. until (res=__WASI_ERRNO_SUCCESS) or ((res<>__WASI_ERRNO_INTR) and (res<>__WASI_ERRNO_AGAIN));
  339. if res=__WASI_ERRNO_SUCCESS then
  340. Result:=our_nwritten
  341. else
  342. Result:=-1;
  343. end;
  344. Function FileSeek (Handle : THandle; FOffset, Origin : Longint) : Longint;
  345. begin
  346. result:=longint(FileSeek(Handle,int64(FOffset),Origin));
  347. end;
  348. Function FileSeek (Handle : THandle; FOffset: Int64; Origin: Longint) : Int64;
  349. var
  350. res: __wasi_errno_t;
  351. newoffset: __wasi_filesize_t;
  352. whence: __wasi_whence_t;
  353. begin
  354. case Origin of
  355. fsFromBeginning:
  356. whence:=__WASI_WHENCE_SET;
  357. fsFromCurrent:
  358. whence:=__WASI_WHENCE_CUR;
  359. fsFromEnd:
  360. whence:=__WASI_WHENCE_END;
  361. else
  362. begin
  363. Result:=-1;
  364. exit;
  365. end;
  366. end;
  367. res:=__wasi_fd_seek(Handle,FOffset,whence,@newoffset);
  368. if res=__WASI_ERRNO_SUCCESS then
  369. Result:=newoffset
  370. else
  371. Result:=-1;
  372. end;
  373. Procedure FileClose (Handle : THandle);
  374. var
  375. res: __wasi_errno_t;
  376. begin
  377. repeat
  378. res:=__wasi_fd_close(Handle);
  379. until (res=__WASI_ERRNO_SUCCESS) or (res<>__WASI_ERRNO_INTR);
  380. end;
  381. Function FileTruncate (Handle: THandle; Size: Int64) : boolean;
  382. var
  383. res: __wasi_errno_t;
  384. begin
  385. Result:=__wasi_fd_filestat_set_size(handle,Size)=__WASI_ERRNO_SUCCESS;
  386. end;
  387. Function FileAge (Const FileName : RawByteString): Int64;
  388. var
  389. res: __wasi_errno_t;
  390. pr: RawByteString;
  391. fd: __wasi_fd_t;
  392. Info: __wasi_filestat_t;
  393. begin
  394. if ConvertToFdRelativePath(FileName,fd,pr)<>0 then
  395. begin
  396. result:=-1;
  397. exit;
  398. end;
  399. res:=__wasi_path_filestat_get(fd,0,PChar(pr),length(pr),@Info);
  400. if res=__WASI_ERRNO_SUCCESS then
  401. result:=Info.mtim div 1000000000
  402. else
  403. result:=-1;
  404. end;
  405. function FileGetSymLinkTarget(const FileName: RawByteString; out SymLinkRec: TRawbyteSymLinkRec): Boolean;
  406. const
  407. MaxSymLinkSize=4096;
  408. var
  409. pr: RawByteString;
  410. fd: __wasi_fd_t;
  411. Info: __wasi_filestat_t;
  412. symlink: RawByteString;
  413. symlink_len: __wasi_size_t;
  414. res: __wasi_errno_t;
  415. begin
  416. FillChar(SymLinkRec, SizeOf(SymLinkRec), 0);
  417. result:=false;
  418. if ConvertToFdRelativePath(FileName,fd,pr)<>0 then
  419. exit;
  420. if __wasi_path_filestat_get(fd,0,PChar(pr),length(pr),@Info)<>__WASI_ERRNO_SUCCESS then
  421. exit;
  422. if Info.filetype<>__WASI_FILETYPE_SYMBOLIC_LINK then
  423. exit;
  424. SetLength(symlink,MaxSymLinkSize);
  425. if __wasi_path_readlink(fd,PChar(pr),Length(pr),@symlink[1],Length(symlink),@symlink_len)<>__WASI_ERRNO_SUCCESS then
  426. exit;
  427. SetLength(symlink,symlink_len);
  428. setcodepage(symlink,DefaultRTLFileSystemCodePage,true);
  429. SymLinkRec.TargetName:=symlink;
  430. res:=__wasi_path_filestat_get(fd,__WASI_LOOKUPFLAGS_SYMLINK_FOLLOW,PChar(pr),length(pr),@Info);
  431. if res<>__WASI_ERRNO_SUCCESS then
  432. raise EDirectoryNotFoundException.Create('Error ' + IntToStr(res){todo: SysErrorMessage SysErrorMessage(GetLastOSError)});
  433. SymLinkRec.Attr := WasiToWinAttr(FileName,fd,PChar(pr),length(pr),Info);
  434. SymLinkRec.Size := Info.size;
  435. result:=true;
  436. end;
  437. function FileExists (const FileName: RawByteString; FollowLink : Boolean): boolean;
  438. var
  439. pr: RawByteString;
  440. fd: __wasi_fd_t;
  441. Info: __wasi_filestat_t;
  442. flags: __wasi_lookupflags_t;
  443. begin
  444. if FileName='' then
  445. exit(false);
  446. if ConvertToFdRelativePath(FileName,fd,pr)<>0 then
  447. exit(false);
  448. if FollowLink then
  449. flags:=__WASI_LOOKUPFLAGS_SYMLINK_FOLLOW
  450. else
  451. flags:=0;
  452. if __wasi_path_filestat_get(fd,flags,PChar(pr),length(pr),@Info)=__WASI_ERRNO_SUCCESS then
  453. result:=Info.filetype<>__WASI_FILETYPE_DIRECTORY
  454. else
  455. result:=false;
  456. end;
  457. Function DirectoryExists (Const Directory : RawByteString; FollowLink : Boolean) : Boolean;
  458. var
  459. pr: RawByteString;
  460. fd: __wasi_fd_t;
  461. Info: __wasi_filestat_t;
  462. flags: __wasi_lookupflags_t;
  463. begin
  464. if Directory='' then
  465. exit(false);
  466. if ConvertToFdRelativePath(Directory,fd,pr)<>0 then
  467. exit(false);
  468. if FollowLink then
  469. flags:=__WASI_LOOKUPFLAGS_SYMLINK_FOLLOW
  470. else
  471. flags:=0;
  472. if __wasi_path_filestat_get(fd,flags,PChar(pr),length(pr),@Info)=__WASI_ERRNO_SUCCESS then
  473. result:=Info.filetype=__WASI_FILETYPE_DIRECTORY
  474. else
  475. result:=false;
  476. end;
  477. Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint;
  478. begin
  479. { not yet implemented }
  480. Result := -1;
  481. end;
  482. Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint;
  483. begin
  484. { not yet implemented }
  485. Result := -1;
  486. end;
  487. Procedure InternalFindClose(var Handle: THandle);
  488. begin
  489. end;
  490. Function FileGetDate (Handle : THandle) : Int64;
  491. var
  492. res: __wasi_errno_t;
  493. Info: __wasi_filestat_t;
  494. begin
  495. res:=__wasi_fd_filestat_get(Handle,@Info);
  496. if res=__WASI_ERRNO_SUCCESS then
  497. result:=Info.mtim div 1000000000
  498. else
  499. result:=-1;
  500. end;
  501. Function FileSetDate (Handle : THandle; Age : Int64) : Longint;
  502. begin
  503. if __wasi_fd_filestat_set_times(Handle,Age*1000000000,Age*1000000000,
  504. __WASI_FSTFLAGS_MTIM or __WASI_FSTFLAGS_ATIM)=__WASI_ERRNO_SUCCESS then
  505. result:=0
  506. else
  507. result:=-1;
  508. end;
  509. Function FileSetDate (Const FileName : RawByteString; Age : Int64) : Longint;
  510. var
  511. pr: RawByteString;
  512. fd: __wasi_fd_t;
  513. begin
  514. if ConvertToFdRelativePath(FileName,fd,pr)<>0 then
  515. begin
  516. result:=-1;
  517. exit;
  518. end;
  519. if __wasi_path_filestat_set_times(fd,0,PChar(pr),length(pr),Age*1000000000,Age*1000000000,
  520. __WASI_FSTFLAGS_MTIM or __WASI_FSTFLAGS_ATIM)=__WASI_ERRNO_SUCCESS then
  521. result:=0
  522. else
  523. result:=-1;
  524. end;
  525. Function FileGetAttr (Const FileName : RawByteString) : Longint;
  526. var
  527. pr: RawByteString;
  528. fd: __wasi_fd_t;
  529. Info: __wasi_filestat_t;
  530. begin
  531. if ConvertToFdRelativePath(FileName,fd,pr)<>0 then
  532. begin
  533. result:=-1;
  534. exit;
  535. end;
  536. if __wasi_path_filestat_get(fd,0,PChar(pr),length(pr),@Info)=__WASI_ERRNO_SUCCESS then
  537. result:=WasiToWinAttr(FileName,fd,PChar(pr),length(pr),Info)
  538. else
  539. result:=-1;
  540. end;
  541. Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
  542. begin
  543. Result:=-1;
  544. end;
  545. Function DeleteFile (Const FileName : RawByteString) : Boolean;
  546. var
  547. fd: __wasi_fd_t;
  548. pr: RawByteString;
  549. res: __wasi_errno_t;
  550. begin
  551. if ConvertToFdRelativePath(FileName,fd,pr)<>0 then
  552. begin
  553. result:=false;
  554. exit;
  555. end;
  556. result:=__wasi_path_unlink_file(fd,PChar(pr),Length(pr))=__WASI_ERRNO_SUCCESS;
  557. end;
  558. Function RenameFile (Const OldName, NewName : RawByteString) : Boolean;
  559. var
  560. fd1,fd2: __wasi_fd_t;
  561. pr1,pr2: RawByteString;
  562. res: __wasi_errno_t;
  563. begin
  564. result:=false;
  565. if ConvertToFdRelativePath(OldName,fd1,pr1)<>0 then
  566. exit;
  567. if ConvertToFdRelativePath(NewName,fd2,pr2)<>0 then
  568. exit;
  569. result:=__wasi_path_rename(fd1,PChar(pr1),Length(pr1),fd2,PChar(pr2),Length(pr2))=__WASI_ERRNO_SUCCESS;
  570. end;
  571. {****************************************************************************
  572. Disk Functions
  573. ****************************************************************************}
  574. function diskfree(drive : byte) : int64;
  575. begin
  576. end;
  577. function disksize(drive : byte) : int64;
  578. begin
  579. end;
  580. {****************************************************************************
  581. Time Functions
  582. ****************************************************************************}
  583. {$I tzenv.inc}
  584. Procedure GetLocalTime(var SystemTime: TSystemTime);
  585. begin
  586. end ;
  587. {****************************************************************************
  588. Misc Functions
  589. ****************************************************************************}
  590. procedure sysBeep;
  591. begin
  592. end;
  593. {****************************************************************************
  594. Locale Functions
  595. ****************************************************************************}
  596. procedure InitAnsi;
  597. begin
  598. end;
  599. Procedure InitInternational;
  600. begin
  601. InitInternationalGeneric;
  602. InitAnsi;
  603. end;
  604. function SysErrorMessage(ErrorCode: Integer): String;
  605. begin
  606. Result:=Format(SUnknownErrorCode,[ErrorCode]);
  607. end;
  608. {****************************************************************************
  609. Os utils
  610. ****************************************************************************}
  611. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  612. var
  613. hp : ppchar;
  614. hs : string;
  615. eqpos : longint;
  616. begin
  617. result:='';
  618. hp:=envp;
  619. if hp<>nil then
  620. while assigned(hp^) do
  621. begin
  622. hs:=strpas(hp^);
  623. eqpos:=pos('=',hs);
  624. if copy(hs,1,eqpos-1)=envvar then
  625. begin
  626. result:=copy(hs,eqpos+1,length(hs)-eqpos);
  627. break;
  628. end;
  629. inc(hp);
  630. end;
  631. end;
  632. Function GetEnvironmentVariableCount : Integer;
  633. var
  634. p: ppchar;
  635. begin
  636. result:=0;
  637. p:=envp; {defined in system}
  638. if p<>nil then
  639. while p^<>nil do
  640. begin
  641. inc(result);
  642. inc(p);
  643. end;
  644. end;
  645. Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
  646. Var
  647. i : longint;
  648. p : ppchar;
  649. begin
  650. if (Index <= 0) or (envp=nil) then
  651. result:=''
  652. else
  653. begin
  654. p:=envp; {defined in system}
  655. i:=1;
  656. while (i<Index) and (p^<>nil) do
  657. begin
  658. inc(i);
  659. inc(p);
  660. end;
  661. if p^=nil then
  662. result:=''
  663. else
  664. result:=strpas(p^)
  665. end;
  666. end;
  667. function ExecuteProcess(Const Path: RawByteString; Const ComLine: RawByteString;Flags:TExecuteFlags=[]):integer;
  668. begin
  669. end;
  670. function ExecuteProcess (const Path: RawByteString;
  671. const ComLine: array of RawByteString;Flags:TExecuteFlags=[]): integer;
  672. begin
  673. end;
  674. {*************************************************************************
  675. Sleep
  676. *************************************************************************}
  677. procedure Sleep (MilliSeconds: Cardinal);
  678. var
  679. subscription: __wasi_subscription_t;
  680. event: __wasi_event_t;
  681. nevents: __wasi_size_t;
  682. begin
  683. FillChar(subscription,SizeOf(subscription),0);
  684. subscription.u.tag:=__WASI_EVENTTYPE_CLOCK;
  685. subscription.u.u.clock.id:=__WASI_CLOCKID_MONOTONIC;
  686. subscription.u.u.clock.timeout:=MilliSeconds*1000000;
  687. subscription.u.u.clock.precision:=1000000;
  688. subscription.u.u.clock.flags:=0; { timeout value is relative }
  689. __wasi_poll_oneoff(@subscription,@event,1,@nevents);
  690. end;
  691. {****************************************************************************
  692. Initialization code
  693. ****************************************************************************}
  694. Initialization
  695. InitExceptions; { Initialize exceptions. OS independent }
  696. InitInternational; { Initialize internationalization settings }
  697. OnBeep:=@SysBeep;
  698. InitTZ;
  699. Finalization
  700. FreeTerminateProcs;
  701. DoneExceptions;
  702. end.