sysfile.inc 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Main OS dependant body of the system unit, loosely modelled
  4. after POSIX. *BSD version (Linux version is near identical)
  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. procedure Do_Close(Handle:thandle);
  12. var
  13. res: __wasi_errno_t;
  14. begin
  15. repeat
  16. res:=__wasi_fd_close(Handle);
  17. until (res=__WASI_ERRNO_SUCCESS) or (res<>__WASI_ERRNO_INTR);
  18. if res=__WASI_ERRNO_SUCCESS then
  19. InOutRes:=0
  20. else
  21. InOutRes:=Errno2InoutRes(res);
  22. end;
  23. procedure Do_Erase(p: PAnsiChar; pchangeable: boolean);
  24. var
  25. fd: __wasi_fd_t;
  26. pr: RawByteString;
  27. res: __wasi_errno_t;
  28. begin
  29. InOutRes:=ConvertToFdRelativePath(p,fd,pr);
  30. if InOutRes<>0 then
  31. exit;
  32. res:=__wasi_path_unlink_file(fd,PAnsiChar(pr),Length(pr));
  33. if res<>__WASI_ERRNO_SUCCESS then
  34. InOutRes:=Errno2InoutRes(res);
  35. end;
  36. procedure do_truncate (handle:thandle;fpos:int64);
  37. var
  38. res: __wasi_errno_t;
  39. begin
  40. res:=__wasi_fd_filestat_set_size(handle,fpos);
  41. if res=__WASI_ERRNO_SUCCESS then
  42. InOutRes:=0
  43. else
  44. InOutRes:=Errno2InoutRes(res);
  45. end;
  46. procedure Do_Rename(p1,p2:PAnsiChar; p1changeable, p2changeable: boolean);
  47. var
  48. fd1,fd2: __wasi_fd_t;
  49. pr1,pr2: RawByteString;
  50. res: __wasi_errno_t;
  51. begin
  52. InOutRes:=ConvertToFdRelativePath(p1,fd1,pr1);
  53. if InOutRes<>0 then
  54. exit;
  55. InOutRes:=ConvertToFdRelativePath(p2,fd2,pr2);
  56. if InOutRes<>0 then
  57. exit;
  58. res:=__wasi_path_rename(fd1,PAnsiChar(pr1),Length(pr1),fd2,PAnsiChar(pr2),Length(pr2));
  59. if res<>__WASI_ERRNO_SUCCESS then
  60. InOutRes:=Errno2InoutRes(res);
  61. end;
  62. function Do_Write(Handle:thandle;Addr:Pointer;Len:Longint):longint;
  63. var
  64. our_iov: __wasi_ciovec_t;
  65. our_nwritten: longint;
  66. res: __wasi_errno_t;
  67. begin
  68. repeat
  69. our_iov.buf := Addr;
  70. our_iov.buf_len := Len;
  71. res:=__wasi_fd_write(Handle, @our_iov, 1, @our_nwritten);
  72. until (res=__WASI_ERRNO_SUCCESS) or ((res<>__WASI_ERRNO_INTR) and (res<>__WASI_ERRNO_AGAIN));
  73. if res=__WASI_ERRNO_SUCCESS then
  74. begin
  75. Do_Write:=our_nwritten;
  76. InOutRes:=0;
  77. end
  78. else
  79. begin
  80. Do_Write:=0;
  81. InOutRes:=Errno2InoutRes(res);
  82. end;
  83. end;
  84. function Do_Read(Handle:thandle;Addr:Pointer;Len:Longint):Longint;
  85. var
  86. our_iov: __wasi_iovec_t;
  87. our_nread: __wasi_size_t;
  88. res: __wasi_errno_t;
  89. begin
  90. repeat
  91. our_iov.buf:=Addr;
  92. our_iov.buf_len:=Len;
  93. res:=__wasi_fd_read(Handle,@our_iov,1,@our_nread);
  94. until (res=__WASI_ERRNO_SUCCESS) or ((res<>__WASI_ERRNO_INTR) and (res<>__WASI_ERRNO_AGAIN));
  95. if res=__WASI_ERRNO_SUCCESS then
  96. begin
  97. Do_Read:=our_nread;
  98. InOutRes:=0;
  99. end
  100. else
  101. begin
  102. Do_Read:=0;
  103. InOutRes:=Errno2InoutRes(res);
  104. end;
  105. end;
  106. function Do_FilePos(Handle: thandle):Int64;
  107. var
  108. res: __wasi_errno_t;
  109. fpos:__wasi_filesize_t;
  110. begin
  111. res:=__wasi_fd_tell(Handle,@fpos);
  112. if res=__WASI_ERRNO_SUCCESS then
  113. begin
  114. InOutRes:=0;
  115. Do_FilePos:=fpos;
  116. end
  117. else
  118. begin
  119. InOutRes:=Errno2InoutRes(res);
  120. Do_FilePos:=-1;
  121. end;
  122. end;
  123. procedure Do_Seek(Handle:thandle;Pos:Int64);
  124. var
  125. res: __wasi_errno_t;
  126. newoffset: __wasi_filesize_t;
  127. begin
  128. res:=__wasi_fd_seek(Handle,Pos,__WASI_WHENCE_SET,@newoffset);
  129. if res=__WASI_ERRNO_SUCCESS then
  130. InOutRes:=0
  131. else
  132. InOutRes:=Errno2InoutRes(res);
  133. end;
  134. function Do_Seekend(Handle:thandle):Int64;
  135. var
  136. res: __wasi_errno_t;
  137. newoffset: __wasi_filesize_t;
  138. begin
  139. res:=__wasi_fd_seek(Handle,0,__WASI_WHENCE_END,@newoffset);
  140. if res=__WASI_ERRNO_SUCCESS then
  141. begin
  142. InOutRes:=0;
  143. Do_Seekend:=newoffset;
  144. end
  145. else
  146. begin
  147. InOutRes:=Errno2InoutRes(res);
  148. Do_Seekend:=-1;
  149. end;
  150. end;
  151. function Do_FileSize(Handle:thandle):Int64;
  152. var
  153. res: __wasi_errno_t;
  154. buf: __wasi_filestat_t;
  155. begin
  156. res:=__wasi_fd_filestat_get(Handle, @buf);
  157. if res=__WASI_ERRNO_SUCCESS then
  158. begin
  159. InOutRes:=0;
  160. Do_FileSize:=buf.size;
  161. end
  162. else
  163. begin
  164. InOutRes:=Errno2InoutRes(res);
  165. Do_FileSize:=0;
  166. end;
  167. end;
  168. procedure Do_Open(var f; p: PAnsiChar; flags: longint; pchangeable: boolean);
  169. {
  170. FileRec and textrec have both Handle and mode as the first items so
  171. they could use the same routine for opening/creating.
  172. when (flags and $100) the file will be append
  173. when (flags and $1000) the file will be truncate/rewritten
  174. when (flags and $10000) there is no check for close (needed for textfiles)
  175. }
  176. var
  177. oflags : __wasi_oflags_t = 0;
  178. fs_rights_base: __wasi_rights_t = 0;
  179. fdflags: __wasi_fdflags_t = 0;
  180. ourfd: __wasi_fd_t;
  181. res: __wasi_errno_t;
  182. pr: RawByteString;
  183. fd: __wasi_fd_t;
  184. Begin
  185. { close first if opened }
  186. if ((flags and $10000)=0) then
  187. begin
  188. case FileRec(f).mode of
  189. fminput,fmoutput,fminout : Do_Close(FileRec(f).Handle);
  190. fmclosed : ;
  191. else
  192. begin
  193. inoutres:=102; {not assigned}
  194. exit;
  195. end;
  196. end;
  197. end;
  198. { reset file Handle }
  199. FileRec(f).Handle:=UnusedHandle;
  200. { We do the conversion of filemodes here, concentrated on 1 place }
  201. case (flags and 3) of
  202. 0 : begin
  203. fs_rights_base :=__WASI_RIGHTS_FD_READ or
  204. __WASI_RIGHTS_FD_FILESTAT_GET or
  205. __WASI_RIGHTS_FD_SEEK or
  206. __WASI_RIGHTS_FD_TELL or
  207. __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS or
  208. __WASI_RIGHTS_FD_ADVISE or
  209. __WASI_RIGHTS_POLL_FD_READWRITE;
  210. FileRec(f).mode:=fminput;
  211. end;
  212. 1 : begin
  213. fs_rights_base :=__WASI_RIGHTS_FD_WRITE or
  214. __WASI_RIGHTS_FD_FILESTAT_GET or
  215. __WASI_RIGHTS_FD_SEEK or
  216. __WASI_RIGHTS_FD_TELL or
  217. __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS or
  218. __WASI_RIGHTS_FD_ADVISE or
  219. __WASI_RIGHTS_POLL_FD_READWRITE or
  220. __WASI_RIGHTS_FD_FILESTAT_SET_SIZE or
  221. __WASI_RIGHTS_FD_FILESTAT_SET_TIMES or
  222. __WASI_RIGHTS_FD_ALLOCATE or
  223. __WASI_RIGHTS_FD_DATASYNC or
  224. __WASI_RIGHTS_FD_SYNC;
  225. FileRec(f).mode:=fmoutput;
  226. end;
  227. 2 : begin
  228. fs_rights_base :=__WASI_RIGHTS_FD_READ or
  229. __WASI_RIGHTS_FD_WRITE or
  230. __WASI_RIGHTS_FD_FILESTAT_GET or
  231. __WASI_RIGHTS_FD_SEEK or
  232. __WASI_RIGHTS_FD_TELL or
  233. __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS or
  234. __WASI_RIGHTS_FD_ADVISE or
  235. __WASI_RIGHTS_POLL_FD_READWRITE or
  236. __WASI_RIGHTS_FD_FILESTAT_SET_SIZE or
  237. __WASI_RIGHTS_FD_FILESTAT_SET_TIMES or
  238. __WASI_RIGHTS_FD_ALLOCATE or
  239. __WASI_RIGHTS_FD_DATASYNC or
  240. __WASI_RIGHTS_FD_SYNC;
  241. FileRec(f).mode:=fminout;
  242. end;
  243. end;
  244. if (flags and $1000)=$1000 then
  245. oflags:=oflags or (__WASI_OFLAGS_CREAT or __WASI_OFLAGS_TRUNC)
  246. else
  247. if (flags and $100)=$100 then
  248. fdflags:=fdflags or __WASI_FDFLAGS_APPEND;
  249. { empty name is special }
  250. if p[0]=#0 then
  251. begin
  252. case FileRec(f).mode of
  253. fminput :
  254. FileRec(f).Handle:=StdInputHandle;
  255. fminout, { this is set by rewrite }
  256. fmoutput :
  257. FileRec(f).Handle:=StdOutputHandle;
  258. fmappend :
  259. begin
  260. FileRec(f).Handle:=StdOutputHandle;
  261. FileRec(f).mode:=fmoutput; {fool fmappend}
  262. end;
  263. end;
  264. exit;
  265. end;
  266. InOutRes:=ConvertToFdRelativePath(p,fd,pr);
  267. if InOutRes<>0 then
  268. exit;
  269. { real open call }
  270. repeat
  271. res:=__wasi_path_open(fd,
  272. 0,
  273. PAnsiChar(pr),
  274. length(pr),
  275. oflags,
  276. fs_rights_base,
  277. fs_rights_base,
  278. fdflags,
  279. @ourfd);
  280. until (res=__WASI_ERRNO_SUCCESS) or (res<>__WASI_ERRNO_INTR);
  281. {if (res=__WASI_ERRNO_ROFS) and ((OFlags and O_RDWR)<>0) then
  282. begin
  283. Oflags:=Oflags and not(O_RDWR);
  284. repeat
  285. FileRec(f).Handle:=Fpopen(p,oflags,MODE_OPEN);
  286. until (FileRec(f).Handle<>-1) or (geterrno<>ESysEINTR);
  287. end;}
  288. If res<>__WASI_ERRNO_SUCCESS Then
  289. begin
  290. FileRec(f).mode:=fmclosed;
  291. InOutRes:=Errno2InoutRes(res);
  292. end
  293. else
  294. begin
  295. FileRec(f).Handle:=ourfd;
  296. InOutRes:=0;
  297. end;
  298. end;