sysutils.pp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  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 HAS_SLEEP}
  23. {$DEFINE HAS_GETTICKCOUNT64}
  24. { used OS file system APIs use ansistring }
  25. {$define SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
  26. { OS has an ansistring/single byte environment variable API }
  27. {$define SYSUTILS_HAS_ANSISTR_ENVVAR_IMPL}
  28. { Include platform independent interface part }
  29. {$i sysutilh.inc}
  30. implementation
  31. uses
  32. sysconst;
  33. {$DEFINE FPC_FEXPAND_UNC} (* UNC paths are supported *)
  34. {$DEFINE FPC_FEXPAND_DRIVES} (* Full paths begin with drive specification *)
  35. {$DEFINE HAS_LOCALTIMEZONEOFFSET}
  36. {$DEFINE executeprocuni} (* Only 1 byte version of ExecuteProcess is provided by the OS *)
  37. { Include platform independent implementation part }
  38. {$i sysutils.inc}
  39. function GetTickCount64: QWord;
  40. var
  41. NanoSecsPast: __wasi_timestamp_t;
  42. begin
  43. if __wasi_clock_time_get(__WASI_CLOCKID_MONOTONIC,1000000,@NanoSecsPast)=__WASI_ERRNO_SUCCESS then
  44. Result:=NanoSecsPast div 1000000
  45. else
  46. Result:=0;
  47. end;
  48. {****************************************************************************
  49. File Functions
  50. ****************************************************************************}
  51. Function FileOpen (Const FileName : RawByteString; Mode : Integer) : THandle;
  52. Var
  53. SystemFileName: RawByteString;
  54. fs_rights_base: __wasi_rights_t = 0;
  55. ourfd: __wasi_fd_t;
  56. res: __wasi_errno_t;
  57. pr: RawByteString;
  58. fd: __wasi_fd_t;
  59. Begin
  60. SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
  61. case (Mode and (fmOpenRead or fmOpenWrite or fmOpenReadWrite)) of
  62. fmOpenRead:
  63. fs_rights_base :=__WASI_RIGHTS_FD_READ or
  64. __WASI_RIGHTS_FD_FILESTAT_GET or
  65. __WASI_RIGHTS_FD_SEEK or
  66. __WASI_RIGHTS_FD_TELL or
  67. __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS or
  68. __WASI_RIGHTS_FD_ADVISE or
  69. __WASI_RIGHTS_POLL_FD_READWRITE;
  70. fmOpenWrite:
  71. fs_rights_base :=__WASI_RIGHTS_FD_WRITE or
  72. __WASI_RIGHTS_FD_FILESTAT_GET or
  73. __WASI_RIGHTS_FD_SEEK or
  74. __WASI_RIGHTS_FD_TELL or
  75. __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS or
  76. __WASI_RIGHTS_FD_ADVISE or
  77. __WASI_RIGHTS_POLL_FD_READWRITE or
  78. __WASI_RIGHTS_FD_FILESTAT_SET_SIZE or
  79. __WASI_RIGHTS_FD_FILESTAT_SET_TIMES or
  80. __WASI_RIGHTS_FD_ALLOCATE or
  81. __WASI_RIGHTS_FD_DATASYNC or
  82. __WASI_RIGHTS_FD_SYNC;
  83. fmOpenReadWrite:
  84. fs_rights_base :=__WASI_RIGHTS_FD_READ or
  85. __WASI_RIGHTS_FD_WRITE or
  86. __WASI_RIGHTS_FD_FILESTAT_GET or
  87. __WASI_RIGHTS_FD_SEEK or
  88. __WASI_RIGHTS_FD_TELL or
  89. __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS or
  90. __WASI_RIGHTS_FD_ADVISE or
  91. __WASI_RIGHTS_POLL_FD_READWRITE or
  92. __WASI_RIGHTS_FD_FILESTAT_SET_SIZE or
  93. __WASI_RIGHTS_FD_FILESTAT_SET_TIMES or
  94. __WASI_RIGHTS_FD_ALLOCATE or
  95. __WASI_RIGHTS_FD_DATASYNC or
  96. __WASI_RIGHTS_FD_SYNC;
  97. end;
  98. if not ConvertToFdRelativePath(SystemFileName,fd,pr) then
  99. begin
  100. result:=-1;
  101. exit;
  102. end;
  103. repeat
  104. res:=__wasi_path_open(fd,
  105. 0,
  106. PChar(pr),
  107. length(pr),
  108. 0,
  109. fs_rights_base,
  110. fs_rights_base,
  111. 0,
  112. @ourfd);
  113. until (res=__WASI_ERRNO_SUCCESS) or (res<>__WASI_ERRNO_INTR);
  114. If res=__WASI_ERRNO_SUCCESS Then
  115. Result:=ourfd
  116. else
  117. Result:=-1;
  118. end;
  119. Function FileCreate (Const FileName : RawByteString) : THandle;
  120. Const
  121. fs_rights_base: __wasi_rights_t =
  122. __WASI_RIGHTS_FD_READ or
  123. __WASI_RIGHTS_FD_WRITE or
  124. __WASI_RIGHTS_FD_FILESTAT_GET or
  125. __WASI_RIGHTS_FD_SEEK or
  126. __WASI_RIGHTS_FD_TELL or
  127. __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS or
  128. __WASI_RIGHTS_FD_ADVISE or
  129. __WASI_RIGHTS_POLL_FD_READWRITE or
  130. __WASI_RIGHTS_FD_FILESTAT_SET_SIZE or
  131. __WASI_RIGHTS_FD_FILESTAT_SET_TIMES or
  132. __WASI_RIGHTS_FD_ALLOCATE or
  133. __WASI_RIGHTS_FD_DATASYNC or
  134. __WASI_RIGHTS_FD_SYNC;
  135. Var
  136. SystemFileName: RawByteString;
  137. ourfd: __wasi_fd_t;
  138. res: __wasi_errno_t;
  139. pr: RawByteString;
  140. fd: __wasi_fd_t;
  141. Begin
  142. SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
  143. if not ConvertToFdRelativePath(SystemFileName,fd,pr) then
  144. begin
  145. result:=-1;
  146. exit;
  147. end;
  148. repeat
  149. res:=__wasi_path_open(fd,
  150. 0,
  151. PChar(pr),
  152. length(pr),
  153. __WASI_OFLAGS_CREAT or __WASI_OFLAGS_TRUNC,
  154. fs_rights_base,
  155. fs_rights_base,
  156. 0,
  157. @ourfd);
  158. until (res=__WASI_ERRNO_SUCCESS) or (res<>__WASI_ERRNO_INTR);
  159. If res=__WASI_ERRNO_SUCCESS Then
  160. Result:=ourfd
  161. else
  162. Result:=-1;
  163. end;
  164. Function FileCreate (Const FileName : RawByteString; ShareMode:integer; Rights : integer) : THandle;
  165. begin
  166. FileCreate:=FileCreate(FileName);
  167. end;
  168. Function FileCreate (Const FileName : RawByteString; Rights:integer) : THandle;
  169. begin
  170. FileCreate:=FileCreate(FileName);
  171. end;
  172. Function FileRead (Handle : THandle; Out Buffer; Count : longint) : Longint;
  173. var
  174. our_iov: __wasi_iovec_t;
  175. our_nread: __wasi_size_t;
  176. res: __wasi_errno_t;
  177. begin
  178. repeat
  179. our_iov.buf:=@Buffer;
  180. our_iov.buf_len:=Count;
  181. res:=__wasi_fd_read(Handle,@our_iov,1,@our_nread);
  182. until (res=__WASI_ERRNO_SUCCESS) or ((res<>__WASI_ERRNO_INTR) and (res<>__WASI_ERRNO_AGAIN));
  183. if res=__WASI_ERRNO_SUCCESS then
  184. Result:=our_nread
  185. else
  186. Result:=-1;
  187. end;
  188. Function FileWrite (Handle : THandle; const Buffer; Count : Longint) : Longint;
  189. var
  190. our_iov: __wasi_ciovec_t;
  191. our_nwritten: longint;
  192. res: __wasi_errno_t;
  193. begin
  194. repeat
  195. our_iov.buf:=@Buffer;
  196. our_iov.buf_len:=Count;
  197. res:=__wasi_fd_write(Handle,@our_iov,1,@our_nwritten);
  198. until (res=__WASI_ERRNO_SUCCESS) or ((res<>__WASI_ERRNO_INTR) and (res<>__WASI_ERRNO_AGAIN));
  199. if res=__WASI_ERRNO_SUCCESS then
  200. Result:=our_nwritten
  201. else
  202. Result:=-1;
  203. end;
  204. Function FileSeek (Handle : THandle; FOffset, Origin : Longint) : Longint;
  205. begin
  206. result:=longint(FileSeek(Handle,int64(FOffset),Origin));
  207. end;
  208. Function FileSeek (Handle : THandle; FOffset: Int64; Origin: Longint) : Int64;
  209. var
  210. res: __wasi_errno_t;
  211. newoffset: __wasi_filesize_t;
  212. whence: __wasi_whence_t;
  213. begin
  214. case Origin of
  215. fsFromBeginning:
  216. whence:=__WASI_WHENCE_SET;
  217. fsFromCurrent:
  218. whence:=__WASI_WHENCE_CUR;
  219. fsFromEnd:
  220. whence:=__WASI_WHENCE_END;
  221. else
  222. begin
  223. Result:=-1;
  224. exit;
  225. end;
  226. end;
  227. res:=__wasi_fd_seek(Handle,FOffset,whence,@newoffset);
  228. if res=__WASI_ERRNO_SUCCESS then
  229. Result:=newoffset
  230. else
  231. Result:=-1;
  232. end;
  233. Procedure FileClose (Handle : THandle);
  234. var
  235. res: __wasi_errno_t;
  236. begin
  237. repeat
  238. res:=__wasi_fd_close(Handle);
  239. until (res=__WASI_ERRNO_SUCCESS) or (res<>__WASI_ERRNO_INTR);
  240. end;
  241. Function FileTruncate (Handle: THandle; Size: Int64) : boolean;
  242. var
  243. res: __wasi_errno_t;
  244. begin
  245. Result:=__wasi_fd_filestat_set_size(handle,Size)=__WASI_ERRNO_SUCCESS;
  246. end;
  247. Function FileAge (Const FileName : RawByteString): Int64;
  248. begin
  249. end;
  250. function FileGetSymLinkTarget(const FileName: RawByteString; out SymLinkRec: TRawbyteSymLinkRec): Boolean;
  251. begin
  252. Result := False;
  253. end;
  254. function FileExists (const FileName: RawByteString; FollowLink : Boolean): boolean;
  255. begin
  256. end;
  257. Function DirectoryExists (Const Directory : RawByteString; FollowLink : Boolean) : Boolean;
  258. begin
  259. end;
  260. Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint;
  261. begin
  262. { not yet implemented }
  263. Result := -1;
  264. end;
  265. Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint;
  266. begin
  267. { not yet implemented }
  268. Result := -1;
  269. end;
  270. Procedure InternalFindClose(var Handle: THandle);
  271. begin
  272. end;
  273. Function FileGetDate (Handle : THandle) : Int64;
  274. begin
  275. end;
  276. Function FileSetDate (Handle : THandle; Age : Int64) : Longint;
  277. begin
  278. end;
  279. Function FileGetAttr (Const FileName : RawByteString) : Longint;
  280. begin
  281. end;
  282. Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
  283. begin
  284. end;
  285. Function DeleteFile (Const FileName : RawByteString) : Boolean;
  286. begin
  287. end;
  288. Function RenameFile (Const OldName, NewName : RawByteString) : Boolean;
  289. var
  290. fd1,fd2: __wasi_fd_t;
  291. pr1,pr2: RawByteString;
  292. res: __wasi_errno_t;
  293. begin
  294. result:=false;
  295. if not ConvertToFdRelativePath(OldName,fd1,pr1) then
  296. exit;
  297. if not ConvertToFdRelativePath(NewName,fd2,pr2) then
  298. exit;
  299. result:=__wasi_path_rename(fd1,PChar(pr1),Length(pr1),fd2,PChar(pr2),Length(pr2))=__WASI_ERRNO_SUCCESS;
  300. end;
  301. {****************************************************************************
  302. Disk Functions
  303. ****************************************************************************}
  304. function diskfree(drive : byte) : int64;
  305. begin
  306. end;
  307. function disksize(drive : byte) : int64;
  308. begin
  309. end;
  310. {****************************************************************************
  311. Time Functions
  312. ****************************************************************************}
  313. {$I tzenv.inc}
  314. Procedure GetLocalTime(var SystemTime: TSystemTime);
  315. begin
  316. end ;
  317. {****************************************************************************
  318. Misc Functions
  319. ****************************************************************************}
  320. procedure sysBeep;
  321. begin
  322. end;
  323. {****************************************************************************
  324. Locale Functions
  325. ****************************************************************************}
  326. procedure InitAnsi;
  327. begin
  328. end;
  329. Procedure InitInternational;
  330. begin
  331. InitInternationalGeneric;
  332. InitAnsi;
  333. end;
  334. function SysErrorMessage(ErrorCode: Integer): String;
  335. begin
  336. Result:=Format(SUnknownErrorCode,[ErrorCode]);
  337. end;
  338. {****************************************************************************
  339. Os utils
  340. ****************************************************************************}
  341. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  342. var
  343. hp : ppchar;
  344. hs : string;
  345. eqpos : longint;
  346. begin
  347. result:='';
  348. hp:=envp;
  349. if hp<>nil then
  350. while assigned(hp^) do
  351. begin
  352. hs:=strpas(hp^);
  353. eqpos:=pos('=',hs);
  354. if copy(hs,1,eqpos-1)=envvar then
  355. begin
  356. result:=copy(hs,eqpos+1,length(hs)-eqpos);
  357. break;
  358. end;
  359. inc(hp);
  360. end;
  361. end;
  362. Function GetEnvironmentVariableCount : Integer;
  363. var
  364. p: ppchar;
  365. begin
  366. result:=0;
  367. p:=envp; {defined in system}
  368. if p<>nil then
  369. while p^<>nil do
  370. begin
  371. inc(result);
  372. inc(p);
  373. end;
  374. end;
  375. Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
  376. Var
  377. i : longint;
  378. p : ppchar;
  379. begin
  380. if (Index <= 0) or (envp=nil) then
  381. result:=''
  382. else
  383. begin
  384. p:=envp; {defined in system}
  385. i:=1;
  386. while (i<Index) and (p^<>nil) do
  387. begin
  388. inc(i);
  389. inc(p);
  390. end;
  391. if p^=nil then
  392. result:=''
  393. else
  394. result:=strpas(p^)
  395. end;
  396. end;
  397. function ExecuteProcess(Const Path: RawByteString; Const ComLine: RawByteString;Flags:TExecuteFlags=[]):integer;
  398. begin
  399. end;
  400. function ExecuteProcess (const Path: RawByteString;
  401. const ComLine: array of RawByteString;Flags:TExecuteFlags=[]): integer;
  402. begin
  403. end;
  404. {*************************************************************************
  405. Sleep
  406. *************************************************************************}
  407. procedure Sleep (MilliSeconds: Cardinal);
  408. var
  409. subscription: __wasi_subscription_t;
  410. event: __wasi_event_t;
  411. nevents: __wasi_size_t;
  412. begin
  413. FillChar(subscription,SizeOf(subscription),0);
  414. subscription.u.tag:=__WASI_EVENTTYPE_CLOCK;
  415. subscription.u.u.clock.id:=__WASI_CLOCKID_MONOTONIC;
  416. subscription.u.u.clock.timeout:=MilliSeconds*1000000;
  417. subscription.u.u.clock.precision:=1000000;
  418. subscription.u.u.clock.flags:=0; { timeout value is relative }
  419. __wasi_poll_oneoff(@subscription,@event,1,@nevents);
  420. end;
  421. {****************************************************************************
  422. Initialization code
  423. ****************************************************************************}
  424. Initialization
  425. InitExceptions; { Initialize exceptions. OS independent }
  426. InitInternational; { Initialize internationalization settings }
  427. OnBeep:=@SysBeep;
  428. InitTZ;
  429. Finalization
  430. FreeTerminateProcs;
  431. DoneExceptions;
  432. end.