@ -369,6 +369,43 @@ stat(const char *path, struct stat *st)
return fstatat ( rel . dirfd , rel . relative_path , st , AT_SYMLINK_NOFOLLOW ) ;
}
/**
* Capability - safe wrapper around the ` unlink ( 2 ) ` system call .
*
* ` unlink ( 2 ) ` accepts a path argument that can reference the global filesystem
* namespace . This is not a capability - safe operation , so this wrapper function
* attempts to look up the path ( or a prefix of it ) within the current global
* po_map and converts the call into the capability - safe ` unlinkat ( 2 ) ` if
* possible . If the current po_map does not contain the sought - after path ,
* this wrapper will call ` unlinkat ( AT_FDCWD , original_path , 0 ) which is
* the same as the unwrapped ` unlink ( 2 ) ` call ( i . e . , will fail with ` ECAPMODE ` ) .
*/
int
unlink ( const char * path )
{
# ifdef __wasilibc_unmodified_upstream
struct po_relpath rel = find_relative ( path , NULL ) ;
# else
struct po_relpath rel_pathname = find_relative ( path , __WASI_RIGHT_PATH_UNLINK_FILE , 0 ) ;
// If we can't find a preopened directory handle to open this file with,
// indicate that the program lacks the capabilities.
if ( rel_pathname . dirfd = = - 1 ) {
errno = ENOTCAPABLE ;
return - 1 ;
}
# endif
# ifdef __wasilibc_unmodified_upstream
return unlinkat ( rel . dirfd , rel . relative_path , 0 ) ;
# else
// `unlinkat` ends up importing `__wasi_path_remove_directory` even
// though we're not passing `AT_REMOVEDIR` here. So instead, use a
// specialized function which just imports `__wasi_path_unlink_file`.
return __wasilibc_unlinkat ( rel_pathname . dirfd , rel_pathname . relative_path ) ;
# endif
}
/*
* Wrappers around other libc calls :
*/
@ -397,21 +434,6 @@ dlopen(const char *path, int mode)
# else
# include <dirent.h>
int
unlink ( const char * pathname )
{
struct po_relpath rel_pathname = find_relative ( pathname , __WASI_RIGHT_PATH_UNLINK_FILE , 0 ) ;
// If we can't find a preopened directory handle to open this file with,
// indicate that the program lacks the capabilities.
if ( rel_pathname . dirfd = = - 1 ) {
errno = ENOTCAPABLE ;
return - 1 ;
}
return __wasilibc_unlinkat ( rel_pathname . dirfd , rel_pathname . relative_path ) ;
}
int
rmdir ( const char * pathname )
{