Browse Source

+ initial implementation of resolving relative paths

git-svn-id: trunk@49524 -
nickysn 4 years ago
parent
commit
bc08af99b0
2 changed files with 48 additions and 3 deletions
  1. 8 3
      rtl/wasi/sysfile.inc
  2. 40 0
      rtl/wasi/system.pp

+ 8 - 3
rtl/wasi/sysfile.inc

@@ -121,6 +121,8 @@ var
   fdflags: __wasi_fdflags_t = 0;
   ourfd: __wasi_fd_t;
   res: __wasi_errno_t;
+  pr: PChar;
+  fd: __wasi_fd_t;
 Begin
 { close first if opened }
   if ((flags and $10000)=0) then
@@ -174,12 +176,14 @@ Begin
      end;
      exit;
    end;
+  if not ConvertToFdRelativePath(p,fd,pr) then
+    exit;
 { real open call }
   repeat
-    res:=__wasi_path_open(3,  { not sure about this fd... }
+    res:=__wasi_path_open(fd,
                           0,
-                          p,
-                          strlen(p),
+                          pr,
+                          strlen(pr),
                           oflags,
                           fs_rights_base,
                           fs_rights_base,
@@ -203,4 +207,5 @@ Begin
       FileRec(f).Handle:=ourfd;
       InOutRes:=0;
     end;
+  FreeMem(pr);
 end;

+ 40 - 0
rtl/wasi/system.pp

@@ -58,6 +58,8 @@ var
   current_dir_fds: Plongint;
   current_drive: longint;
 
+function ConvertToFdRelativePath(path: PChar; out fd: LongInt; out relfd_path: PChar): Boolean;
+
 procedure DebugWrite(const P: PChar);
 procedure DebugWriteLn(const P: PChar);
 procedure DebugWriteChar(Ch: Char);
@@ -96,6 +98,44 @@ begin
   HasDriveLetter:=(path<>nil) and (UpCase(path[0]) in ['A'..'Z']) and (path[1] = ':');
 end;
 
+function ConvertToFdRelativePath(path: PChar; out fd: LongInt; out relfd_path: PChar): Boolean;
+var
+  drive_nr: longint;
+  IsAbsolutePath: Boolean;
+begin
+  fd:=0;
+  relfd_path:=nil;
+
+  if HasDriveLetter(path) then
+  begin
+    drive_nr:=Ord(UpCase(path[0]))-(Ord('A')-1);
+    inc(path,2);
+  end
+  else
+    drive_nr:=current_drive;
+  if path[0] in ['/','\'] then
+  begin
+    { todo: search absolute path in preopened dirs array }
+    InOutRes:=3;
+    ConvertToFdRelativePath:=false;
+    exit;
+  end
+  else
+  begin
+    { path is relative to a current directory }
+    if (drive_nr>=drives_count) or (current_dirs[drive_nr]=nil) then
+    begin
+      InOutRes:=15;
+      ConvertToFdRelativePath:=false;
+      exit;
+    end;
+    fd:=current_dir_fds[drive_nr];
+    relfd_path:=GetMem(1+StrLen(path));
+    Move(path^,relfd_path^,1+StrLen(path));
+    ConvertToFdRelativePath:=true;
+  end;
+end;
+
 procedure Setup_PreopenedDirs;
 var
   fd: __wasi_fd_t;