+/**
+ * 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
+}
+