sysutils.pp 22 KB

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