sysutils.pp 21 KB

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