Browse Source

+ initial implementation of GetDir() for WASI

git-svn-id: trunk@49522 -
nickysn 4 years ago
parent
commit
d3ce008cd3
2 changed files with 41 additions and 2 deletions
  1. 6 1
      rtl/wasi/sysdir.inc
  2. 35 1
      rtl/wasi/system.pp

+ 6 - 1
rtl/wasi/sysdir.inc

@@ -35,5 +35,10 @@ end;
 
 
 procedure do_getdir(drivenr : byte;var dir : rawbytestring);
 procedure do_getdir(drivenr : byte;var dir : rawbytestring);
 begin
 begin
-  DebugWriteLn('do_getdir');
+  if drivenr=0 then
+    drivenr:=current_drive;
+  if (drivenr<=drives_count) and (current_dirs[drivenr]<>nil) then
+    dir:=current_dirs[drivenr]
+  else
+    InoutRes:=15;
 end;
 end;

+ 35 - 1
rtl/wasi/system.pp

@@ -53,6 +53,9 @@ var
   argv: PPChar;
   argv: PPChar;
   preopened_dirs_count: longint;
   preopened_dirs_count: longint;
   preopened_dirs: PPChar;
   preopened_dirs: PPChar;
+  drives_count: longint;
+  current_dirs: PPChar;
+  current_drive: longint;
 
 
 procedure DebugWrite(const P: PChar);
 procedure DebugWrite(const P: PChar);
 procedure DebugWriteLn(const P: PChar);
 procedure DebugWriteLn(const P: PChar);
@@ -87,15 +90,24 @@ begin
   __wasi_proc_exit(ExitCode);
   __wasi_proc_exit(ExitCode);
 End;
 End;
 
 
+function HasDriveLetter(const path: PChar): Boolean;
+begin
+  HasDriveLetter:=(path<>nil) and (UpCase(path[0]) in ['A'..'Z']) and (path[1] = ':');
+end;
+
 procedure Setup_PreopenedDirs;
 procedure Setup_PreopenedDirs;
 var
 var
   fd: __wasi_fd_t;
   fd: __wasi_fd_t;
   prestat: __wasi_prestat_t;
   prestat: __wasi_prestat_t;
   res: __wasi_errno_t;
   res: __wasi_errno_t;
   prestat_dir_name: PChar;
   prestat_dir_name: PChar;
+  drive_nr: longint;
 begin
 begin
   preopened_dirs_count:=0;
   preopened_dirs_count:=0;
   preopened_dirs:=nil;
   preopened_dirs:=nil;
+  drives_count:=0;
+  current_dirs:=nil;
+  current_drive:=0;
   fd:=3;
   fd:=3;
   repeat
   repeat
     res:=__wasi_fd_prestat_get(fd, @prestat);
     res:=__wasi_fd_prestat_get(fd, @prestat);
@@ -108,8 +120,28 @@ begin
         begin
         begin
           prestat_dir_name[prestat.u.dir.pr_name_len]:=#0;
           prestat_dir_name[prestat.u.dir.pr_name_len]:=#0;
           Inc(preopened_dirs_count);
           Inc(preopened_dirs_count);
-          ReAllocMem(preopened_dirs, preopened_dirs_count*SizeOf(PChar));
+          if preopened_dirs=nil then
+            preopened_dirs:=AllocMem(preopened_dirs_count*SizeOf(PChar))
+          else
+            ReAllocMem(preopened_dirs, preopened_dirs_count*SizeOf(PChar));
           preopened_dirs[preopened_dirs_count-1]:=prestat_dir_name;
           preopened_dirs[preopened_dirs_count-1]:=prestat_dir_name;
+          if HasDriveLetter(prestat_dir_name) then
+            drive_nr:=Ord(UpCase(prestat_dir_name[0]))-(Ord('A')-1)
+          else
+            drive_nr:=0;
+          if (drive_nr+1)>drives_count then
+          begin
+            drives_count:=drive_nr+1;
+            if current_dirs=nil then
+              current_dirs:=AllocMem(drives_count*SizeOf(PChar))
+            else
+              ReAllocMem(current_dirs,drives_count*SizeOf(PChar));
+          end;
+          if current_dirs[drive_nr]=nil then
+          begin
+            current_dirs[drive_nr]:=GetMem(1+StrLen(prestat_dir_name));
+            Move(prestat_dir_name^,current_dirs[drive_nr]^,StrLen(prestat_dir_name)+1);
+          end;
         end
         end
         else
         else
           FreeMem(prestat_dir_name,prestat.u.dir.pr_name_len+1);
           FreeMem(prestat_dir_name,prestat.u.dir.pr_name_len+1);
@@ -117,6 +149,8 @@ begin
     end;
     end;
     Inc(fd);
     Inc(fd);
   until res<>__WASI_ERRNO_SUCCESS;
   until res<>__WASI_ERRNO_SUCCESS;
+  while (current_drive<drives_count) and (current_dirs[current_drive]=nil) do
+    Inc(current_drive);
 end;
 end;
 
 
 procedure setup_arguments;
 procedure setup_arguments;