mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 08:19:36 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			314 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			314 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
{
 | 
						|
    This file is part of the Free Pascal run time library.
 | 
						|
 | 
						|
    Main OS dependant body of the system unit, loosely modelled
 | 
						|
    after POSIX.  *BSD version (Linux version is near identical)
 | 
						|
 | 
						|
    See the file COPYING.FPC, included in this distribution,
 | 
						|
    for details about the copyright.
 | 
						|
 | 
						|
    This program is distributed in the hope that it will be useful,
 | 
						|
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
						|
 | 
						|
 **********************************************************************}
 | 
						|
 | 
						|
procedure Do_Close(Handle:thandle);
 | 
						|
var
 | 
						|
  res: __wasi_errno_t;
 | 
						|
begin
 | 
						|
  repeat
 | 
						|
    res:=__wasi_fd_close(Handle);
 | 
						|
  until (res=__WASI_ERRNO_SUCCESS) or (res<>__WASI_ERRNO_INTR);
 | 
						|
  if res=__WASI_ERRNO_SUCCESS then
 | 
						|
    InOutRes:=0
 | 
						|
  else
 | 
						|
    InOutRes:=Errno2InoutRes(res);
 | 
						|
end;
 | 
						|
 | 
						|
procedure Do_Erase(p: PAnsiChar; pchangeable: boolean);
 | 
						|
var
 | 
						|
  fd: __wasi_fd_t;
 | 
						|
  pr: RawByteString;
 | 
						|
  res: __wasi_errno_t;
 | 
						|
begin
 | 
						|
  InOutRes:=ConvertToFdRelativePath(p,fd,pr);
 | 
						|
  if InOutRes<>0 then
 | 
						|
    exit;
 | 
						|
  res:=__wasi_path_unlink_file(fd,PAnsiChar(pr),Length(pr));
 | 
						|
  if res<>__WASI_ERRNO_SUCCESS then
 | 
						|
    InOutRes:=Errno2InoutRes(res);
 | 
						|
end;
 | 
						|
 | 
						|
procedure do_truncate (handle:thandle;fpos:int64);
 | 
						|
var
 | 
						|
  res: __wasi_errno_t;
 | 
						|
begin
 | 
						|
  res:=__wasi_fd_filestat_set_size(handle,fpos);
 | 
						|
  if res=__WASI_ERRNO_SUCCESS then
 | 
						|
    InOutRes:=0
 | 
						|
  else
 | 
						|
    InOutRes:=Errno2InoutRes(res);
 | 
						|
end;
 | 
						|
 | 
						|
procedure Do_Rename(p1,p2:PAnsiChar; p1changeable, p2changeable: boolean);
 | 
						|
var
 | 
						|
  fd1,fd2: __wasi_fd_t;
 | 
						|
  pr1,pr2: RawByteString;
 | 
						|
  res: __wasi_errno_t;
 | 
						|
begin
 | 
						|
  InOutRes:=ConvertToFdRelativePath(p1,fd1,pr1);
 | 
						|
  if InOutRes<>0 then
 | 
						|
    exit;
 | 
						|
  InOutRes:=ConvertToFdRelativePath(p2,fd2,pr2);
 | 
						|
  if InOutRes<>0 then
 | 
						|
    exit;
 | 
						|
  res:=__wasi_path_rename(fd1,PAnsiChar(pr1),Length(pr1),fd2,PAnsiChar(pr2),Length(pr2));
 | 
						|
  if res<>__WASI_ERRNO_SUCCESS then
 | 
						|
    InOutRes:=Errno2InoutRes(res);
 | 
						|
end;
 | 
						|
 | 
						|
function Do_Write(Handle:thandle;Addr:Pointer;Len:Longint):longint;
 | 
						|
var
 | 
						|
  our_iov: __wasi_ciovec_t;
 | 
						|
  our_nwritten: longint;
 | 
						|
  res: __wasi_errno_t;
 | 
						|
begin
 | 
						|
  repeat
 | 
						|
    our_iov.buf := Addr;
 | 
						|
    our_iov.buf_len := Len;
 | 
						|
    res:=__wasi_fd_write(Handle, @our_iov, 1, @our_nwritten);
 | 
						|
  until (res=__WASI_ERRNO_SUCCESS) or ((res<>__WASI_ERRNO_INTR) and (res<>__WASI_ERRNO_AGAIN));
 | 
						|
  if res=__WASI_ERRNO_SUCCESS then
 | 
						|
    begin
 | 
						|
      Do_Write:=our_nwritten;
 | 
						|
      InOutRes:=0;
 | 
						|
    end
 | 
						|
  else
 | 
						|
    begin
 | 
						|
      Do_Write:=0;
 | 
						|
      InOutRes:=Errno2InoutRes(res);
 | 
						|
    end;
 | 
						|
end;
 | 
						|
 | 
						|
function Do_Read(Handle:thandle;Addr:Pointer;Len:Longint):Longint;
 | 
						|
var
 | 
						|
  our_iov: __wasi_iovec_t;
 | 
						|
  our_nread: __wasi_size_t;
 | 
						|
  res: __wasi_errno_t;
 | 
						|
begin
 | 
						|
  repeat
 | 
						|
    our_iov.buf:=Addr;
 | 
						|
    our_iov.buf_len:=Len;
 | 
						|
    res:=__wasi_fd_read(Handle,@our_iov,1,@our_nread);
 | 
						|
  until (res=__WASI_ERRNO_SUCCESS) or ((res<>__WASI_ERRNO_INTR) and (res<>__WASI_ERRNO_AGAIN));
 | 
						|
  if res=__WASI_ERRNO_SUCCESS then
 | 
						|
    begin
 | 
						|
      Do_Read:=our_nread;
 | 
						|
      InOutRes:=0;
 | 
						|
    end
 | 
						|
  else
 | 
						|
    begin
 | 
						|
      Do_Read:=0;
 | 
						|
      InOutRes:=Errno2InoutRes(res);
 | 
						|
    end;
 | 
						|
end;
 | 
						|
 | 
						|
function Do_FilePos(Handle: thandle):Int64;
 | 
						|
var
 | 
						|
  res: __wasi_errno_t;
 | 
						|
  fpos:__wasi_filesize_t;
 | 
						|
begin
 | 
						|
  res:=__wasi_fd_tell(Handle,@fpos);
 | 
						|
  if res=__WASI_ERRNO_SUCCESS then
 | 
						|
  begin
 | 
						|
    InOutRes:=0;
 | 
						|
    Do_FilePos:=fpos;
 | 
						|
  end
 | 
						|
  else
 | 
						|
  begin
 | 
						|
    InOutRes:=Errno2InoutRes(res);
 | 
						|
    Do_FilePos:=-1;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure Do_Seek(Handle:thandle;Pos:Int64);
 | 
						|
var
 | 
						|
  res: __wasi_errno_t;
 | 
						|
  newoffset: __wasi_filesize_t;
 | 
						|
begin
 | 
						|
  res:=__wasi_fd_seek(Handle,Pos,__WASI_WHENCE_SET,@newoffset);
 | 
						|
  if res=__WASI_ERRNO_SUCCESS then
 | 
						|
    InOutRes:=0
 | 
						|
  else
 | 
						|
    InOutRes:=Errno2InoutRes(res);
 | 
						|
end;
 | 
						|
 | 
						|
function Do_Seekend(Handle:thandle):Int64;
 | 
						|
var
 | 
						|
  res: __wasi_errno_t;
 | 
						|
  newoffset: __wasi_filesize_t;
 | 
						|
begin
 | 
						|
  res:=__wasi_fd_seek(Handle,0,__WASI_WHENCE_END,@newoffset);
 | 
						|
  if res=__WASI_ERRNO_SUCCESS then
 | 
						|
  begin
 | 
						|
    InOutRes:=0;
 | 
						|
    Do_Seekend:=newoffset;
 | 
						|
  end
 | 
						|
  else
 | 
						|
  begin
 | 
						|
    InOutRes:=Errno2InoutRes(res);
 | 
						|
    Do_Seekend:=-1;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
function Do_FileSize(Handle:thandle):Int64;
 | 
						|
var
 | 
						|
  res: __wasi_errno_t;
 | 
						|
  buf: __wasi_filestat_t;
 | 
						|
begin
 | 
						|
  res:=__wasi_fd_filestat_get(Handle, @buf);
 | 
						|
  if res=__WASI_ERRNO_SUCCESS then
 | 
						|
  begin
 | 
						|
    InOutRes:=0;
 | 
						|
    Do_FileSize:=buf.size;
 | 
						|
  end
 | 
						|
  else
 | 
						|
  begin
 | 
						|
    InOutRes:=Errno2InoutRes(res);
 | 
						|
    Do_FileSize:=0;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure Do_Open(var f; p: PAnsiChar; flags: longint; pchangeable: boolean);
 | 
						|
{
 | 
						|
  FileRec and textrec have both Handle and mode as the first items so
 | 
						|
  they could use the same routine for opening/creating.
 | 
						|
  when (flags and $100)   the file will be append
 | 
						|
  when (flags and $1000)  the file will be truncate/rewritten
 | 
						|
  when (flags and $10000) there is no check for close (needed for textfiles)
 | 
						|
}
 | 
						|
var
 | 
						|
  oflags : __wasi_oflags_t = 0;
 | 
						|
  fs_rights_base: __wasi_rights_t = 0;
 | 
						|
  fdflags: __wasi_fdflags_t = 0;
 | 
						|
  ourfd: __wasi_fd_t;
 | 
						|
  res: __wasi_errno_t;
 | 
						|
  pr: RawByteString;
 | 
						|
  fd: __wasi_fd_t;
 | 
						|
Begin
 | 
						|
{ close first if opened }
 | 
						|
  if ((flags and $10000)=0) then
 | 
						|
   begin
 | 
						|
     case FileRec(f).mode of
 | 
						|
      fminput,fmoutput,fminout : Do_Close(FileRec(f).Handle);
 | 
						|
      fmclosed : ;
 | 
						|
     else
 | 
						|
      begin
 | 
						|
        inoutres:=102; {not assigned}
 | 
						|
        exit;
 | 
						|
      end;
 | 
						|
     end;
 | 
						|
   end;
 | 
						|
{ reset file Handle }
 | 
						|
  FileRec(f).Handle:=UnusedHandle;
 | 
						|
{ We do the conversion of filemodes here, concentrated on 1 place }
 | 
						|
  case (flags and 3) of
 | 
						|
   0 : begin
 | 
						|
         fs_rights_base :=__WASI_RIGHTS_FD_READ or
 | 
						|
                          __WASI_RIGHTS_FD_FILESTAT_GET or
 | 
						|
                          __WASI_RIGHTS_FD_SEEK or
 | 
						|
                          __WASI_RIGHTS_FD_TELL or
 | 
						|
                          __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS or
 | 
						|
                          __WASI_RIGHTS_FD_ADVISE or
 | 
						|
                          __WASI_RIGHTS_POLL_FD_READWRITE;
 | 
						|
         FileRec(f).mode:=fminput;
 | 
						|
       end;
 | 
						|
   1 : begin
 | 
						|
         fs_rights_base :=__WASI_RIGHTS_FD_WRITE or
 | 
						|
                          __WASI_RIGHTS_FD_FILESTAT_GET or
 | 
						|
                          __WASI_RIGHTS_FD_SEEK or
 | 
						|
                          __WASI_RIGHTS_FD_TELL or
 | 
						|
                          __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS or
 | 
						|
                          __WASI_RIGHTS_FD_ADVISE or
 | 
						|
                          __WASI_RIGHTS_POLL_FD_READWRITE or
 | 
						|
                          __WASI_RIGHTS_FD_FILESTAT_SET_SIZE or
 | 
						|
                          __WASI_RIGHTS_FD_FILESTAT_SET_TIMES or
 | 
						|
                          __WASI_RIGHTS_FD_ALLOCATE or
 | 
						|
                          __WASI_RIGHTS_FD_DATASYNC or
 | 
						|
                          __WASI_RIGHTS_FD_SYNC;
 | 
						|
         FileRec(f).mode:=fmoutput;
 | 
						|
       end;
 | 
						|
   2 : begin
 | 
						|
         fs_rights_base :=__WASI_RIGHTS_FD_READ or
 | 
						|
                          __WASI_RIGHTS_FD_WRITE or
 | 
						|
                          __WASI_RIGHTS_FD_FILESTAT_GET or
 | 
						|
                          __WASI_RIGHTS_FD_SEEK or
 | 
						|
                          __WASI_RIGHTS_FD_TELL or
 | 
						|
                          __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS or
 | 
						|
                          __WASI_RIGHTS_FD_ADVISE or
 | 
						|
                          __WASI_RIGHTS_POLL_FD_READWRITE or
 | 
						|
                          __WASI_RIGHTS_FD_FILESTAT_SET_SIZE or
 | 
						|
                          __WASI_RIGHTS_FD_FILESTAT_SET_TIMES or
 | 
						|
                          __WASI_RIGHTS_FD_ALLOCATE or
 | 
						|
                          __WASI_RIGHTS_FD_DATASYNC or
 | 
						|
                          __WASI_RIGHTS_FD_SYNC;
 | 
						|
         FileRec(f).mode:=fminout;
 | 
						|
       end;
 | 
						|
  end;
 | 
						|
  if (flags and $1000)=$1000 then
 | 
						|
   oflags:=oflags or (__WASI_OFLAGS_CREAT or __WASI_OFLAGS_TRUNC)
 | 
						|
  else
 | 
						|
   if (flags and $100)=$100 then
 | 
						|
    fdflags:=fdflags or __WASI_FDFLAGS_APPEND;
 | 
						|
{ empty name is special }
 | 
						|
  if p[0]=#0 then
 | 
						|
   begin
 | 
						|
     case FileRec(f).mode of
 | 
						|
       fminput :
 | 
						|
         FileRec(f).Handle:=StdInputHandle;
 | 
						|
       fminout, { this is set by rewrite }
 | 
						|
       fmoutput :
 | 
						|
         FileRec(f).Handle:=StdOutputHandle;
 | 
						|
       fmappend :
 | 
						|
         begin
 | 
						|
           FileRec(f).Handle:=StdOutputHandle;
 | 
						|
           FileRec(f).mode:=fmoutput; {fool fmappend}
 | 
						|
         end;
 | 
						|
     end;
 | 
						|
     exit;
 | 
						|
   end;
 | 
						|
  InOutRes:=ConvertToFdRelativePath(p,fd,pr);
 | 
						|
  if InOutRes<>0 then
 | 
						|
    exit;
 | 
						|
{ real open call }
 | 
						|
  repeat
 | 
						|
    res:=__wasi_path_open(fd,
 | 
						|
                          0,
 | 
						|
                          PAnsiChar(pr),
 | 
						|
                          length(pr),
 | 
						|
                          oflags,
 | 
						|
                          fs_rights_base,
 | 
						|
                          fs_rights_base,
 | 
						|
                          fdflags,
 | 
						|
                          @ourfd);
 | 
						|
  until (res=__WASI_ERRNO_SUCCESS) or (res<>__WASI_ERRNO_INTR);
 | 
						|
  {if (res=__WASI_ERRNO_ROFS) and ((OFlags and O_RDWR)<>0) then
 | 
						|
   begin
 | 
						|
     Oflags:=Oflags and not(O_RDWR);
 | 
						|
     repeat
 | 
						|
       FileRec(f).Handle:=Fpopen(p,oflags,MODE_OPEN);
 | 
						|
     until (FileRec(f).Handle<>-1) or (geterrno<>ESysEINTR);
 | 
						|
   end;}
 | 
						|
  If res<>__WASI_ERRNO_SUCCESS Then
 | 
						|
    begin
 | 
						|
      FileRec(f).mode:=fmclosed;
 | 
						|
      InOutRes:=Errno2InoutRes(res);
 | 
						|
    end
 | 
						|
  else
 | 
						|
    begin
 | 
						|
      FileRec(f).Handle:=ourfd;
 | 
						|
      InOutRes:=0;
 | 
						|
    end;
 | 
						|
end;
 |