mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-07 22:50:24 +02:00
+ added a wrapper function around __wasi_path_readlink that calls it iteratively
with doubling buffer sizes, starting with 64 bytes, until it reaches 16384 bytes, and reads the link into a rawbytestring. Use that function in all places in the WASI rtl that need to read a symlink.
This commit is contained in:
parent
0da5d57c1e
commit
21d843128d
@ -73,8 +73,6 @@ procedure do_ChDir_internal(s: rawbytestring; SymLinkFollowCount: longint);
|
||||
delete(s,1,1);
|
||||
end;
|
||||
|
||||
const
|
||||
MaxSymLinkSize = 4096;
|
||||
var
|
||||
new_drive_nr: longint;
|
||||
new_dir,new_dir_save,next_dir_part: RawByteString;
|
||||
@ -83,7 +81,6 @@ var
|
||||
st: __wasi_filestat_t;
|
||||
res: __wasi_errno_t;
|
||||
symlink: RawByteString;
|
||||
symlink_len: __wasi_size_t;
|
||||
begin
|
||||
if SymLinkFollowCount<0 then
|
||||
begin
|
||||
@ -151,14 +148,12 @@ begin
|
||||
end;
|
||||
if st.filetype=__WASI_FILETYPE_SYMBOLIC_LINK then
|
||||
begin
|
||||
SetLength(symlink,MaxSymLinkSize);
|
||||
res:=__wasi_path_readlink(fd,PChar(pr),Length(pr),@symlink[1],Length(symlink),@symlink_len);
|
||||
res:=fpc_wasi_path_readlink_ansistring(fd,PChar(pr),Length(pr),symlink);
|
||||
if res<>__WASI_ERRNO_SUCCESS then
|
||||
begin
|
||||
InOutRes:=Errno2InoutRes(res);
|
||||
exit;
|
||||
end;
|
||||
SetLength(symlink,symlink_len);
|
||||
if (symlink<>'') and (symlink[1] in AllowDirectorySeparators) then
|
||||
do_ChDir_internal(symlink,SymLinkFollowCount-1)
|
||||
else if (new_dir_save<>'') and (new_dir_save[length(new_dir_save)] in AllowDirectorySeparators) then
|
||||
|
@ -60,6 +60,33 @@ implementation
|
||||
{$I wasitypes.inc}
|
||||
{$I wasiprocs.inc}
|
||||
|
||||
function fpc_wasi_path_readlink_ansistring(
|
||||
fd: __wasi_fd_t;
|
||||
const path: PChar;
|
||||
path_len: size_t;
|
||||
out link: rawbytestring): __wasi_errno_t;[Public, Alias : 'FPC_WASI_PATH_READLINK_ANSISTRING'];
|
||||
const
|
||||
InitialBufLen=64;
|
||||
MaximumBufLen=16384;
|
||||
var
|
||||
CurrentBufLen: __wasi_size_t;
|
||||
BufUsed: __wasi_size_t;
|
||||
begin
|
||||
CurrentBufLen:=InitialBufLen div 2;
|
||||
repeat
|
||||
CurrentBufLen:=CurrentBufLen*2;
|
||||
SetLength(link,CurrentBufLen);
|
||||
result:=__wasi_path_readlink(fd,path,path_len,@(link[1]),CurrentBufLen,@BufUsed);
|
||||
until (result<>__WASI_ERRNO_SUCCESS) or ((result=__WASI_ERRNO_SUCCESS) and (BufUsed<CurrentBufLen)) or (CurrentBufLen>MaximumBufLen);
|
||||
if result=__WASI_ERRNO_SUCCESS then
|
||||
begin
|
||||
SetLength(link,BufUsed);
|
||||
setcodepage(link,DefaultRTLFileSystemCodePage,true);
|
||||
end
|
||||
else
|
||||
link:='';
|
||||
end;
|
||||
|
||||
function HasDriveLetter(const path: rawbytestring): Boolean;
|
||||
begin
|
||||
HasDriveLetter:=(Length(path)>=2) and (UpCase(path[1]) in ['A'..'Z']) and (path[2] = ':');
|
||||
|
@ -52,6 +52,12 @@ implementation
|
||||
|
||||
{$DEFINE executeprocuni} (* Only 1 byte version of ExecuteProcess is provided by the OS *)
|
||||
|
||||
function fpc_wasi_path_readlink_ansistring(
|
||||
fd: __wasi_fd_t;
|
||||
const path: PChar;
|
||||
path_len: size_t;
|
||||
out link: rawbytestring): __wasi_errno_t; external name 'FPC_WASI_PATH_READLINK_ANSISTRING';
|
||||
|
||||
Function UniversalToEpoch(year,month,day,hour,minute,second:Word):int64;
|
||||
const
|
||||
days_in_month: array [boolean, 1..12] of Byte =
|
||||
@ -453,14 +459,11 @@ end;
|
||||
|
||||
|
||||
function FileGetSymLinkTarget(const FileName: RawByteString; out SymLinkRec: TRawbyteSymLinkRec): Boolean;
|
||||
const
|
||||
MaxSymLinkSize=4096;
|
||||
var
|
||||
pr: RawByteString;
|
||||
fd: __wasi_fd_t;
|
||||
Info: __wasi_filestat_t;
|
||||
symlink: RawByteString;
|
||||
symlink_len: __wasi_size_t;
|
||||
res: __wasi_errno_t;
|
||||
begin
|
||||
FillChar(SymLinkRec, SizeOf(SymLinkRec), 0);
|
||||
@ -471,11 +474,8 @@ begin
|
||||
exit;
|
||||
if Info.filetype<>__WASI_FILETYPE_SYMBOLIC_LINK then
|
||||
exit;
|
||||
SetLength(symlink,MaxSymLinkSize);
|
||||
if __wasi_path_readlink(fd,PChar(pr),Length(pr),@symlink[1],Length(symlink),@symlink_len)<>__WASI_ERRNO_SUCCESS then
|
||||
if fpc_wasi_path_readlink_ansistring(fd,PChar(pr),Length(pr),symlink)<>__WASI_ERRNO_SUCCESS then
|
||||
exit;
|
||||
SetLength(symlink,symlink_len);
|
||||
setcodepage(symlink,DefaultRTLFileSystemCodePage,true);
|
||||
SymLinkRec.TargetName:=symlink;
|
||||
|
||||
res:=__wasi_path_filestat_get(fd,__WASI_LOOKUPFLAGS_SYMLINK_FOLLOW,PChar(pr),length(pr),@Info);
|
||||
|
Loading…
Reference in New Issue
Block a user