sysfile.inc 8.6 KB

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