Compare commits
No commits in common. "419604a4d29a4f705fd308c4d435e94b64576de1" and "55c362eecf94f3da7c0e0535289373557e590f91" have entirely different histories.
419604a4d2
...
55c362eecf
@ -12,7 +12,7 @@ Result<u64> sys_poll(Registers*, SyscallArgs args)
|
||||
nfds_t nfds = (nfds_t)args[1];
|
||||
int timeout = (int)args[2];
|
||||
|
||||
struct pollfd* kfds = (struct pollfd*)TRY(malloc_impl(nfds * sizeof(pollfd), false, false));
|
||||
struct pollfd* kfds = (struct pollfd*)TRY(malloc_impl(nfds * sizeof(pollfd)));
|
||||
auto guard = make_scope_guard([kfds] { free_impl(kfds); });
|
||||
|
||||
if (!MemoryManager::copy_from_user(fds, kfds, nfds * sizeof(pollfd))) return err(EFAULT);
|
||||
|
@ -117,7 +117,9 @@ extern "C"
|
||||
|
||||
raise(SIGABRT);
|
||||
|
||||
__builtin_trap();
|
||||
// There is no way we could end up here, unless there is some sort of race condition or the kernel decided to
|
||||
// change the default action for SIGABRT because it's a Tuesday.
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
__noreturn void _Exit(int status)
|
||||
|
@ -24,7 +24,7 @@
|
||||
*/
|
||||
template <typename T, class... Args> [[nodiscard]] Result<T*> make(Args... args)
|
||||
{
|
||||
T* const result = (T*)TRY(malloc_impl(sizeof(T), false, false));
|
||||
T* const result = (T*)TRY(malloc_impl(sizeof(T)));
|
||||
new (result) T(args...);
|
||||
return result;
|
||||
}
|
||||
|
@ -1,19 +1,7 @@
|
||||
/**
|
||||
* @file Buffer.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief A managed wrapper around a resizable buffer of arbitrary memory.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <luna/Result.h>
|
||||
#include <luna/Types.h>
|
||||
|
||||
/**
|
||||
* @brief A managed wrapper around a resizable buffer of arbitrary memory.
|
||||
*/
|
||||
class Buffer
|
||||
{
|
||||
public:
|
||||
@ -23,135 +11,45 @@ class Buffer
|
||||
Buffer(Buffer&& other);
|
||||
Buffer(const Buffer& other) = delete; // For now.
|
||||
|
||||
/**
|
||||
* @brief Create a Buffer object, allocating a specific amount of memory for it.
|
||||
*
|
||||
* @param size The number of bytes to allocate.
|
||||
* @return Result<Buffer> An error, or the newly created buffer.
|
||||
*/
|
||||
static Result<Buffer> create_sized(usize size);
|
||||
|
||||
/**
|
||||
* @brief Resize the buffer.
|
||||
*
|
||||
* The existing data is kept, unless the new size is smaller than the old size, in which case only the first
|
||||
* new_size bytes are kept.
|
||||
*
|
||||
* @param new_size The new size of the buffer, in bytes.
|
||||
* @return Result<void> Whether the operation succeeded.
|
||||
*/
|
||||
Result<void> try_resize(usize new_size);
|
||||
|
||||
/**
|
||||
* @brief Expand the buffer and return a pointer to the beginning of this new expanded area.
|
||||
*
|
||||
* @param size The amount of bytes to expand the buffer by.
|
||||
* @return Result<u8*> An error, or a pointer to the new area of the buffer.
|
||||
*/
|
||||
Result<u8*> slice_at_end(usize size);
|
||||
|
||||
/**
|
||||
* @brief Return a pointer to an area of the buffer, expanding it if necessary.
|
||||
*
|
||||
* @param offset The offset inside the buffer to start at.
|
||||
* @param size The amount of bytes to reserve.
|
||||
* @return Result<u8*> An error, or a pointer to the requested area.
|
||||
*/
|
||||
Result<u8*> slice(usize offset, usize size);
|
||||
|
||||
/**
|
||||
* @brief Add data to the end of the buffer.
|
||||
*
|
||||
* @param data A pointer to the data to add.
|
||||
* @param size The amount of bytes to add.
|
||||
* @return Result<void> Whether the operation succeeded.
|
||||
*/
|
||||
Result<void> append_data(const u8* data, usize size);
|
||||
|
||||
/**
|
||||
* @brief Remove data from the beginning of the buffer and return it.
|
||||
*
|
||||
* @param data A pointer to store the removed data in.
|
||||
* @param size The amount of bytes to remove.
|
||||
* @return usize The amount of bytes actually removed (may be less if the buffer was smaller than the requested
|
||||
* size).
|
||||
*/
|
||||
usize dequeue_data(u8* data, usize size);
|
||||
|
||||
/**
|
||||
* @brief Return a pointer to the data contained in the buffer.
|
||||
*
|
||||
* This pointer may be invalid after the buffer is resized.
|
||||
*
|
||||
* @return u8* The contained data.
|
||||
*/
|
||||
u8* data()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return a pointer to the data contained in the buffer.
|
||||
*
|
||||
* This pointer may be invalid after the buffer is resized.
|
||||
*
|
||||
* @return const u8* The contained data.
|
||||
*/
|
||||
const u8* data() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return a pointer to the data contained in the buffer, moving the data out of the buffer.
|
||||
*
|
||||
* This call will empty the buffer, making it the caller's responsibility to manage the data, including freeing it
|
||||
* when no longer used.
|
||||
*
|
||||
* @return u8* The released data.
|
||||
*/
|
||||
u8* release_data();
|
||||
|
||||
/**
|
||||
* @brief Return a pointer to the end of the data contained in the buffer.
|
||||
*
|
||||
* This pointer points past the data; as such, dereferencing it directly is undefined behavior.
|
||||
*
|
||||
* @return u8* The end of the data.
|
||||
*/
|
||||
u8* end()
|
||||
{
|
||||
return m_data + m_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return a pointer to the end of the data contained in the buffer.
|
||||
*
|
||||
* This pointer points past the data; as such, dereferencing it directly is undefined behavior.
|
||||
*
|
||||
* @return const u8* The end of the data.
|
||||
*/
|
||||
const u8* end() const
|
||||
{
|
||||
return m_data + m_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the size of the buffer in bytes.
|
||||
*
|
||||
* @return usize The buffer's size.
|
||||
*/
|
||||
usize size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether the buffer is empty.
|
||||
*
|
||||
* @return true The buffer is empty.
|
||||
* @return false The buffer is not empty.
|
||||
*/
|
||||
bool is_empty() const
|
||||
{
|
||||
return m_size == 0;
|
||||
|
@ -46,7 +46,7 @@ template <typename T, usize Size> class CircularQueue
|
||||
* @brief Push a value onto the queue.
|
||||
*
|
||||
* @param value The value to push.
|
||||
* @return true The operation succeeded.
|
||||
* @return true The operation succeded.
|
||||
* @return false The queue was full or someone else was trying to push a value at the same time.
|
||||
*/
|
||||
bool try_push(const T& value)
|
||||
@ -71,7 +71,7 @@ template <typename T, usize Size> class CircularQueue
|
||||
* @brief Pop a value from the queue.
|
||||
*
|
||||
* @param value The variable to store the value into.
|
||||
* @return true The operation succeeded.
|
||||
* @return true The operation succeded.
|
||||
* @return false The queue was empty or someone else was trying to pop a value at the same time.
|
||||
*/
|
||||
bool try_pop(T& value)
|
||||
@ -136,7 +136,7 @@ template <typename T> class DynamicCircularQueue
|
||||
* be called once to set the initial size of the queue and that's it.
|
||||
*
|
||||
* @param size The amount of elements to make space for.
|
||||
* @return Result<void> Whether the operation succeeded.
|
||||
* @return Result<void> Whether the operation succeded.
|
||||
*/
|
||||
Result<void> set_size(usize size)
|
||||
{
|
||||
@ -150,7 +150,7 @@ template <typename T> class DynamicCircularQueue
|
||||
* @brief Push a value onto the queue.
|
||||
*
|
||||
* @param value The value to push.
|
||||
* @return true The operation succeeded.
|
||||
* @return true The operation succeded.
|
||||
* @return false The queue was full or someone else was trying to push a value at the same time.
|
||||
*/
|
||||
bool try_push(const T& value)
|
||||
@ -176,7 +176,7 @@ template <typename T> class DynamicCircularQueue
|
||||
* @brief Pop a value from the queue.
|
||||
*
|
||||
* @param value The variable to store the value into.
|
||||
* @return true The operation succeeded.
|
||||
* @return true The operation succeded.
|
||||
* @return false The queue was empty or someone else was trying to pop a value at the same time.
|
||||
*/
|
||||
bool try_pop(T& value)
|
||||
|
@ -1,61 +1,16 @@
|
||||
/**
|
||||
* @file Hash.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief Common hash functions for use in hash tables.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <luna/CString.h>
|
||||
#include <luna/Types.h>
|
||||
|
||||
/**
|
||||
* @brief Calculate the hash of an area of memory.
|
||||
*
|
||||
* @param mem A pointer to the memory to hash.
|
||||
* @param size The amount of bytes to use.
|
||||
* @param salt A randomly generated salt to vary the output and avoid hash table attacks.
|
||||
* @return u64 The calculated hash.
|
||||
*/
|
||||
u64 hash_memory(const void* mem, usize size, u64 salt);
|
||||
|
||||
/**
|
||||
* @brief Calculate the hash of a value.
|
||||
*
|
||||
* The default implementation simply hashes the raw memory representation of the value. This may not be suitable for
|
||||
* some types, so those can define a template specialization of this function to do their own hashing.
|
||||
*
|
||||
* @tparam T The type of the value to hash.
|
||||
* @param value The value to hash.
|
||||
* @param salt A randomly generated salt to vary the output and avoid hash table attacks.
|
||||
* @return u64 The calculated hash.
|
||||
*/
|
||||
template <typename T> u64 hash(const T& value, u64 salt)
|
||||
{
|
||||
return hash_memory(&value, sizeof(value), salt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Template specialization of hash() for C-strings.
|
||||
*
|
||||
* This function hashes the actual string instead of the pointer value.
|
||||
*
|
||||
* @param value The C-string to hash.
|
||||
* @param salt A randomly generated salt to vary the output and avoid hash table attacks.
|
||||
* @return u64 The calculated hash.
|
||||
*/
|
||||
template <> u64 hash(const char* const& value, u64 salt);
|
||||
|
||||
/**
|
||||
* @brief Swap two values of the same type.
|
||||
*
|
||||
* FIXME: This function should be moved to a more appropriate header.
|
||||
*
|
||||
* @tparam T The type of the values to swap.
|
||||
* @param a The first value to swap.
|
||||
* @param b The second value to swap.
|
||||
*/
|
||||
template <typename T> static void swap(T* a, T* b)
|
||||
{
|
||||
char* x = (char*)a;
|
||||
|
@ -1,94 +1,35 @@
|
||||
/**
|
||||
* @file HashMap.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief Map between keys and values with best-case constant time lookup.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <luna/HashTable.h>
|
||||
|
||||
/**
|
||||
* @brief Internal representation of a key-value pair in a HashMap.
|
||||
*
|
||||
* @tparam K The key type.
|
||||
* @tparam V The value type.
|
||||
*/
|
||||
template <typename K, typename V> struct HashPair
|
||||
{
|
||||
K key;
|
||||
Option<V> value;
|
||||
|
||||
/**
|
||||
* @brief Compare two HashPair objects's keys.
|
||||
*
|
||||
* @param other The HashPair to compare against.
|
||||
* @return true The keys match.
|
||||
* @return false The keys do not match.
|
||||
*/
|
||||
bool operator==(const HashPair<K, V>& other) const
|
||||
{
|
||||
return key == other.key;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Template specialization of hash() for HashPair objects.
|
||||
*
|
||||
* This function hashes only the key, ignoring the value.
|
||||
*
|
||||
* @tparam K The key type.
|
||||
* @tparam V The value type.
|
||||
* @param value The HashPair to hash.
|
||||
* @param salt A randomly generated salt to vary the output and avoid hash table attacks.
|
||||
* @return u64 The calculated hash.
|
||||
*/
|
||||
template <typename K, typename V> u64 hash(const HashPair<K, V>& value, u64 salt)
|
||||
{
|
||||
return hash(value.key, salt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A map between keys and values with best-case constant time lookup.
|
||||
*
|
||||
* @tparam K The key type.
|
||||
* @tparam V The value type.
|
||||
*/
|
||||
template <typename K, typename V> struct HashMap
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Try to insert a key-value pair into the HashMap.
|
||||
*
|
||||
* @param key The key to use.
|
||||
* @param value The value to use.
|
||||
* @return Result<bool> An error, true if the insertion succeeded, or false if the key already existed.
|
||||
*/
|
||||
Result<bool> try_set(const K& key, V&& value)
|
||||
{
|
||||
return m_table.try_set(HashPair<K, V> { key, move(value) });
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Try to insert a key-value pair into the HashMap.
|
||||
*
|
||||
* @param key The key to use.
|
||||
* @param value The value to use.
|
||||
* @return Result<bool> An error, true if the insertion succeeded, or false if the key already existed.
|
||||
*/
|
||||
Result<bool> try_set(const K& key, const V& value)
|
||||
{
|
||||
return m_table.try_set(HashPair<K, V> { key, value });
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the associated value for a key.
|
||||
*
|
||||
* @param key The key to use.
|
||||
* @return Option<V> The associated value, or an empty option if the key did not exist.
|
||||
*/
|
||||
Option<V> try_get(const K& key)
|
||||
{
|
||||
auto* p = m_table.try_find(HashPair<K, V> { key, {} });
|
||||
@ -96,14 +37,6 @@ template <typename K, typename V> struct HashMap
|
||||
return p->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a pointer to the associated value for a key inside the HashMap.
|
||||
*
|
||||
* This pointer should always be checked before usage.
|
||||
*
|
||||
* @param key The key to use.
|
||||
* @return V* A pointer to the associated value, or nullptr if the key did not exist.
|
||||
*/
|
||||
V* try_get_ref(const K& key)
|
||||
{
|
||||
auto* p = m_table.try_find(HashPair<K, V> { key, {} });
|
||||
@ -111,44 +44,21 @@ template <typename K, typename V> struct HashMap
|
||||
return p->value.value_ptr();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove a key-value pair from this HashMap.
|
||||
*
|
||||
* @param key The key to use.
|
||||
* @return true The pair was successfully removed.
|
||||
* @return false The key did not exist.
|
||||
*/
|
||||
bool try_remove(const K& key)
|
||||
{
|
||||
return m_table.try_remove(HashPair<K, V> { key, {} });
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the number of key-value pairs that can currently fit in the HashMap.
|
||||
*
|
||||
* The number of actual entries will always be smaller than this (unless it is 0), since the HashMap grows before
|
||||
* the number of entries reaches the capacity.
|
||||
*
|
||||
* @return usize The current capacity.
|
||||
*/
|
||||
usize capacity() const
|
||||
{
|
||||
return m_table.capacity();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the number of key-value pairs currently contained in this HashMap.
|
||||
*
|
||||
* @return usize The number of pairs contained.
|
||||
*/
|
||||
usize size() const
|
||||
{
|
||||
return m_table.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the HashMap.
|
||||
*/
|
||||
void clear()
|
||||
{
|
||||
m_table.clear();
|
||||
|
@ -1,50 +1,23 @@
|
||||
/**
|
||||
* @file HashTable.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief Table of values with best-case constant time lookup.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <luna/Hash.h>
|
||||
#include <luna/Heap.h>
|
||||
#include <luna/Option.h>
|
||||
|
||||
/**
|
||||
* @brief A table of values with best-case constant time lookup.
|
||||
*
|
||||
* @tparam T The type of values to store.
|
||||
*/
|
||||
template <typename T> class HashTable
|
||||
{
|
||||
static constexpr usize GROW_RATE = 2;
|
||||
static constexpr usize GROW_FACTOR = 2;
|
||||
static constexpr usize INITIAL_CAPACITY = 32;
|
||||
static constexpr usize GROW_FACTOR = 16;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Try to insert a value into the table.
|
||||
*
|
||||
* @param value The value to insert.
|
||||
* @return Result<bool> An error, true if the insertion succeeded, or false if the value already existed.
|
||||
*/
|
||||
Result<bool> try_set(const T& value)
|
||||
{
|
||||
T copy { value };
|
||||
return try_set(move(copy));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Try to insert a value into the table.
|
||||
*
|
||||
* @param value The value to insert.
|
||||
* @return Result<bool> An error, true if the insertion succeeded, or false if the value already existed.
|
||||
*/
|
||||
Result<bool> try_set(T&& value)
|
||||
{
|
||||
if (should_grow()) TRY(rehash(m_capacity ? m_capacity * GROW_FACTOR : INITIAL_CAPACITY));
|
||||
if (should_grow()) TRY(rehash(m_capacity + GROW_FACTOR));
|
||||
|
||||
u64 index = hash(value, m_salt) % m_capacity;
|
||||
|
||||
@ -72,12 +45,6 @@ template <typename T> class HashTable
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find a value inside the table, returning a pointer to it if found.
|
||||
*
|
||||
* @param value The value to compare against.
|
||||
* @return T* A pointer to the value inside the table if found, or nullptr if it was not found.
|
||||
*/
|
||||
T* try_find(const T& value)
|
||||
{
|
||||
if (!m_size) return nullptr;
|
||||
@ -102,13 +69,6 @@ template <typename T> class HashTable
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove a value from this table.
|
||||
*
|
||||
* @param value The value to remove.
|
||||
* @return true The value was successfully removed.
|
||||
* @return false The value did not exist.
|
||||
*/
|
||||
bool try_remove(const T& value)
|
||||
{
|
||||
if (!m_size) return false;
|
||||
@ -139,9 +99,6 @@ template <typename T> class HashTable
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the table.
|
||||
*/
|
||||
void clear()
|
||||
{
|
||||
if (m_capacity)
|
||||
@ -153,24 +110,11 @@ template <typename T> class HashTable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the number of values that can currently fit in the table.
|
||||
*
|
||||
* The number of actual entries will always be smaller than this (unless it is 0), since the table grows before
|
||||
* the number of entries reaches the capacity.
|
||||
*
|
||||
* @return usize The current capacity.
|
||||
*/
|
||||
usize capacity() const
|
||||
{
|
||||
return m_capacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the number of values currently contained in the table.
|
||||
*
|
||||
* @return usize The number of values contained.
|
||||
*/
|
||||
usize size() const
|
||||
{
|
||||
return m_size;
|
||||
|
@ -1,29 +1,5 @@
|
||||
/**
|
||||
* @file Ignore.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief Do nothing.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @brief Do nothing.
|
||||
*
|
||||
* Calling
|
||||
* ignore(a, b, c);
|
||||
* is a more compact equivalent of doing:
|
||||
* (void)a;
|
||||
* (void)b;
|
||||
* (void)c;
|
||||
*
|
||||
* This function is used to discard unused variables avoiding compiler warnings, if you know they'll be used in the
|
||||
* future.
|
||||
*
|
||||
* @tparam Args The list of ignored variable types.
|
||||
*/
|
||||
template <class... Args> constexpr void ignore(Args...)
|
||||
{
|
||||
}
|
||||
|
@ -1,12 +1,3 @@
|
||||
/**
|
||||
* @file Buffer.cpp
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief A managed wrapper around a resizable buffer of arbitrary memory.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <luna/Buffer.h>
|
||||
#include <luna/CString.h>
|
||||
#include <luna/Heap.h>
|
||||
|
@ -1,13 +1,3 @@
|
||||
/**
|
||||
* @file Hash.cpp
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief Common hash functions for use in hash tables.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <luna/CString.h>
|
||||
#include <luna/Hash.h>
|
||||
|
||||
u64 hash_memory(const void* mem, usize size, u64 salt)
|
||||
|
@ -425,12 +425,12 @@ void dump_heap_usage()
|
||||
#ifdef USE_FREESTANDING
|
||||
void* operator new(usize size, const std::nothrow_t&) noexcept
|
||||
{
|
||||
return malloc_impl(size, false, false).value_or(nullptr);
|
||||
return malloc_impl(size).value_or(nullptr);
|
||||
}
|
||||
|
||||
void* operator new[](usize size, const std::nothrow_t&) noexcept
|
||||
{
|
||||
return malloc_impl(size, false, false).value_or(nullptr);
|
||||
return malloc_impl(size).value_or(nullptr);
|
||||
}
|
||||
|
||||
void operator delete(void* p) noexcept
|
||||
|
@ -1,11 +1,4 @@
|
||||
/**
|
||||
* @file ImplPOSIX.cpp
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief POSIX userspace implementation of libluna hooks.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
/* POSIX userspace implementation of libluna hooks. */
|
||||
|
||||
#include <luna/Attributes.h>
|
||||
#include <luna/Result.h>
|
||||
|
@ -41,7 +41,7 @@ namespace os
|
||||
* _exit(2). If NULL, the promises are not changed.
|
||||
* @param execpromises The promises to apply on the next call to execve(2), separated by spaces. If empty, the
|
||||
* process may only call _exit(2). If NULL, the execpromises are not changed.
|
||||
* @return Result<void> Whether the operation succeeded.
|
||||
* @return Result<void> Whether the operation succeded.
|
||||
*/
|
||||
Result<void> pledge(const char* promises, const char* execpromises);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user