local a=...local b={}a.vfs=b;b.mounts={["$"]="/"}b.disks=a.disks;local c=0x02;local function d(e,f)return math.floor(e/2^f)%2==1 end;local function g(h)if not h or h==""then return{}end;local i={}local j=1;local k=0;local l=h:byte(1)if l==0x02 or l==0x01 then k=l;j=2 end;while j<=#h do if j>#h then break end;local m=h:byte(j)j=j+1;if m==0 or j+m-1>#h then break end;local n=h:sub(j,j+m-1)j=j+m;local o,p,q,r,s;if k==0x02 then if j+6>#h then break end;o=h:byte(j)j=j+1;p=h:byte(j)+h:byte(j+1)*256;j=j+2;q=h:byte(j)+h:byte(j+1)*256;j=j+2;r=h:byte(j)+h:byte(j+1)*256;j=j+2 elseif k==0x01 then if j+4>#h then break end;o=h:byte(j)j=j+1;p=h:byte(j)j=j+1;q=h:byte(j)j=j+1;r=h:byte(j)+h:byte(j+1)*256;j=j+2 else if j+2>#h then break end;o=0x00;p=h:byte(j)j=j+1;q=h:byte(j)j=j+1;r=h:byte(j)j=j+1 end;if j>#h then break end;local t=h:byte(j)j=j+1;s=""if t>0 then s=h:sub(j,j+t-1)j=j+t end;i[n]={etype=o,owner=p,group=q,perms=r,cmeta=s}end;return i end;local function u(v)local w=string.char(c)for n,x in pairs(v)do local y=x.perms%256;local z=math.floor(x.perms/256)%256;local A=(x.owner or 0)%256;local B=math.floor((x.owner or 0)/256)%256;local C=(x.group or 0)%256;local D=math.floor((x.group or 0)/256)%256;w=w..string.char(#n)..n..string.char(x.etype or 0x00)..string.char(A,B,C,D,y,z)..string.char(#x.cmeta)..x.cmeta end;return w end;local E="^[A-Za-z0-9_.+%-%@%(%)%[%]]+$"local function F(G)local H=G:sub(1,1)=="/"local I={}for J in(G.."/"):gmatch("([^/]*)/")do table.insert(I,J)end;return H,I end;local function K(J)local L=J:lower()if not L:match(E)then error("EINVAL: illegal characters in path component: "..J,3)end;if L==".meta"then error("EINVAL: reserved path component: .meta",3)end end;function b.splitPath(G)local M=string.split(G,"/")while table.indexOf(M,"")~=-1 do table.remove(M,table.indexOf(M,""))end;return M end;local function N(O)local P,Q=nil,nil;for R,S in pairs(b.mounts)do local T=S~="/"and S:sub(-1)=="/"and S:sub(1,-2)or S;if O==T or T=="/"and O:sub(1,1)=="/"or O:sub(1,#T+1)==T.."/"then if not P or#T>#P then P=T;Q=R end end end;if not Q then error("ENODEV")end;local U=O:sub(#P+1)if U==""then U="/"end;return b.disks[Q],U end;b._parseMetafile=g;local function V(W,X,Y)if Y==".meta"then error("EACCES: Cannot open metafile")end;local S;if X=="/"then S=".meta"else local j=X:gsub("^/+","")S=j.."/.meta"end;local Z,_=pcall(function()return W:open(S,"r")end)if not Z or not _ then return nil end;local h=_.read(65535)if _.close then _.close()end;if h and#h>0 and h:byte(1)~=c then local a0=u(g(h))local a1,a2=pcall(function()return W:open(S,"w")end)if a1 and a2 then a2.write(a0)if a2.close then a2.close()end end;h=a0 end;local a3=g(h)return a3[Y]end;local a4=16;local function a5(G,a6,a7)a7=a7 or 0;if a7>a4 then error("ELOOP")end;local a8=a.currentTask;local a9=a8 and(a8.euid or a8.uid)or a.uid;local aa=a8 and a8.groups or a.groups or{}local ab=a8 and a8.root or"/"local ac=a8 and a8.cwd or"/"if ab~="/"and ab:sub(-1)=="/"then ab=ab:sub(1,-2)end;local function ad(ae)if a9==0 then return true end;if not ae then return true end;local af=ae.perms;if a9==ae.owner and d(af,9)then return true end;if ae.group then for ag,ah in ipairs(aa)do if ah==ae.group and d(af,8)then return true end end end;return d(af,7)end;local H,I=F(G)local ai={}if H then ai={}else for aj in ac:gmatch("[^/]+")do table.insert(ai,aj)end end;local ak=1;while ak<=#I do local J=I[ak]ak=ak+1;J=J:match("^%s*(.-)%s*$")if J==""or J=="."then elseif J==".."then local al="/"..table.concat(ai,"/")local am={}if ab~="/"then for aj in ab:gmatch("[^/]+")do table.insert(am,aj)end end;if#ai<=#am then ai={}for ag,aj in ipairs(am)do table.insert(ai,aj)end else local an=ai[#ai]local ao="/"..table.concat(ai,"/",1,#ai-1)if ao=="/"then ao="/"end;local ap,aq,ar=pcall(N,ao==""and"/"or ao)if ap and aq then local ae=V(aq,ar,an)if ae then if ae.etype~=0x00 then error("ENOTDIR: not a directory: "..al)end;if not ad(ae)then error("EACCES: permission denied traversing "..al)end else local as,at,au=pcall(N,al)if as and at then local av=at:type(au)if av~=nil and av~="directory"then error("ENOTDIR: not a directory: "..al)end end end end;table.remove(ai)end else K(J)local aw=J:lower()local ax="/"..table.concat(ai,"/")local ap,aq,ar=pcall(N,ax=="/"and"/"or ax)local ae=nil;if ap and aq then ae=V(aq,ar,aw)end;local ay=ak>#I;if ae and ae.etype==0x01 then if ay and a6 then table.insert(ai,aw)else a7=a7+1;if a7>a4 then error("ELOOP")end;local az=ae.cmeta;if not az or az==""then error("ENOENT: empty symlink target")end;local aA,aB=F(az)if aA then ai={}if ab~="/"then for aj in ab:gmatch("[^/]+")do table.insert(ai,aj)end end end;local aC={}for aD=1,ak-2 do table.insert(aC,I[aD])end;local aE=#aC+1;for ag,aF in ipairs(aB)do table.insert(aC,aF)end;for aD=ak,#I do table.insert(aC,I[aD])end;I=aC;ak=aE end else table.insert(ai,aw)if not ay then local aG="/"..table.concat(ai,"/")local as,at,au=pcall(N,aG)if as and at then local av=at:type(au)if av~=nil and av~="directory"then error("ENOTDIR: not a directory: "..aG)end end;if not ad(ae)then error("EACCES: permission denied traversing "..aG)end end end end end;local aH="/"..table.concat(ai,"/")if ab~="/"then if aH~=ab and aH:sub(1,#ab+1)~=ab.."/"then aH=ab end end;return aH end;local function aI(G)local a8=a.currentTask;local ac=a8 and a8.cwd or"/"local ab=a8 and a8.root or"/"if ab~="/"and ab:sub(-1)=="/"then ab=ab:sub(1,-2)end;local H,I=F(G)local ai={}if not H then for aj in ac:gmatch("[^/]+")do table.insert(ai,aj)end end;local am={}if ab~="/"then for aj in ab:gmatch("[^/]+")do table.insert(am,aj)end end;for ag,J in ipairs(I)do J=J:match("^%s*(.-)%s*$")if J==""or J=="."then elseif J==".."then if#ai>#am then table.remove(ai)end else table.insert(ai,J:lower())end end;local aH="/"..table.concat(ai,"/")if ab~="/"then if aH~=ab and aH:sub(1,#ab+1)~=ab.."/"then aH=ab end end;return aH end;local function aJ(G,a6)local aK=a5(G,a6)local W,U=N(aK)if a.config.logPathResolution then a.log("resolvePath '"..G.."' -> '"..aK.."' diskPath '"..U.."'")end;return W,U,aK end;local function aL(G,a6)local aK=a5(G,a6)if aK=="/"then return{etype=0x00,owner=0,group=0,perms=62,cmeta=""}end;local aM=aK;while true do local aN,n=aM:match("^(.*)/([^/]+)$")if not aN or aN==""then aN="/"end;local W,X=N(aN)local ae=V(W,X,n)if ae then return ae end;if aN=="/"or aM=="/"then break end;aM=aN end;return{etype=0x00,owner=0,group=0,perms=63,cmeta=""}end;local function aO(G,n,ae,a6)local aK=a5(G,a6)local W,U=N(aK)local S;if U=="/"then S=".meta"else S=U:gsub("^/+","").."/.meta"end;local aP={}local aQ,aR=pcall(function()return W:open(S,"r")end)if aQ and aR then local h=aR.read(65535)if aR.close then aR.close()end;aP=g(h)end;aP[n]=ae;local _=W:open(S,"w")_.write(u(aP))if _.close then _.close()end end;b.P={OWNER_R=1*2^5,OWNER_W=1*2^4,OWNER_X=1*2^9,GROUP_R=1*2^3,GROUP_W=1*2^2,GROUP_X=1*2^8,WORLD_R=1*2^1,WORLD_W=1*2^0,WORLD_X=1*2^7,SUID=1*2^6}local aS=b.P;b.PERM={RW_R_R=aS.OWNER_R+aS.OWNER_W+aS.GROUP_R+aS.WORLD_R,RWX_RX=aS.OWNER_R+aS.OWNER_W+aS.OWNER_X+aS.GROUP_R+aS.GROUP_X+aS.WORLD_R+aS.WORLD_X,RW_R__=aS.OWNER_R+aS.OWNER_W+aS.GROUP_R,RW____=aS.OWNER_R+aS.OWNER_W,RWXR__=aS.OWNER_R+aS.OWNER_W+aS.OWNER_X+aS.GROUP_R+aS.WORLD_R,SUID_755=aS.SUID+aS.OWNER_R+aS.OWNER_W+aS.OWNER_X+aS.GROUP_R+aS.GROUP_X+aS.WORLD_R+aS.WORLD_X,RWXRWXRWX=aS.OWNER_R+aS.OWNER_W+aS.OWNER_X+aS.GROUP_R+aS.GROUP_W+aS.GROUP_X+aS.WORLD_R+aS.WORLD_W+aS.WORLD_X}local function aT(v,aU)local a8=a.currentTask;local a9=a8 and a8.euid or a8 and a8.uid or a.uid;local aa=a8 and a8.groups or a.groups or{}if a9==0 then return true end;local af=v.perms;if aU=="x"then if a9==v.owner and d(af,9)then return true end;if v.group then for ag,ah in ipairs(aa)do if ah==v.group and d(af,8)then return true end end end;if d(af,7)then return true end;error("EACCES")end;local aV={r={owner=5,group=3,everyone=1},w={owner=4,group=2,everyone=0},a={owner=4,group=2,everyone=0}}local x=aV[aU]if not x then error("EINVAL")end;if a9==v.owner and d(af,x.owner)then return true end;if v.group then for ag,ah in ipairs(aa)do if ah==v.group and d(af,x.group)then return true end end end;if d(af,x.everyone)then return true end;error("EACCES")end;local function aW(G)G=aI(G)if G~="/"and G:sub(-1)=="/"then G=G:sub(1,-2)end;return G end;local aX={"open","type","list","attributes","fileExists","makeDirectory","remove"}local function aY(W)for ag,n in ipairs(aX)do if type(W[n])~="function"then error("Invalid disk: missing method '"..n.."'")end end end;local aZ=0;local function a_(a8)local b0=0;while a8.fd[b0]do b0=b0+1 end;if b0>=a.config.maxFilesPerTask then error("ENFILE")end;return b0 end;local function b1()if aZ>=a.config.maxOpenFiles-16 then error("ENFILE")end end;local function b2(b3,aU,G,v,b4)return{handle=b3,mode=aU,path=G,meta=v,type=b4,refcount=1}end;function b.newfd(b5)local b0=a_(a.currentTask)a.currentTask.fd[b0]=b5;return b0 end;function b.mount(az,b6)local b7=a.currentTask and(a.currentTask.euid or a.currentTask.uid)or a.uid;if b7~=0 then error("EPERM")end;if not az then error("EINVAL")end;az=aW(az)local b8,G=aJ(az)if not b8:directoryExists(G)then b8:makeDirectory(G)end;if b8:type(az)~="directory"then error("EINVAL")end;local W,R;if type(b6)=="string"then W=a.disks[b6]if not W then error("ENODEV")end;aY(W)R=b6 elseif type(b6)=="table"then aY(b6)W=b6;R=W.address;b.disks[R]=W else error("EINVAL")end;if b.mounts[R]then error("EBUSY")end;for ag,S in pairs(b.mounts)do if S==az then error("EBUSY")end end;b.mounts[R]=az;return true end;function b.umount(az)local b7=a.currentTask and(a.currentTask.euid or a.currentTask.uid)or a.uid;if b7~=0 then error("EPERM")end;if not az then error("EINVAL")end;az=aW(az)for R,S in pairs(b.mounts)do if S==az then if R=="$"then error("EBUSY")end;b.mounts[R]=nil;return true end end;error("EINVAL")end;function b.open(G,aU)b1()local a8=a.currentTask;local b0=a_(a8)local W,U=aJ(G)if not W then error("NODISK")end;if(aU=="w"or aU=="a")and W:isReadOnly()then error("ERDONLY")end;if a.unixSockets[aI(G)]then local v=a.unixSockets[aI(G)].meta;if a.uid~=0 or a.uid~=v.owner then local aa=a8 and a8.groups or a.groups or{}local b9=false;for ag,ah in ipairs(aa)do if ah==v.group then b9=true end end;if not b9 then error("EACCES")end end;a8[b0]=a.unixSockets[aI(G)]return b0 end;local v=aL(G)local ba=(aU=="w"or aU=="a")and not W:fileExists(U)aT(v,aU=="r"and"r"or"w")local b3;if W:type(U)~="directory"then b3=W:open(U,aU)if type(b3)~="table"then error("ENFILE")end end;if ba then local a9=a8 and(a8.euid or a8.uid)or a.uid;local bb=a8 and a8.gid or 0;local bc=aI(G)local aN=bc:match("^(.*)/[^/]+$")or"/"if aN==""then aN="/"end;local n=bc:match("[^/]+$")if n then local ae={etype=0x00,owner=a9,group=bb,perms=b.PERM.RW_R_R,cmeta=""}pcall(aO,aN,n,ae,false)v=ae end end;local bd=b2(b3,aU,G,v,W:type(U))if aU=="r"and d(v.perms,6)then bd.suid_owner=v.owner end;if W.isvirt then bd.isvirt=true end;a8.fd[b0]=bd;if not W.isvirt then aZ=aZ+1 end;return b0 end;function b.read(b0,be)local bf=a.currentTask.fd[b0]if not bf or not bf.handle or not bf.handle.read then error("EBADF")end;return bf.handle.read(be or 1)or""end;function b.write(b0,bg)local bf=a.currentTask.fd[b0]if not bf or not bf.handle or not bf.handle.write then error("EBADF")end;return bf.handle.write(bg)end;function b.pread(b0,be,bh)local bf=a.currentTask.fd[b0]if not bf or not bf.handle or not bf.handle.read or not bf.handle.seek then error("EBADF")end;bf.handle.seek("set",bh)return bf.handle.read(be or 1)or""end;function b.pwrite(b0,bg,bh)local bf=a.currentTask.fd[b0]if not bf or not bf.handle or not bf.handle.write or not bf.handle.seek then error("EBADF")end;bf.handle.seek("set",bh)return bf.handle.write(bg)end;function b.lseek(b0,bh,bi)local bf=a.currentTask.fd[b0]if not bf or not bf.handle or not bf.handle.seek then error("EBADF")end;return bf.handle.seek(bi or"set",bh)end;function b.fsync(b0)local bf=a.currentTask.fd[b0]if not bf or not bf.handle or not bf.handle.flush then error("EBADF")end;if bf.mode~="w"and bf.mode~="a"then error("EBADF")end;bf.handle.flush()end;function b.close(b0)local a8=a.currentTask;local bf=a8.fd[b0]if not bf then error("EBADF")end;if not a8.fd[b0].isvirt then aZ=aZ-1 end;a8.fd[b0]=nil;bf.refcount=bf.refcount-1;if bf.refcount<=0 and bf.handle and bf.handle.close then bf.handle.close()end end;function b.sendfile(bj,bk,be)local bl=a.currentTask.fd[bk]local bm=a.currentTask.fd[bj]if not bl or not bm then error("EBADF")end;if not bl.handle.read or not bm.handle.write then error("EBADF")end;local bn=bl.handle.read(be or 1024)if not bn or bn==""then return end;return bm.handle.write(bn)end;function b.stat(G)local bo;local v;if v.etype==0x02 then bo={size=0,modified=0,created=0}else local W,U=aJ(G)v=aL(G)local Z;Z,bo=pcall(W.attributes,W,U)if not Z then bo={size=0,modified=0,created=0}end end;return{size=bo.size,modified=bo.modified,created=bo.created,owner=v.owner,group=v.group,perms=v.perms,etype=v.etype,xattr=v.cmeta}end;function b.lstat(G)local v=aL(G,true)local bo;if v.etype==0x01 or v.etype==0x02 then bo={size=0,modified=0,created=0}else local W,U=aJ(G,true)local Z,bp=pcall(W.attributes,W,U)bo=Z and bp or{size=0,modified=0,created=0}end;return{size=bo.size,modified=bo.modified,created=bo.created,owner=v.owner,group=v.group,perms=v.perms,etype=v.etype,xattr=v.etype==0x01 and""or v.cmeta,symlink_target=v.etype==0x01 and v.cmeta or nil}end;function b.fstat(b0)local bf=a.currentTask.fd[b0]if not bf then error("EBADF")end;local bo;if bf.meta.etype==0x02 then bo={size=0,modified=0,created=0}else local W,U=aJ(bf.path,true)local Z,bp=pcall(W.attributes,W,U)bo=Z and bp or{size=0,modified=0,created=0}end;return{size=bo.size,modified=bo.modified,created=bo.created,owner=bf.meta.owner,group=bf.meta.group,perms=bf.meta.perms,etype=bf.meta.etype,xattr=bf.meta.cmeta}end;function b.listdir(G)local W,U=aJ(G)local v=aL(G)aT(v,"r")if W:type(U)~="directory"then error("ENOTDIR")end;local bq=W:list(U)local br={}local w={}for ag,bs in ipairs(bq)do if bs~=".meta"then br[bs]=true;table.insert(w,bs)end end;for bt,bs in pairs(a.unixSockets)do local j=aI(G)if bt:match("^(.*)/[^/]+$")==j then br[bs.name]=true;table.insert(w,bs.name)end end;local S;if U=="/"then S=".meta"else S=U:gsub("^/+","").."/.meta"end;local bu,bv=pcall(function()return W:open(S,"r")end)if bu and bv then local h=bv.read(65535)if bv.close then bv.close()end;local a3=g(h)for n,ae in pairs(a3)do if ae.etype==0x01 and not br[n]then table.insert(w,n)end end end;return w end;function b.mkdir(G)local bc=aI(G)local aN=bc:match("^(.*)/[^/]+$")or"/"if aN==""then aN="/"end;local bw=aL(aN)aT(bw,"w")local W,U=aJ(G)if W:isReadOnly()then error("ERDONLY")end;W:makeDirectory(U)local a8=a.currentTask;local a9=a8 and(a8.euid or a8.uid)or a.uid;local bb=a8 and a8.gid or 0;local n=bc:match("[^/]+$")if n then local ae={etype=0x00,owner=a9,group=bb,perms=b.PERM.RWX_RX,cmeta=""}pcall(aO,aN,n,ae,false)end end;function b.remove(G)local bc=a5(G,true)local aN=bc:match("^(.*)/[^/]+$")or"/"if aN==""then aN="/"end;local bw=aL(aN)aT(bw,"w")local v=aL(G,true)if a.unixSockets and a.unixSockets[aI(G)]then if a.uid~=0 then if a.unixSockets[aI(G)].meta.owner~=a.uid then error("EACCES")end end;a.unixSockets[aI(G)]=nil end;if v.etype==0x01 then local bc=a5(G,true)local aN=bc:match("^(.*)/[^/]+$")or"/"if aN==""then aN="/"end;local n=bc:match("[^/]+$")local W,X=N(aN)if W:isReadOnly()then error("ERDONLY")end;local S;if X=="/"then S=".meta"else S=X:gsub("^/+","").."/.meta"end;local aQ,aR=pcall(function()return W:open(S,"r")end)local a3={}if aQ and aR then local h=aR.read(65535)if aR.close then aR.close()end;a3=g(h)end;a3[n]=nil;local bx=W:open(S,"w")bx.write(u(a3))if bx.close then bx.close()end else local W,U=aJ(G)if W:isReadOnly()then error("ERDONLY")end;W:remove(U)end end;function b.symlink(az,by)if type(az)~="string"or type(by)~="string"then error("EINVAL")end;local bc=aI(by)local aN=bc:match("^(.*)/[^/]+$")or"/"local W=N(by)if W:isReadOnly()then error("ERDONLY")end;if aN==""then aN="/"end;local n=bc:match("[^/]+$")if not n then error("EINVAL")end;local bw=aL(aN)aT(bw,"w")local a8=a.currentTask;local a9=a8 and(a8.euid or a8.uid)or a.uid;local bb=a8 and a8.gid or a.gid or 0;local ae={etype=0x01,owner=a9,group=bb,perms=b.PERM.RWXRWXRWX,cmeta=az}local Z,bz=pcall(aO,aN,n,ae,false)if not Z then error(bz)end end;function b.readlink(G)local v=aL(G,true)if v.etype~=0x01 then error("EINVAL")end;return v.cmeta end;function b.access(G,aU)local v;if a.unixSockets[aI(G)]then v=a.unixSockets[aI(G)].meta else v=aL(G)end;for ak=1,#aU do aT(v,aU:sub(ak,ak))end;return true end;local function bA(G,bB,a6)local aK=a5(G,a6)local bc=aK;local aN=bc:match("^(.*)/[^/]+$")or"/"local W=N(G)if W:isReadOnly()then error("ERDONLY")end;if aN==""then aN="/"end;local n=bc:match("[^/]+$")if not n then error("EINVAL")end;local W,bC=N(aN)local S;if bC=="/"then S=".meta"else S=bC:gsub("^/+","").."/.meta"end;local aP={}local bD,bE=pcall(function()return W:open(S,"r")end)if bD and bE then local h=bE.read(65535)if bE.close then bE.close()end;aP=g(h)end;local ae=aP[n]or{etype=0,owner=0,group=0,perms=63,cmeta=""}bB(ae)aP[n]=ae;local _=W:open(S,"w")_.write(u(aP))if _.close then _.close()end end;function b.chmod(G,r)if a.unixSockets[aI(G)]then error("EINVAL")end;local W=N(G)if W:isReadOnly()then error("ERDONLY")end;local v=aL(G)local a9=a.currentTask and(a.currentTask.euid or a.currentTask.uid)or a.uid;if a9~=0 and a9~=v.owner then error("EACCES")end;bA(G,function(bF)bF.perms=r end)end;function b.fchmod(b0,r)local bf=a.currentTask.fd[b0]if not bf then error("EBADF")end;if bf.etype==0x02 then error("EINVAL")end;b.chmod(bf.path,r)end;function b.chown(G,bG,ah)if a.unixSockets[aI(G)]then error("EINVAL")end;local W=N(G)if W:isReadOnly()then error("ERDONLY")end;local b7=a.currentTask and(a.currentTask.euid or a.currentTask.uid)or a.uid;if b7~=0 then error("EPERM")end;bA(G,function(bF)bF.owner=bG;bF.group=ah end)end;function b.fchown(b0,bG,ah)local bf=a.currentTask.fd[b0]if not bf then error("EBADF")end;if bf.etype==0x02 then error("EINVAL")end;b.chown(bf.path,bG,ah)end;function b.exists(G)local v=aL(G,true)if v.etype==0x01 then return true end;local Z,W,U=pcall(aJ,G)if not Z then return false end;if W:type(U)then return true else return false end end;function b.type(G)local v=aL(G,true)if v.etype==0x01 then return"symlink"end;if a.unixSockets[aI(G)]then return"socket"end;local Z,W,U=pcall(aJ,G)if not Z then return nil end;return W:type(U)end;function b.getcwd()return a.currentTask.cwd end;function b.chdir(G)if b.type(G)~="directory"then error("ENOTDIR")end;a.currentTask.cwd=aI(G)end;function b.chroot(G)local a9=a.currentTask and(a.currentTask.euid or a.currentTask.uid)or a.uid;if a9~=0 then error("EPERM")end;if b.type(G)~="directory"then error("ENOTDIR")end;local bc=aI(G)a.currentTask.root=bc;a.currentTask.cwd=bc end;function b.dup(bH)local a8=a.currentTask;local bf=a8.fd[bH]if not bf then error("EBADF")end;b1()local bI=a_(a8)bf.refcount=bf.refcount+1;a8.fd[bI]=bf;aZ=aZ+1;return bI end;function b.dup2(bH,bI)local a8=a.currentTask;local bf=a8.fd[bH]if not bf then error("EBADF")end;if bI<0 or bI>=a.config.maxFilesPerTask then error("EBADF")end;if bH==bI then return bI end;if a8.fd[bI]then b.close(bI)end;b1()bf.refcount=bf.refcount+1;a8.fd[bI]=bf;aZ=aZ+1;return bI end;function b.devctl(b0,bJ,...)if not a.currentTask.fd[b0]then error("EBADF")end;if not a.currentTask.fd[b0].handle[bJ]then error("EINVAL")end;return a.currentTask.fd[b0].handle[bJ](...)end;b.resolveMount=N;local bK=a.syscalls;bK["open"]=b.open;bK["close"]=b.close;bK["read"]=b.read;bK["write"]=b.write;bK["pread"]=b.pread;bK["pwrite"]=b.pwrite;bK["lseek"]=b.lseek;bK["fsync"]=b.fsync;bK["sendfile"]=b.sendfile;bK["stat"]=b.stat;bK["lstat"]=b.lstat;bK["fstat"]=b.fstat;bK["mkdir"]=b.mkdir;bK["remove"]=b.remove;bK["listdir"]=b.listdir;bK["chmod"]=b.chmod;bK["fchmod"]=b.fchmod;bK["chown"]=b.chown;bK["fchown"]=b.fchown;bK["exists"]=b.exists;bK["type"]=b.type;bK["mount"]=b.mount;bK["umount"]=b.umount;bK["getcwd"]=b.getcwd;bK["chdir"]=b.chdir;bK["chroot"]=b.chroot;bK["dup"]=b.dup;bK["dup2"]=b.dup2;bK["devctl"]=b.devctl;bK["symlink"]=b.symlink;bK["readlink"]=b.readlink;bK["access"]=b.access;bK["fget_suid"]=function(b0)local bd=a.currentTask and a.currentTask.fd[b0]return bd and bd.suid_owner or nil end;a.log("VFS module loaded")