getopt: fix null pointer arithmetic ub
[musl] / src / thread / sem_timedwait.c
1 #include <semaphore.h>
2 #include <limits.h>
3 #include "pthread_impl.h"
4
5 static void cleanup(void *p)
6 {
7         a_dec(p);
8 }
9
10 int sem_timedwait(sem_t *restrict sem, const struct timespec *restrict at)
11 {
12         pthread_testcancel();
13
14         if (!sem_trywait(sem)) return 0;
15
16         int spins = 100;
17         while (spins-- && !(sem->__val[0] & SEM_VALUE_MAX) && !sem->__val[1])
18                 a_spin();
19
20         while (sem_trywait(sem)) {
21                 int r, priv = sem->__val[2];
22                 a_inc(sem->__val+1);
23                 a_cas(sem->__val, 0, 0x80000000);
24                 pthread_cleanup_push(cleanup, (void *)(sem->__val+1));
25                 r = __timedwait_cp(sem->__val, 0x80000000, CLOCK_REALTIME, at, priv);
26                 pthread_cleanup_pop(1);
27                 if (r) {
28                         errno = r;
29                         return -1;
30                 }
31         }
32         return 0;
33 }