1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-30 02:47:35 +00:00

Add some basic setgroups(), getgroups() and initgroups().

Also teach /bin/id to print the user's supplemental groups.
This commit is contained in:
Andreas Kling 2018-11-07 01:38:51 +01:00
parent d3bd3791cb
commit a7f1d892a9
12 changed files with 167 additions and 19 deletions

View file

@ -8,6 +8,7 @@ template<typename T>
class DoublyLinkedList {
private:
struct Node {
explicit Node(const T& v) : value(v) { }
explicit Node(T&& v) : value(move(v)) { }
T value;
Node* next { nullptr };
@ -38,17 +39,13 @@ public:
void append(T&& value)
{
auto* node = new Node(move(value));
if (!m_head) {
ASSERT(!m_tail);
m_head = node;
m_tail = node;
return;
}
ASSERT(m_tail);
m_tail->next = node;
node->prev = m_tail;
m_tail = node;
append_node(new Node(move(value)));
}
void append(const T& value)
{
append_node(new Node(value));
}
bool containsSlow(const T& value) const
@ -136,6 +133,20 @@ public:
private:
friend class Iterator;
void append_node(Node* node)
{
if (!m_head) {
ASSERT(!m_tail);
m_head = node;
m_tail = node;
return;
}
ASSERT(m_tail);
m_tail->next = node;
node->prev = m_tail;
m_tail = node;
}
Node* head() { return m_head; }
const Node* head() const { return m_head; }

View file

@ -48,6 +48,7 @@ public:
unsigned size() const { return m_size; }
unsigned capacity() const { return m_capacity; }
void set(const T&);
void set(T&&);
bool contains(const T&) const;
void clear();
@ -224,6 +225,7 @@ private:
Bucket& lookup(const T&, unsigned* bucketIndex = nullptr);
const Bucket& lookup(const T&, unsigned* bucketIndex = nullptr) const;
void rehash(unsigned capacity);
void insert(const T&);
void insert(T&&);
Bucket* m_buckets { nullptr };
@ -251,6 +253,26 @@ void HashTable<T, TraitsForT>::set(T&& value)
m_size++;
}
template<typename T, typename TraitsForT>
void HashTable<T, TraitsForT>::set(const T& value)
{
if (!m_capacity)
rehash(1);
auto& bucket = lookup(value);
for (auto& e : bucket.chain) {
if (e == value)
return;
}
if (size() >= capacity()) {
rehash(size() + 1);
insert(value);
} else {
bucket.chain.append(value);
}
m_size++;
}
template<typename T, typename TraitsForT>
void HashTable<T, TraitsForT>::rehash(unsigned newCapacity)
{
@ -291,6 +313,13 @@ void HashTable<T, TraitsForT>::insert(T&& value)
bucket.chain.append(move(value));
}
template<typename T, typename TraitsForT>
void HashTable<T, TraitsForT>::insert(const T& value)
{
auto& bucket = lookup(value);
bucket.chain.append(value);
}
template<typename T, typename TraitsForT>
bool HashTable<T, TraitsForT>::contains(const T& value) const
{