sysutils.pp 20 KB

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