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