diff --git a/Userland/Libraries/LibC/semaphore.cpp b/Userland/Libraries/LibC/semaphore.cpp index a3546459cd..264edcbf92 100644 --- a/Userland/Libraries/LibC/semaphore.cpp +++ b/Userland/Libraries/LibC/semaphore.cpp @@ -12,6 +12,8 @@ #include #include +static constexpr u32 SEM_MAGIC = 0x78951230; + // Whether sem_wait() or sem_post() is responsible for waking any sleeping // threads. static constexpr u32 POST_WAKES = 1 << 31; @@ -50,19 +52,31 @@ int sem_init(sem_t* sem, int shared, unsigned int value) return -1; } + sem->magic = SEM_MAGIC; sem->value = value; return 0; } // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_destroy.html -int sem_destroy(sem_t*) +int sem_destroy(sem_t* sem) { + if (sem->magic != SEM_MAGIC) { + errno = EINVAL; + return -1; + } + + sem->magic = 0; return 0; } // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_getvalue.html int sem_getvalue(sem_t* sem, int* sval) { + if (sem->magic != SEM_MAGIC) { + errno = EINVAL; + return -1; + } + u32 value = AK::atomic_load(&sem->value, AK::memory_order_relaxed); *sval = value & ~POST_WAKES; return 0; @@ -71,6 +85,11 @@ int sem_getvalue(sem_t* sem, int* sval) // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_post.html int sem_post(sem_t* sem) { + if (sem->magic != SEM_MAGIC) { + errno = EINVAL; + return -1; + } + u32 value = AK::atomic_fetch_add(&sem->value, 1u, AK::memory_order_release); // Fast path: no need to wake. if (!(value & POST_WAKES)) [[likely]] @@ -91,6 +110,11 @@ int sem_post(sem_t* sem) // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_trywait.html int sem_trywait(sem_t* sem) { + if (sem->magic != SEM_MAGIC) { + errno = EINVAL; + return -1; + } + u32 value = AK::atomic_load(&sem->value, AK::memory_order_relaxed); u32 count = value & ~POST_WAKES; if (count == 0) { @@ -111,12 +135,22 @@ int sem_trywait(sem_t* sem) // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_wait.html int sem_wait(sem_t* sem) { + if (sem->magic != SEM_MAGIC) { + errno = EINVAL; + return -1; + } + return sem_timedwait(sem, nullptr); } // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_timedwait.html int sem_timedwait(sem_t* sem, const struct timespec* abstime) { + if (sem->magic != SEM_MAGIC) { + errno = EINVAL; + return -1; + } + u32 value = AK::atomic_load(&sem->value, AK::memory_order_relaxed); bool responsible_for_waking = false; diff --git a/Userland/Libraries/LibC/semaphore.h b/Userland/Libraries/LibC/semaphore.h index d04c22943e..3485fb58aa 100644 --- a/Userland/Libraries/LibC/semaphore.h +++ b/Userland/Libraries/LibC/semaphore.h @@ -14,6 +14,7 @@ __BEGIN_DECLS typedef struct { + uint32_t magic; uint32_t value; } sem_t;