Browse Source

* keep the drive string separate in the preopen and the current dir records on
the WASI platform

Nikolay Nikolov 3 years ago
parent
commit
25ac138092
2 changed files with 31 additions and 20 deletions
  1. 11 11
      rtl/wasi/sysdir.inc
  2. 20 9
      rtl/wasi/system.pp

+ 11 - 11
rtl/wasi/sysdir.inc

@@ -99,7 +99,7 @@ begin
   end
   else
     new_drive_nr:=current_drive;
-  if (new_drive_nr>drives_count) or (current_dirs[new_drive_nr].dir_name='') then
+  if (new_drive_nr>=drives_count) or (current_dirs[new_drive_nr].dir_name='') then
   begin
     InoutRes:=15;
     exit;
@@ -110,10 +110,7 @@ begin
     if s[1] in ['/','\'] then
     begin
       delete(s,1,1);
-      if new_drive_nr>0 then
-        new_dir:=Copy(new_dir,1,2)+'/'
-      else
-        new_dir:='/';
+      new_dir:='/';
     end;
     while s<>'' do
     begin
@@ -139,7 +136,7 @@ begin
           new_dir:=new_dir+next_dir_part
         else
           new_dir:=new_dir+'/'+next_dir_part;
-        if not ConvertToFdRelativePath(new_dir,fd,pr) then
+        if not ConvertToFdRelativePath(current_dirs[new_drive_nr].drive_str+new_dir,fd,pr) then
         begin
           {...}
           InOutRes:=3;
@@ -166,10 +163,10 @@ begin
           SetLength(symlink,symlink_len);
           if (symlink<>'') and (symlink[1] in ['/', '\']) then
             do_ChDir_internal(symlink,SymLinkFollowCount-1)
-          else if (new_dir_save<>'') and (new_dir_save[1] in ['/', '\']) then
-            do_ChDir_internal(new_dir_save+symlink,SymLinkFollowCount-1)
+          else if (new_dir_save<>'') and (new_dir_save[length(new_dir_save)] in ['/', '\']) then
+            do_ChDir_internal(current_dirs[new_drive_nr].drive_str+new_dir_save+symlink,SymLinkFollowCount-1)
           else
-            do_ChDir_internal(new_dir_save+'/'+symlink,SymLinkFollowCount-1);
+            do_ChDir_internal(current_dirs[new_drive_nr].drive_str+new_dir_save+'/'+symlink,SymLinkFollowCount-1);
           exit;
         end
         else if st.filetype<>__WASI_FILETYPE_DIRECTORY then
@@ -194,8 +191,11 @@ procedure do_getdir(drivenr : byte;var dir : rawbytestring);
 begin
   if drivenr=0 then
     drivenr:=current_drive;
-  if (drivenr<=drives_count) and (current_dirs[drivenr].dir_name<>'') then
-    dir:=current_dirs[drivenr].dir_name
+  if (drivenr<drives_count) and (current_dirs[drivenr].dir_name<>'') then
+  begin
+    dir:=current_dirs[drivenr].drive_str+current_dirs[drivenr].dir_name;
+    InOutRes:=0;
+  end
   else
     InoutRes:=15;
 end;

+ 20 - 9
rtl/wasi/system.pp

@@ -69,11 +69,13 @@ type
   PPreopenedDir = ^TPreopenedDir;
   TPreopenedDir = record
     dir_name: ansistring;
+    drive_str: ansistring;
     fd: longint;
   end;
   PCurrentDir = ^TCurrentDir;
   TCurrentDir = record
     dir_name: ansistring;
+    drive_str: ansistring;
   end;
 
 var
@@ -136,8 +138,6 @@ begin
       path:=current_dirs[drive_nr].dir_name+path
     else
       path:=current_dirs[drive_nr].dir_name+'/'+path;
-    if HasDriveLetter(path) then
-      delete(path,1,2);
   end;
   { path is now absolute. Try to find it in the preopened dirs array }
   ConvertToFdRelativePath:=false;
@@ -145,11 +145,8 @@ begin
   for I:=0 to preopened_dirs_count-1 do
   begin
     pdir:=preopened_dirs[I].dir_name;
-    if HasDriveLetter(pdir) then
-    begin
-      pdir_drive:=Ord(UpCase(pdir[1]))-(Ord('A')-1);
-      delete(pdir,1,2);
-    end
+    if preopened_dirs[I].drive_str<>'' then
+      pdir_drive:=Ord(UpCase(preopened_dirs[I].drive_str[1]))-(Ord('A')-1)
     else
       pdir_drive:=0;
     if pdir_drive<>drive_nr then
@@ -206,12 +203,19 @@ begin
             preopened_dirs:=AllocMem(preopened_dirs_count*SizeOf(TPreopenedDir))
           else
             ReAllocMem(preopened_dirs, preopened_dirs_count*SizeOf(TPreopenedDir));
-          preopened_dirs[preopened_dirs_count-1].dir_name:=prestat_dir_name;
           preopened_dirs[preopened_dirs_count-1].fd:=fd;
           if HasDriveLetter(prestat_dir_name) then
-            drive_nr:=Ord(UpCase(prestat_dir_name[1]))-(Ord('A')-1)
+          begin
+            drive_nr:=Ord(UpCase(prestat_dir_name[1]))-(Ord('A')-1);
+            preopened_dirs[preopened_dirs_count-1].drive_str:=Copy(prestat_dir_name,1,2);
+            preopened_dirs[preopened_dirs_count-1].dir_name:=Copy(prestat_dir_name,2,Length(prestat_dir_name)-2);
+          end
           else
+          begin
             drive_nr:=0;
+            preopened_dirs[preopened_dirs_count-1].drive_str:='';
+            preopened_dirs[preopened_dirs_count-1].dir_name:=prestat_dir_name;
+          end;
           if (drive_nr+1)>drives_count then
           begin
             drives_count:=drive_nr+1;
@@ -229,6 +233,13 @@ begin
   until res<>__WASI_ERRNO_SUCCESS;
   while (current_drive<drives_count) and (current_dirs[current_drive].dir_name='') do
     Inc(current_drive);
+  for drive_nr:=0 to drives_count-1 do
+  begin
+    if drive_nr>0 then
+      current_dirs[drive_nr].drive_str:=Chr(Ord('A')+drive_nr-1)+':';
+    if current_dirs[drive_nr].dir_name='' then
+      current_dirs[drive_nr].dir_name:=DirectorySeparator;
+  end;
 end;
 
 procedure Setup_Environment;