sysdir.inc 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. {*****************************************************************************
  12. Directory Handling
  13. *****************************************************************************}
  14. procedure Do_MkDir(s: rawbytestring);
  15. var
  16. fd: __wasi_fd_t;
  17. pr: RawByteString;
  18. res: __wasi_errno_t;
  19. begin
  20. InOutRes:=ConvertToFdRelativePath(s,fd,pr);
  21. if InOutRes<>0 then
  22. exit;
  23. res:=__wasi_path_create_directory(fd,PAnsiChar(pr),Length(pr));
  24. if res<>__WASI_ERRNO_SUCCESS then
  25. InOutRes:=Errno2InoutRes(res);
  26. end;
  27. procedure Do_RmDir(s: rawbytestring);
  28. var
  29. fd: __wasi_fd_t;
  30. pr: RawByteString;
  31. res: __wasi_errno_t;
  32. begin
  33. InOutRes:=ConvertToFdRelativePath(s,fd,pr);
  34. if InOutRes<>0 then
  35. exit;
  36. res:=__wasi_path_remove_directory(fd,PAnsiChar(pr),Length(pr));
  37. if res<>__WASI_ERRNO_SUCCESS then
  38. InOutRes:=Errno2InoutRes(res);
  39. end;
  40. procedure do_ChDir_internal(s: rawbytestring; SymLinkFollowCount: longint);
  41. function GetNextPart: RawByteString;
  42. var
  43. slashpos,backslashpos: longint;
  44. begin
  45. slashpos:=Pos('/',s);
  46. backslashpos:=Pos('\',s);
  47. if (slashpos<>0) and ((slashpos<backslashpos) or (backslashpos=0)) then
  48. begin
  49. result:=Copy(s,1,slashpos-1);
  50. delete(s,1,slashpos);
  51. end
  52. else if backslashpos<>0 then
  53. begin
  54. result:=Copy(s,1,backslashpos-1);
  55. delete(s,1,backslashpos);
  56. end
  57. else
  58. begin
  59. result:=s;
  60. s:='';
  61. end;
  62. while (s<>'') and (s[1] in AllowDirectorySeparators) do
  63. delete(s,1,1);
  64. end;
  65. var
  66. new_drive_nr: longint;
  67. new_dir,new_dir_save,next_dir_part: RawByteString;
  68. fd: __wasi_fd_t;
  69. pr: RawByteString;
  70. st: __wasi_filestat_t;
  71. res: __wasi_errno_t;
  72. symlink: RawByteString;
  73. begin
  74. if SymLinkFollowCount<0 then
  75. begin
  76. InOutRes:=40;
  77. exit;
  78. end;
  79. if HasDriveLetter(s) then
  80. begin
  81. new_drive_nr:=Ord(UpCase(s[1]))-(Ord('A')-1);
  82. delete(s,1,2);
  83. end
  84. else
  85. new_drive_nr:=current_drive;
  86. if (new_drive_nr>=drives_count) or (current_dirs[new_drive_nr].dir_name='') then
  87. begin
  88. InoutRes:=15;
  89. exit;
  90. end;
  91. new_dir:=current_dirs[new_drive_nr].dir_name;
  92. if s<>'' then
  93. begin
  94. if s[1] in AllowDirectorySeparators then
  95. begin
  96. delete(s,1,1);
  97. new_dir:=DirectorySeparator;
  98. end;
  99. while s<>'' do
  100. begin
  101. next_dir_part:=GetNextPart;
  102. if next_dir_part='.' then
  103. {nothing to do}
  104. else if next_dir_part='..' then
  105. begin
  106. if (new_dir<>'') and not (new_dir[Length(new_dir)] in AllowDirectorySeparators) then
  107. begin
  108. while (new_dir<>'') and not (new_dir[Length(new_dir)] in AllowDirectorySeparators) do
  109. delete(new_dir,Length(new_dir),1);
  110. while (new_dir<>'') and (new_dir[Length(new_dir)] in AllowDirectorySeparators) do
  111. delete(new_dir,Length(new_dir),1);
  112. if (Pos('/',new_dir)=0) and (Pos('\',new_dir)=0) then
  113. new_dir:=new_dir+DirectorySeparator;
  114. end;
  115. end
  116. else
  117. begin
  118. new_dir_save:=new_dir;
  119. if (new_dir<>'') and (new_dir[Length(new_dir)] in AllowDirectorySeparators) then
  120. new_dir:=new_dir+next_dir_part
  121. else
  122. new_dir:=new_dir+DirectorySeparator+next_dir_part;
  123. if ConvertToFdRelativePath(current_dirs[new_drive_nr].drive_str+new_dir,fd,pr)<>0 then
  124. begin
  125. {...}
  126. InOutRes:=3;
  127. exit;
  128. end;
  129. res:=__wasi_path_filestat_get(fd,0,PAnsiChar(pr),Length(pr),@st);
  130. if res<>__WASI_ERRNO_SUCCESS then
  131. begin
  132. if res=__WASI_ERRNO_NOENT then
  133. InOutRes:=3
  134. else
  135. InOutRes:=Errno2InoutRes(res);
  136. exit;
  137. end;
  138. if st.filetype=__WASI_FILETYPE_SYMBOLIC_LINK then
  139. begin
  140. res:=fpc_wasi_path_readlink_ansistring(fd,PAnsiChar(pr),Length(pr),symlink);
  141. if res<>__WASI_ERRNO_SUCCESS then
  142. begin
  143. InOutRes:=Errno2InoutRes(res);
  144. exit;
  145. end;
  146. if (symlink<>'') and (symlink[1] in AllowDirectorySeparators) then
  147. do_ChDir_internal(symlink,SymLinkFollowCount-1)
  148. else if (new_dir_save<>'') and (new_dir_save[length(new_dir_save)] in AllowDirectorySeparators) then
  149. do_ChDir_internal(current_dirs[new_drive_nr].drive_str+new_dir_save+symlink,SymLinkFollowCount-1)
  150. else
  151. do_ChDir_internal(current_dirs[new_drive_nr].drive_str+new_dir_save+DirectorySeparator+symlink,SymLinkFollowCount-1);
  152. exit;
  153. end
  154. else if st.filetype<>__WASI_FILETYPE_DIRECTORY then
  155. begin
  156. InOutRes:=5;
  157. exit;
  158. end;
  159. end;
  160. end;
  161. end;
  162. current_drive:=new_drive_nr;
  163. current_dirs[new_drive_nr].dir_name:=new_dir;
  164. InOutRes:=0;
  165. end;
  166. procedure do_ChDir(s: rawbytestring);
  167. begin
  168. do_ChDir_internal(s, 40);
  169. end;
  170. procedure do_getdir(drivenr : byte;var dir : rawbytestring);
  171. begin
  172. if drivenr=0 then
  173. drivenr:=current_drive;
  174. if (drivenr<drives_count) and (current_dirs[drivenr].dir_name<>'') then
  175. begin
  176. dir:=current_dirs[drivenr].drive_str+current_dirs[drivenr].dir_name;
  177. InOutRes:=0;
  178. end
  179. else
  180. InoutRes:=15;
  181. end;