Browse Source

* preopen fd names and current dir changed to use ansistring, as well as the
parameters and result of ConvertToFdRelativePath. This will allow easier
implementation of ChDir.

Nikolay Nikolov 3 years ago
parent
commit
bae50d80d2
4 changed files with 66 additions and 101 deletions
  1. 11 25
      rtl/wasi/dos.pp
  2. 8 10
      rtl/wasi/sysdir.inc
  3. 7 14
      rtl/wasi/sysfile.inc
  4. 40 52
      rtl/wasi/system.pp

+ 11 - 25
rtl/wasi/dos.pp

@@ -457,23 +457,18 @@ End;
 
 Function FindGetFileInfo(const s:string;var f:SearchRec):boolean;
 var
-  s_ansi: ansistring;
   DT   : DateTime;
   Info : RtlInfoType;
   st   : __wasi_filestat_t;
   fd   : __wasi_fd_t;
-  pr   : PChar;
+  pr   : ansistring;
 begin
   FindGetFileInfo:=false;
-  s_ansi:=s;
-  if not ConvertToFdRelativePath(PChar(s_ansi),fd,pr) then
+  if not ConvertToFdRelativePath(s,fd,pr) then
     exit;
   { todo: __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW??? }
-  if __wasi_path_filestat_get(fd,0,pr,StrLen(pr),@st)<>__WASI_ERRNO_SUCCESS then
-    begin
-      FreeMem(pr);
-      exit;
-    end;
+  if __wasi_path_filestat_get(fd,0,PChar(pr),Length(pr),@st)<>__WASI_ERRNO_SUCCESS then
+    exit;
   info.FSize:=st.size;
   info.FMTime:=st.mtim;
   if st.filetype=__WASI_FILETYPE_DIRECTORY then
@@ -495,7 +490,6 @@ begin
      PackTime(DT,f.Time);
      FindGetFileInfo:=true;
    End;
-  FreeMem(pr);
 end;
 
 
@@ -535,9 +529,9 @@ Procedure FindNext(Var f: SearchRec);
 }
 Var
   fd,ourfd: __wasi_fd_t;
-  pr: PChar;
+  pr: ansistring;
   res: __wasi_errno_t;
-  DirName  : Array[0..256] of Char;
+  DirName  : ansistring;
   i,
   ArrayPos : Longint;
   FName,
@@ -559,23 +553,16 @@ Begin
      If ArrayPos=0 Then
       Begin
         If f.NamePos = 0 Then
-         Begin
-           DirName[0] := '.';
-           DirName[1] := '/';
-           DirName[2] := #0;
-         End
+         DirName:='./'
         Else
-         Begin
-           Move(f.SearchSpec[1], DirName[0], f.NamePos);
-           DirName[f.NamePos] := #0;
-         End;
-        if ConvertToFdRelativePath(@DirName[0],fd,pr) then
+         DirName:=Copy(f.SearchSpec,1,f.NamePos);
+        if ConvertToFdRelativePath(DirName,fd,pr) then
          begin
            repeat
              res:=__wasi_path_open(fd,
                                    0,
-                                   pr,
-                                   strlen(pr),
+                                   PChar(pr),
+                                   length(pr),
                                    __WASI_OFLAGS_DIRECTORY,
                                    __WASI_RIGHTS_FD_READDIR,
                                    __WASI_RIGHTS_FD_READDIR,
@@ -595,7 +582,6 @@ Begin
             end
            else
             f.DirFD:=-1;
-           FreeMem(pr);
          end
         else
          f.DirFD:=-1;

+ 8 - 10
rtl/wasi/sysdir.inc

@@ -21,33 +21,31 @@
 procedure Do_MkDir(s: rawbytestring);
 var
   fd: __wasi_fd_t;
-  pr: PChar;
+  pr: ansistring;
   res: __wasi_errno_t;
 begin
-  if not ConvertToFdRelativePath(PChar(s),fd,pr) then
+  if not ConvertToFdRelativePath(s,fd,pr) then
     exit;
-  res:=__wasi_path_create_directory(fd,pr,StrLen(pr));
+  res:=__wasi_path_create_directory(fd,PChar(pr),Length(pr));
   if res=__WASI_ERRNO_SUCCESS then
     InOutRes:=0
   else
     InOutRes:=Errno2InoutRes(res);
-  FreeMem(pr);
 end;
 
 procedure Do_RmDir(s: rawbytestring);
 var
   fd: __wasi_fd_t;
-  pr: PChar;
+  pr: ansistring;
   res: __wasi_errno_t;
 begin
-  if not ConvertToFdRelativePath(PChar(s),fd,pr) then
+  if not ConvertToFdRelativePath(s,fd,pr) then
     exit;
-  res:=__wasi_path_remove_directory(fd,pr,StrLen(pr));
+  res:=__wasi_path_remove_directory(fd,PChar(pr),Length(pr));
   if res=__WASI_ERRNO_SUCCESS then
     InOutRes:=0
   else
     InOutRes:=Errno2InoutRes(res);
-  FreeMem(pr);
 end;
 
 procedure do_ChDir(s: rawbytestring);
@@ -59,8 +57,8 @@ procedure do_getdir(drivenr : byte;var dir : rawbytestring);
 begin
   if drivenr=0 then
     drivenr:=current_drive;
-  if (drivenr<=drives_count) and (current_dirs[drivenr]<>nil) then
-    dir:=current_dirs[drivenr]
+  if (drivenr<=drives_count) and (current_dirs[drivenr].dir_name<>'') then
+    dir:=current_dirs[drivenr].dir_name
   else
     InoutRes:=15;
 end;

+ 7 - 14
rtl/wasi/sysfile.inc

@@ -29,17 +29,16 @@ end;
 procedure Do_Erase(p: pchar; pchangeable: boolean);
 var
   fd: __wasi_fd_t;
-  pr: PChar;
+  pr: ansistring;
   res: __wasi_errno_t;
 begin
   if not ConvertToFdRelativePath(p,fd,pr) then
     exit;
-  res:=__wasi_path_unlink_file(fd,pr,StrLen(pr));
+  res:=__wasi_path_unlink_file(fd,PChar(pr),Length(pr));
   if res=__WASI_ERRNO_SUCCESS then
     InOutRes:=0
   else
     InOutRes:=Errno2InoutRes(res);
-  FreeMem(pr);
 end;
 
 procedure do_truncate (handle:thandle;fpos:int64);
@@ -56,23 +55,18 @@ end;
 procedure Do_Rename(p1,p2:pchar; p1changeable, p2changeable: boolean);
 var
   fd1,fd2: __wasi_fd_t;
-  pr1,pr2: PChar;
+  pr1,pr2: ansistring;
   res: __wasi_errno_t;
 begin
   if not ConvertToFdRelativePath(p1,fd1,pr1) then
     exit;
   if not ConvertToFdRelativePath(p2,fd2,pr2) then
-  begin
-    FreeMem(pr1);
     exit;
-  end;
-  res:=__wasi_path_rename(fd1,pr1,StrLen(pr1),fd2,pr2,StrLen(pr2));
+  res:=__wasi_path_rename(fd1,PChar(pr1),Length(pr1),fd2,PChar(pr2),Length(pr2));
   if res=__WASI_ERRNO_SUCCESS then
     InOutRes:=0
   else
     InOutRes:=Errno2InoutRes(res);
-  FreeMem(pr1);
-  FreeMem(pr2);
 end;
 
 function Do_Write(Handle:thandle;Addr:Pointer;Len:Longint):longint;
@@ -201,7 +195,7 @@ var
   fdflags: __wasi_fdflags_t = 0;
   ourfd: __wasi_fd_t;
   res: __wasi_errno_t;
-  pr: PChar;
+  pr: ansistring;
   fd: __wasi_fd_t;
 Begin
 { close first if opened }
@@ -291,8 +285,8 @@ Begin
   repeat
     res:=__wasi_path_open(fd,
                           0,
-                          pr,
-                          strlen(pr),
+                          PChar(pr),
+                          length(pr),
                           oflags,
                           fs_rights_base,
                           fs_rights_base,
@@ -316,5 +310,4 @@ Begin
       FileRec(f).Handle:=ourfd;
       InOutRes:=0;
     end;
-  FreeMem(pr);
 end;

+ 40 - 52
rtl/wasi/system.pp

@@ -51,7 +51,12 @@ const
 type
   PPreopenedDir = ^TPreopenedDir;
   TPreopenedDir = record
-    dir_name: PChar;
+    dir_name: ansistring;
+    fd: longint;
+  end;
+  PCurrentDir = ^TCurrentDir;
+  TCurrentDir = record
+    dir_name: ansistring;
     fd: longint;
   end;
 
@@ -62,11 +67,10 @@ var
   preopened_dirs_count: longint;
   preopened_dirs: PPreopenedDir;
   drives_count: longint;
-  current_dirs: PPChar;
-  current_dir_fds: Plongint;
+  current_dirs: PCurrentDir;
   current_drive: longint;
 
-function ConvertToFdRelativePath(path: PChar; out fd: LongInt; out relfd_path: PChar): Boolean;
+function ConvertToFdRelativePath(path: ansistring; out fd: LongInt; out relfd_path: ansistring): Boolean;
 
 procedure DebugWrite(const P: PChar);
 procedure DebugWriteLn(const P: PChar);
@@ -104,64 +108,60 @@ begin
   __wasi_proc_exit(ExitCode);
 End;
 
-function HasDriveLetter(const path: PChar): Boolean;
+function HasDriveLetter(const path: rawbytestring): Boolean;
 begin
-  HasDriveLetter:=(path<>nil) and (UpCase(path[0]) in ['A'..'Z']) and (path[1] = ':');
+  HasDriveLetter:=(path<>'') and (UpCase(path[1]) in ['A'..'Z']) and (path[2] = ':');
 end;
 
-function ConvertToFdRelativePath(path: PChar; out fd: LongInt; out relfd_path: PChar): Boolean;
+function ConvertToFdRelativePath(path: ansistring; out fd: LongInt; out relfd_path: ansistring): Boolean;
 var
-  drive_nr,I,pdir_drive,longest_match,pdir_length: longint;
+  drive_nr,I,pdir_drive,longest_match,pdir_length,chridx: longint;
   IsAbsolutePath: Boolean;
-  pdir, savepath: PChar;
+  pdir: ansistring;
 begin
   fd:=0;
-  relfd_path:=nil;
+  relfd_path:='';
 
   if HasDriveLetter(path) then
   begin
-    drive_nr:=Ord(UpCase(path[0]))-(Ord('A')-1);
-    inc(path,2);
+    drive_nr:=Ord(UpCase(path[1]))-(Ord('A')-1);
+    delete(path,1,2);
   end
   else
     drive_nr:=current_drive;
-  if path[0] in ['/','\'] then
+  if path[1] in ['/','\'] then
   begin
     { path is absolute. Try to find it in the preopened dirs array }
     InOutRes:=3;
     ConvertToFdRelativePath:=false;
     longest_match:=0;
-    savepath:=path;
     for I:=0 to preopened_dirs_count-1 do
     begin
-      path:=savepath;
       pdir:=preopened_dirs[I].dir_name;
       if HasDriveLetter(pdir) then
       begin
-        pdir_drive:=Ord(UpCase(pdir[0]))-(Ord('A')-1);
-        Inc(pdir,2);
+        pdir_drive:=Ord(UpCase(pdir[1]))-(Ord('A')-1);
+        delete(pdir,1,2);
       end
       else
         pdir_drive:=0;
       if pdir_drive<>drive_nr then
         continue;
-      pdir_length:=StrLen(pdir);
-      if pdir_length>StrLen(path) then
+      pdir_length:=Length(pdir);
+      if pdir_length>Length(path) then
         continue;
-      if CompareByte(path^,pdir^,pdir_length)<>0 then
+      if Copy(path,1,pdir_length)<>Copy(pdir,1,pdir_length) then
         continue;
-      Inc(path,pdir_length);
-      if not (path^ in [#0,'/','\']) then
+      chridx:=pdir_length+1;
+      if (chridx>Length(path)) or not (path[chridx] in ['/','\']) then
         continue;
       if pdir_length>longest_match then
       begin
         longest_match:=pdir_length;
-        while path^ in ['/','\'] do
-          Inc(path);
+        while (chridx<=Length(path)) and (path[chridx] in ['/','\']) do
+          Inc(chridx);
         fd:=preopened_dirs[I].fd;
-        FreeMem(relfd_path);
-        relfd_path:=GetMem(StrLen(path)+1);
-        Move(path^,relfd_path^,StrLen(path)+1);
+        relfd_path:=Copy(path,chridx,Length(path)-chridx+1);
         InOutRes:=0;
         ConvertToFdRelativePath:=true;
       end;
@@ -170,15 +170,14 @@ begin
   else
   begin
     { path is relative to a current directory }
-    if (drive_nr>=drives_count) or (current_dirs[drive_nr]=nil) then
+    if (drive_nr>=drives_count) or (current_dirs[drive_nr].dir_name='') 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));
+    fd:=current_dirs[drive_nr].fd;
+    relfd_path:=path;
     ConvertToFdRelativePath:=true;
   end;
 end;
@@ -188,14 +187,13 @@ var
   fd: __wasi_fd_t;
   prestat: __wasi_prestat_t;
   res: __wasi_errno_t;
-  prestat_dir_name: PChar;
+  prestat_dir_name: ansistring;
   drive_nr: longint;
 begin
   preopened_dirs_count:=0;
   preopened_dirs:=nil;
   drives_count:=0;
   current_dirs:=nil;
-  current_dir_fds:=nil;
   current_drive:=0;
   fd:=3;
   repeat
@@ -204,10 +202,9 @@ begin
     begin
       if (prestat.tag=__WASI_PREOPENTYPE_DIR) and (prestat.u.dir.pr_name_len>0) then
       begin
-        GetMem(prestat_dir_name,prestat.u.dir.pr_name_len+1);
+        SetLength(prestat_dir_name,prestat.u.dir.pr_name_len);
         if __wasi_fd_prestat_dir_name(fd,PByte(prestat_dir_name),prestat.u.dir.pr_name_len)=__WASI_ERRNO_SUCCESS then
         begin
-          prestat_dir_name[prestat.u.dir.pr_name_len]:=#0;
           Inc(preopened_dirs_count);
           if preopened_dirs=nil then
             preopened_dirs:=AllocMem(preopened_dirs_count*SizeOf(TPreopenedDir))
@@ -216,37 +213,28 @@ begin
           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[0]))-(Ord('A')-1)
+            drive_nr:=Ord(UpCase(prestat_dir_name[1]))-(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
-            begin
-              current_dirs:=AllocMem(drives_count*SizeOf(PChar));
-              current_dir_fds:=AllocMem(drives_count*SizeOf(longint));
-            end
+              current_dirs:=AllocMem(drives_count*SizeOf(TCurrentDir))
             else
-            begin
-              ReAllocMem(current_dirs,drives_count*SizeOf(PChar));
-              ReAllocMem(current_dir_fds,drives_count*SizeOf(longint));
-            end;
+              ReAllocMem(current_dirs,drives_count*SizeOf(TCurrentDir));
           end;
-          if current_dirs[drive_nr]=nil then
+          if current_dirs[drive_nr].dir_name='' 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);
-            current_dir_fds[drive_nr]:=fd;
+            current_dirs[drive_nr].dir_name:=prestat_dir_name;
+            current_dirs[drive_nr].fd:=fd;
           end;
-        end
-        else
-          FreeMem(prestat_dir_name,prestat.u.dir.pr_name_len+1);
+        end;
       end;
     end;
     Inc(fd);
   until res<>__WASI_ERRNO_SUCCESS;
-  while (current_drive<drives_count) and (current_dirs[current_drive]=nil) do
+  while (current_drive<drives_count) and (current_dirs[current_drive].dir_name='') do
     Inc(current_drive);
 end;