feat: add durable addressed registry publication

This commit is contained in:
2026-08-11 13:39:38 +02:00
parent 475e94b662
commit ee87a59e1f
24 changed files with 380 additions and 55 deletions
@@ -22,8 +22,8 @@ static bool str(napi_env env,napi_value v,std::string& out){ size_t n; if(napi_g
static napi_value statObj(napi_env env,const struct stat& st){ napi_value o,n; napi_create_object(env,&o); napi_create_bigint_uint64(env,(uint64_t)st.st_dev,&n); napi_set_named_property(env,o,"device",n); napi_create_bigint_uint64(env,(uint64_t)st.st_ino,&n); napi_set_named_property(env,o,"inode",n); napi_create_uint32(env,(uint32_t)st.st_mode,&n); napi_set_named_property(env,o,"mode",n); napi_create_uint32(env,(uint32_t)st.st_uid,&n); napi_set_named_property(env,o,"uid",n); napi_create_uint32(env,(uint32_t)st.st_gid,&n); napi_set_named_property(env,o,"gid",n); napi_create_bigint_uint64(env,(uint64_t)st.st_nlink,&n); napi_set_named_property(env,o,"nlink",n); return o; }
static napi_value result(napi_env env,int fd,bool dir,const struct stat&st){ auto*h=new Handle{MAGIC,fd,dir,false}; handles.insert(h); napi_value e,o,s; napi_create_external(env,h,finalize,nullptr,&e); napi_create_object(env,&o); napi_set_named_property(env,o,"handle",e); s=statObj(env,st); napi_set_named_property(env,o,"openedStat",s); return o; }
static napi_value openatFn(napi_env env,napi_callback_info info){ size_t argc=1; napi_value a[1]; if(napi_get_cb_info(env,info,&argc,a,nullptr,nullptr)!=napi_ok||argc!=1)return fail(env,"openat",EINVAL); napi_value pv,nv,kv,mv; if(napi_get_named_property(env,a[0],"parent",&pv)!=napi_ok||napi_get_named_property(env,a[0],"name",&nv)!=napi_ok||napi_get_named_property(env,a[0],"kind",&kv)!=napi_ok||napi_get_named_property(env,a[0],"createMode",&mv)!=napi_ok)return fail(env,"openat",EINVAL); std::string name,kind; if(!str(env,nv,name)||!str(env,kv,kind))return fail(env,"openat",EINVAL); int32_t mode; if(napi_get_value_int32(env,mv,&mode)!=napi_ok)return fail(env,"openat",EINVAL); bool root=name=="/"; if(!root&&(name.empty()||name.size()>255||name=="."||name==".."||name.find('/')!=std::string::npos||name.find('\0')!=std::string::npos))return fail(env,"openat",EINVAL); Handle*ph=nullptr; if(root){if(kind!="directory"||mode!=0)return fail(env,"openat",EINVAL);} else if(!getHandle(env,pv,&ph)||!ph->directory)return fail(env,"openat",EBADF); int fd; if(root)fd=::open("/",O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW); else if(kind=="directory"&&mode==0)fd=::openat(ph->fd,name.c_str(),O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW); else if(kind=="regular_lock"&&mode==0600)fd=::openat(ph->fd,name.c_str(),O_RDWR|O_CREAT|O_CLOEXEC|O_NOFOLLOW,0600); else return fail(env,"openat",EINVAL); if(fd<0)return fail(env,"openat",errno); struct stat st; if(::fstat(fd,&st)<0){int e=errno;::close(fd);return fail(env,"fstat",e);} if(kind=="directory"&&!S_ISDIR(st.st_mode)){::close(fd);return fail(env,"openat",ENOTDIR);} if(kind=="regular_lock"&&(!S_ISREG(st.st_mode)||(st.st_mode&0777)!=0600)){::close(fd);return fail(env,"openat",EPERM);} return result(env,fd,kind=="directory",st); }
static napi_value mkdiratFn(napi_env env,napi_callback_info info){size_t n=3; napi_value a[3]; napi_get_cb_info(env,info,&n,a,nullptr,nullptr);Handle*h;std::string s;int32_t m;if(n!=3||!getHandle(env,a[0],&h)||!h->directory||!str(env,a[1],s)||napi_get_value_int32(env,a[2],&m)!=napi_ok||m!=0700)return fail(env,"mkdirat",EINVAL);if(s.empty()||s.size()>255||s=="."||s==".."||s.find('/')!=std::string::npos)return fail(env,"mkdirat",EINVAL);if(::mkdirat(h->fd,s.c_str(),0700)<0)return fail(env,"mkdirat",errno);return nullptr;}
static napi_value fstatatFn(napi_env env,napi_callback_info info){size_t n=2;napi_value a[2];napi_get_cb_info(env,info,&n,a,nullptr,nullptr);Handle*h;std::string s;if(n!=2||!getHandle(env,a[0],&h)||!h->directory||!str(env,a[1],s)||s.empty()||s.size()>255||s=="."||s==".."||s.find('/')!=std::string::npos)return fail(env,"fstatat",EINVAL);struct stat st;if(::fstatat(h->fd,s.c_str(),&st,AT_SYMLINK_NOFOLLOW)<0)return fail(env,"fstatat",errno);return statObj(env,st);}
static napi_value mkdiratFn(napi_env env,napi_callback_info info){size_t n=3; napi_value a[3]; napi_get_cb_info(env,info,&n,a,nullptr,nullptr);Handle*h;std::string s;int32_t m;if(n!=3||!getHandle(env,a[0],&h)||!h->directory||!str(env,a[1],s)||napi_get_value_int32(env,a[2],&m)!=napi_ok||m!=0700)return fail(env,"mkdirat",EINVAL);if(s.empty()||s.size()>255||s=="."||s==".."||s.find('/')!=std::string::npos||s.find('\0')!=std::string::npos)return fail(env,"mkdirat",EINVAL);if(::mkdirat(h->fd,s.c_str(),0700)<0)return fail(env,"mkdirat",errno);return nullptr;}
static napi_value fstatatFn(napi_env env,napi_callback_info info){size_t n=2;napi_value a[2];napi_get_cb_info(env,info,&n,a,nullptr,nullptr);Handle*h;std::string s;if(n!=2||!getHandle(env,a[0],&h)||!h->directory||!str(env,a[1],s)||s.empty()||s.size()>255||s=="."||s==".."||s.find('/')!=std::string::npos||s.find('\0')!=std::string::npos)return fail(env,"fstatat",EINVAL);struct stat st;if(::fstatat(h->fd,s.c_str(),&st,AT_SYMLINK_NOFOLLOW)<0)return fail(env,"fstatat",errno);return statObj(env,st);}
static napi_value fsyncFn(napi_env env,napi_callback_info info){size_t n=1;napi_value a[1];napi_get_cb_info(env,info,&n,a,nullptr,nullptr);Handle*h;if(n!=1||!getHandle(env,a[0],&h)||!h->directory)return fail(env,"fsync",EBADF);if(::fsync(h->fd)<0)return fail(env,"fsync",errno);return nullptr;}
static napi_value closeFn(napi_env env,napi_callback_info info){size_t n=1;napi_value a[1];napi_get_cb_info(env,info,&n,a,nullptr,nullptr);Handle*h;if(n!=1||!getHandle(env,a[0],&h))return fail(env,"close",EBADF);h->closed=true;int rc=::close(h->fd);if(rc<0)return fail(env,"close",errno);return nullptr;}
static napi_value fdFn(napi_env env,napi_callback_info info){size_t n=1;napi_value a[1];napi_get_cb_info(env,info,&n,a,nullptr,nullptr);Handle*h;if(n!=1||!getHandle(env,a[0],&h))return fail(env,"fcntl",EBADF);napi_value x;napi_create_int32(env,h->fd,&x);return x;}