nx_fs_create_lib.nx source
↩ module page · 32 lines · 1641 B
1// Exclusive host artifact creation: sync complete bytes before RENAME_NOREPLACE.
2// Scratch derives from the actual path and PID; OS path errors remain OS errors.
3import "nx_fsops_lib.nx"
4const FXC_OPEN_EXCLUSIVE: i64 = 0xc1
5const FXC_RENAMEAT2_X86: i64 = 316
6const FXC_RENAME_NOREPLACE: i64 = 1
7const FXC_EXISTS: i64 = 0 - 17
8const FXC_IO: i64 = 0 - 3
9func fxc_create(path:*u8,body:*u8,n:i64)->i64{
10 if (path as i64)==0||n<0{return FXC_IO}
11 if n>0&&(body as i64)==0{return FXC_IO}
12 if fsx_write_denied(path)==1{return 0-2}
13 let plen:i64=vw_slen(path);let suffix:*u8=".nxc";let sn:i64=vw_slen(suffix)
14 let pid:i64=osp_selfpid();var digits:i64=1;var p:i64=pid;while p>=10{digits=digits+1;p=p/10}
15 let extra:i64=sn+digits+1
16 if plen>9223372036854775807-extra{return FXC_IO}
17 let size:i64=plen+extra;let tmp:*u8=sys_mmap_try(size);if (tmp as i64)==0{return 0-12}
18 var i:i64=0;while i<plen{tmp[i]=path[i];i=i+1};var j:i64=0;while j<sn{tmp[i]=suffix[j];i=i+1;j=j+1}
19 i=nxi_buf(tmp,i,pid);tmp[i]=0 as u8
20 let fd:i64=__syscall(SYS_OPENAT,AT_FDCWD,tmp,FXC_OPEN_EXCLUSIVE,MODE_0644,0,0)
21 var result:i64=fd
22 if fd==FXC_EXISTS{result=0-16} // EBUSY: own temporary name exists; destination is unexamined.
23 if fd>=0{
24 var off:i64=0;var failed:i64=0
25 while off<n{let wrote:i64=sys_write(fd,(body as i64+off) as *u8,n-off);if wrote<=0{failed=1;result=FXC_IO;break};off=off+wrote}
26 if failed==0{result=sys_fsync(fd);if result<0{failed=1}}
27 sys_close(fd)
28 if failed==0{result=__syscall(FXC_RENAMEAT2_X86,AT_FDCWD,tmp,AT_FDCWD,path,FXC_RENAME_NOREPLACE,0)}
29 if result!=0{sys_unlinkat(tmp)}else{result=n}
30 }
31 sys_munmap_direct(tmp,size);return result
32}