summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
Diffstat (limited to 'libc')
-rw-r--r--libc/inet/resolv.c2
-rw-r--r--libc/misc/sysvipc/ipc.h9
-rw-r--r--libc/misc/sysvipc/msgq.c21
-rw-r--r--libc/misc/sysvipc/sem.c11
-rw-r--r--libc/misc/sysvipc/shm.c19
-rw-r--r--libc/stdlib/malloc-standard/malloc.c10
-rw-r--r--libc/sysdeps/linux/aarch64/bits/shm.h87
-rw-r--r--libc/sysdeps/linux/arc/bits/fenv.h75
-rw-r--r--libc/sysdeps/linux/arc/fpu_control.h104
-rw-r--r--libc/sysdeps/linux/arm/bits/shm.h6
-rw-r--r--libc/sysdeps/linux/common/Makefile.in1
-rw-r--r--libc/sysdeps/linux/common/bits/msq.h14
-rw-r--r--libc/sysdeps/linux/common/bits/sem.h8
-rw-r--r--libc/sysdeps/linux/common/getentropy.c46
-rw-r--r--libc/sysdeps/linux/common/getrandom.c3
-rw-r--r--libc/sysdeps/linux/common/sys/random.h18
-rw-r--r--libc/sysdeps/linux/common/utimes.c4
-rw-r--r--libc/sysdeps/linux/csky/bits/fenv.h123
-rw-r--r--libc/sysdeps/linux/csky/fpu_control.h147
-rw-r--r--libc/sysdeps/linux/kvx/bits/shm.h87
-rw-r--r--libc/sysdeps/linux/m68k/bits/fenv.h98
-rw-r--r--libc/sysdeps/linux/m68k/bits/shm.h108
-rw-r--r--libc/sysdeps/linux/m68k/bsd-_setjmp.S4
-rw-r--r--libc/sysdeps/linux/m68k/bsd-setjmp.S4
-rw-r--r--libc/sysdeps/linux/m68k/fpu_control.h77
-rw-r--r--libc/sysdeps/linux/m68k/setjmp.S4
-rw-r--r--libc/sysdeps/linux/mips/bits/fenv.h82
-rw-r--r--libc/sysdeps/linux/mips/bits/msq.h94
-rw-r--r--libc/sysdeps/linux/mips/bits/sem.h11
-rw-r--r--libc/sysdeps/linux/mips/bits/shm.h28
-rw-r--r--libc/sysdeps/linux/mips/bits/syscalls.h36
-rw-r--r--libc/sysdeps/linux/mips/fpu_control.h68
-rw-r--r--libc/sysdeps/linux/or1k/bits/fenv.h84
-rw-r--r--libc/sysdeps/linux/or1k/fpu_control.h88
-rw-r--r--libc/sysdeps/linux/riscv32/bits/fenv.h2
-rw-r--r--libc/sysdeps/linux/riscv32/bits/shm.h6
-rw-r--r--libc/sysdeps/linux/riscv64/bits/fenv.h2
-rw-r--r--libc/sysdeps/linux/riscv64/bits/shm.h7
-rw-r--r--libc/sysdeps/linux/sh/bits/fenv.h60
-rw-r--r--libc/sysdeps/linux/sh/fpu_control.h30
-rw-r--r--libc/sysdeps/linux/sparc/bits/fenv.h60
-rw-r--r--libc/sysdeps/linux/sparc/fpu_control.h24
42 files changed, 1489 insertions, 283 deletions
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index 130a9a505..44685e6b8 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -1892,7 +1892,7 @@ int getnameinfo(const struct sockaddr *sa,
socklen_t hostlen,
char *serv,
socklen_t servlen,
- unsigned flags)
+ int flags)
{
int serrno = errno;
bool ok = 0;
diff --git a/libc/misc/sysvipc/ipc.h b/libc/misc/sysvipc/ipc.h
index b342dc1cf..58a690ee3 100644
--- a/libc/misc/sysvipc/ipc.h
+++ b/libc/misc/sysvipc/ipc.h
@@ -1,12 +1,19 @@
#ifndef IPC_H
#define IPC_H
#include <syscall.h>
+#include <bits/kernel-features.h>
#include <bits/wordsize.h>
#ifndef __ARCH_HAS_DEPRECATED_SYSCALLS__
# define __IPC_64 0x0
+#elif defined __mips__ || defined __m68k__
+# if __LINUX_KERNEL_VERSION < 0x050100
+# define __IPC_64 0x100
+# else
+# define __IPC_64 0x0
+# endif
#else
-# if __WORDSIZE == 32 || defined __alpha__ || defined __mips__
+# if __WORDSIZE == 32 || defined __alpha__
# define __IPC_64 0x100
# else
# define __IPC_64 0x0
diff --git a/libc/misc/sysvipc/msgq.c b/libc/misc/sysvipc/msgq.c
index 185cd268b..2d8bcae99 100644
--- a/libc/misc/sysvipc/msgq.c
+++ b/libc/misc/sysvipc/msgq.c
@@ -1,5 +1,6 @@
#include <errno.h>
#include <sys/msg.h>
+#include <stddef.h>
#include "ipc.h"
#ifdef __UCLIBC_HAS_THREADS_NATIVE__
#include "sysdep-cancel.h"
@@ -7,6 +8,12 @@
#define SINGLE_THREAD_P 1
#endif
+#if defined(__UCLIBC_USE_TIME64__)
+union msqun {
+ struct msqid_ds* buff;
+ void *__pad;
+};
+#endif
#ifdef L_msgctl
@@ -18,9 +25,19 @@ static __inline__ _syscall3(int, __libc_msgctl, int, msqid, int, cmd, struct msq
int msgctl(int msqid, int cmd, struct msqid_ds *buf)
{
#ifdef __NR_msgctl
- return __libc_msgctl(msqid, cmd | __IPC_64, buf);
+ int __ret = __libc_msgctl(msqid, cmd | __IPC_64, buf);
+#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__) && (defined(__mips) || defined(__riscv))
+ union msqun arg = {.buff = buf};
+ // When cmd is IPC_RMID, buf should be NULL.
+ if (arg.__pad != NULL) {
+ arg.buff->msg_stime = (__time_t)arg.buff->msg_stime_internal_1 | (__time_t)(arg.buff->msg_stime_internal_2) << 32;
+ arg.buff->msg_rtime = (__time_t)arg.buff->msg_rtime_internal_1 | (__time_t)(arg.buff->msg_rtime_internal_2) << 32;
+ arg.buff->msg_ctime = (__time_t)arg.buff->msg_ctime_internal_1 | (__time_t)(arg.buff->msg_ctime_internal_2) << 32;
+ }
+#endif
+ return __ret;
#else
- return __syscall_ipc(IPCOP_msgctl, msqid, cmd | __IPC_64, 0, buf, 0);
+ return __syscall_ipc(IPCOP_msgctl, msqid, cmd | __IPC_64, 0, buf, 0);
#endif
}
#endif
diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c
index 07076eff7..66f86f53c 100644
--- a/libc/misc/sysvipc/sem.c
+++ b/libc/misc/sysvipc/sem.c
@@ -57,9 +57,14 @@ int semctl(int semid, int semnum, int cmd, ...)
va_end (ap);
#ifdef __NR_semctl
int __ret = __semctl(semid, semnum, cmd | __IPC_64, arg.__pad);
-#if defined(__UCLIBC_USE_TIME64__)
- arg.buf->sem_otime = (__time_t)arg.buf->__sem_otime_internal_1 | (__time_t)(arg.buf->__sem_otime_internal_2) << 32;
- arg.buf->sem_ctime = (__time_t)arg.buf->__sem_ctime_internal_1 | (__time_t)(arg.buf->__sem_ctime_internal_2) << 32;
+#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__)
+ // Only when cmd is IPC_STAT and IPC_SET, semun points to struct semid_ds.
+ // At this point, arg.__pad should not be NULL, but a check is added just
+ // to be safe.
+ if ((cmd & (IPC_STAT | IPC_SET)) && (arg.__pad != NULL)) {
+ arg.buf->sem_otime = (__time_t)arg.buf->__sem_otime_internal_1 | (__time_t)(arg.buf->__sem_otime_internal_2) << 32;
+ arg.buf->sem_ctime = (__time_t)arg.buf->__sem_ctime_internal_1 | (__time_t)(arg.buf->__sem_ctime_internal_2) << 32;
+ }
#endif
return __ret;
#else
diff --git a/libc/misc/sysvipc/shm.c b/libc/misc/sysvipc/shm.c
index cd46ff0dd..b3366b301 100644
--- a/libc/misc/sysvipc/shm.c
+++ b/libc/misc/sysvipc/shm.c
@@ -25,6 +25,13 @@
#include <syscall.h>
#include "ipc.h"
+#if defined(__UCLIBC_USE_TIME64__)
+union shmun {
+ struct shmid_ds* buff;
+ void *__pad;
+};
+#endif
+
#ifdef L_shmat
/* Attach the shared memory segment associated with SHMID to the data
segment of the calling process. SHMADDR and SHMFLG determine how
@@ -59,7 +66,17 @@ static __always_inline _syscall3(int, __syscall_shmctl, int, shmid, int, cmd, st
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
{
#ifdef __NR_shmctl
- return __syscall_shmctl(shmid, cmd | __IPC_64, buf);
+ int __ret = __syscall_shmctl(shmid, cmd | __IPC_64, buf);
+#if (__WORDSIZE == 32) && defined(__mips) && defined(__UCLIBC_USE_TIME64__)
+ union shmun arg = {.buff = buf};
+ // When cmd is IPC_RMID, buf should be NULL.
+ if (arg.__pad != NULL) {
+ arg.buff->shm_atime = (__time_t)arg.buff->shm_atime_internal_1 | (__time_t)(arg.buff->shm_atime_internal_2) << 32;
+ arg.buff->shm_dtime = (__time_t)arg.buff->shm_dtime_internal_1 | (__time_t)(arg.buff->shm_dtime_internal_2) << 32;
+ arg.buff->shm_ctime = (__time_t)arg.buff->shm_ctime_internal_1 | (__time_t)(arg.buff->shm_ctime_internal_2) << 32;
+ }
+#endif
+ return __ret;
#else
return __syscall_ipc(IPCOP_shmctl, shmid, cmd | __IPC_64, 0, buf, 0);
#endif
diff --git a/libc/stdlib/malloc-standard/malloc.c b/libc/stdlib/malloc-standard/malloc.c
index cecea87ec..e51bc6610 100644
--- a/libc/stdlib/malloc-standard/malloc.c
+++ b/libc/stdlib/malloc-standard/malloc.c
@@ -29,7 +29,7 @@ __UCLIBC_MUTEX_INIT(__malloc_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
struct malloc_state __malloc_state; /* never directly referenced */
/* forward declaration */
-static int __malloc_largebin_index(unsigned int sz);
+static int __malloc_largebin_index(unsigned long sz);
#ifdef __UCLIBC_MALLOC_DEBUGGING__
@@ -755,10 +755,10 @@ static void* __malloc_alloc(size_t nb, mstate av)
Compute index for size. We expect this to be inlined when
compiled with optimization, else not, which works out well.
*/
-static int __malloc_largebin_index(unsigned int sz)
+static int __malloc_largebin_index(unsigned long sz)
{
- unsigned int x = sz >> SMALLBIN_WIDTH;
- unsigned int m; /* bit position of highest set bit of m */
+ unsigned long x = sz >> SMALLBIN_WIDTH;
+ unsigned long m; /* bit position of highest set bit of m */
if (x >= 0x10000) return NBINS-1;
@@ -776,7 +776,7 @@ static int __malloc_largebin_index(unsigned int sz)
S. Warren Jr's book "Hacker's Delight".
*/
- unsigned int n = ((x - 0x100) >> 16) & 8;
+ unsigned long n = ((x - 0x100) >> 16) & 8;
x <<= n;
m = ((x - 0x1000) >> 16) & 4;
n += m;
diff --git a/libc/sysdeps/linux/aarch64/bits/shm.h b/libc/sysdeps/linux/aarch64/bits/shm.h
new file mode 100644
index 000000000..bfb603499
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/bits/shm.h
@@ -0,0 +1,87 @@
+/*
+ * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB
+ * in this tarball.
+ */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Permission flag for shmget. */
+#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
+#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
+
+/* Flags for `shmat'. */
+#define SHM_RDONLY 010000 /* attach read-only else read-write */
+#define SHM_RND 020000 /* round attach address to SHMLBA */
+#define SHM_REMAP 040000 /* take-over region on attach */
+
+/* Commands for `shmctl'. */
+#define SHM_LOCK 11 /* lock segment (root only) */
+#define SHM_UNLOCK 12 /* unlock segment (root only) */
+
+__BEGIN_DECLS
+
+/* Segment low boundary address multiple. */
+#define SHMLBA (__getpagesize () << 2)
+extern int __getpagesize (void) __THROW __attribute__ ((__const__));
+
+
+/* Type to count number of attaches. */
+typedef unsigned long int shmatt_t;
+
+/* Data structure describing a set of semaphores. */
+struct shmid_ds
+ {
+ struct ipc_perm shm_perm; /* operation permission struct */
+ size_t shm_segsz; /* size of segment in bytes */
+ __time_t shm_atime; /* time of last shmat() */
+ __time_t shm_dtime; /* time of last shmdt() */
+ __time_t shm_ctime; /* time of last change by shmctl() */
+ __pid_t shm_cpid; /* pid of creator */
+ __pid_t shm_lpid; /* pid of last shmop */
+ shmatt_t shm_nattch; /* number of current attaches */
+ unsigned long int __uclibc_unused1;
+ unsigned long int __uclibc_unused2;
+ };
+
+#ifdef __USE_MISC
+
+/* ipcs ctl commands */
+# define SHM_STAT 13
+# define SHM_INFO 14
+
+/* shm_mode upper byte flags */
+# define SHM_DEST 01000 /* segment will be destroyed on last detach */
+# define SHM_LOCKED 02000 /* segment will not be swapped */
+# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */
+# define SHM_NORESERVE 010000 /* don't check for reservations */
+
+struct shminfo
+ {
+ unsigned long int shmmax;
+ unsigned long int shmmin;
+ unsigned long int shmmni;
+ unsigned long int shmseg;
+ unsigned long int shmall;
+ unsigned long int __uclibc_unused1;
+ unsigned long int __uclibc_unused2;
+ unsigned long int __uclibc_unused3;
+ unsigned long int __uclibc_unused4;
+ };
+
+struct shm_info
+ {
+ int used_ids;
+ unsigned long int shm_tot; /* total allocated shm */
+ unsigned long int shm_rss; /* total resident shm */
+ unsigned long int shm_swp; /* total swapped shm */
+ unsigned long int swap_attempts;
+ unsigned long int swap_successes;
+ };
+
+#endif /* __USE_MISC */
+
+__END_DECLS
diff --git a/libc/sysdeps/linux/arc/bits/fenv.h b/libc/sysdeps/linux/arc/bits/fenv.h
new file mode 100644
index 000000000..c5c76cb93
--- /dev/null
+++ b/libc/sysdeps/linux/arc/bits/fenv.h
@@ -0,0 +1,75 @@
+/* Floating point environment. ARC version.
+ Copyright (C) 2020-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+enum
+ {
+ FE_INVALID =
+# define FE_INVALID (0x01)
+ FE_INVALID,
+ FE_DIVBYZERO =
+# define FE_DIVBYZERO (0x02)
+ FE_DIVBYZERO,
+ FE_OVERFLOW =
+# define FE_OVERFLOW (0x04)
+ FE_OVERFLOW,
+ FE_UNDERFLOW =
+# define FE_UNDERFLOW (0x08)
+ FE_UNDERFLOW,
+ FE_INEXACT =
+# define FE_INEXACT (0x10)
+ FE_INEXACT
+ };
+
+# define FE_ALL_EXCEPT \
+ (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
+
+enum
+ {
+ FE_TOWARDZERO =
+# define FE_TOWARDZERO (0x0)
+ FE_TOWARDZERO,
+ FE_TONEAREST =
+# define FE_TONEAREST (0x1) /* default */
+ FE_TONEAREST,
+ FE_UPWARD =
+# define FE_UPWARD (0x2)
+ FE_UPWARD,
+ FE_DOWNWARD =
+# define FE_DOWNWARD (0x3)
+ FE_DOWNWARD
+ };
+
+typedef unsigned int fexcept_t;
+
+typedef struct
+{
+ unsigned int __fpcr;
+ unsigned int __fpsr;
+} fenv_t;
+
+/* If the default argument is used we use this value. */
+#define FE_DFL_ENV ((const fenv_t *) -1)
+
+/* Type representing floating-point control modes. */
+typedef unsigned int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) -1L)
diff --git a/libc/sysdeps/linux/arc/fpu_control.h b/libc/sysdeps/linux/arc/fpu_control.h
new file mode 100644
index 000000000..e833de3aa
--- /dev/null
+++ b/libc/sysdeps/linux/arc/fpu_control.h
@@ -0,0 +1,104 @@
+/* FPU control word bits. ARC version.
+ Copyright (C) 2020-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _FPU_CONTROL_H
+#define _FPU_CONTROL_H
+
+/* ARC FPU control register bits.
+
+ [ 0] -> IVE: Enable invalid operation exception.
+ if 0, soft exception: status register IV flag set.
+ if 1, hardware exception trap (not supported in Linux yet).
+ [ 1] -> DZE: Enable division by zero exception.
+ if 0, soft exception: status register IV flag set.
+ if 1, hardware exception: (not supported in Linux yet).
+ [9:8] -> RM: Rounding Mode:
+ 00 - Rounding toward zero.
+ 01 - Rounding to nearest (default).
+ 10 - Rounding (up) toward plus infinity.
+ 11 - Rounding (down)toward minus infinity.
+
+ ARC FPU status register bits.
+
+ [ 0] -> IV: flag invalid operation.
+ [ 1] -> DZ: flag division by zero.
+ [ 2] -> OV: flag Overflow operation.
+ [ 3] -> UV: flag Underflow operation.
+ [ 4] -> IX: flag Inexact operation.
+ [31] -> FWE: Flag Write Enable.
+ If 1, above flags writable explicitly (clearing),
+ else IoW and only writable indirectly via bits [12:7]. */
+
+#include <features.h>
+
+#if !defined(__ARC_FPU_SP__) && !defined(__ARC_FPU_DP__)
+
+# define _FPU_RESERVED 0xffffffff
+# define _FPU_DEFAULT 0x00000000
+typedef unsigned int fpu_control_t;
+# define _FPU_GETCW(cw) (cw) = 0
+# define _FPU_SETCW(cw) (void) (cw)
+# define _FPU_GETS(cw) (cw) = 0
+# define _FPU_SETS(cw) (void) (cw)
+extern fpu_control_t __fpu_control;
+
+#else
+
+#define _FPU_RESERVED 0
+
+/* The fdlibm code requires strict IEEE double precision arithmetic,
+ and no interrupts for exceptions, rounding to nearest.
+ So only RM set to b'01. */
+# define _FPU_DEFAULT 0x00000100
+
+/* Actually default needs to have FWE bit as 1 but that is already
+ ingrained into _FPU_SETS macro below. */
+#define _FPU_FPSR_DEFAULT 0x00000000
+
+#define __FPU_RND_SHIFT 8
+#define __FPU_RND_MASK 0x3
+
+/* Type of the control word. */
+typedef unsigned int fpu_control_t;
+
+/* Macros for accessing the hardware control word. */
+# define _FPU_GETCW(cw) __asm__ volatile ("lr %0, [0x300]" : "=r" (cw))
+# define _FPU_SETCW(cw) __asm__ volatile ("sr %0, [0x300]" : : "r" (cw))
+
+/* Macros for accessing the hardware status word.
+ Writing to FPU_STATUS requires a "control" bit FWE to be able to set the
+ exception flags directly (as opposed to side-effects of FP instructions).
+ That is done in the macro here to keeps callers agnostic of this detail.
+ And given FWE is write-only and RAZ, no need to "clear" it in _FPU_GETS
+ macro. */
+# define _FPU_GETS(cw) \
+ __asm__ volatile ("lr %0, [0x301] \r\n" \
+ : "=r" (cw))
+
+# define _FPU_SETS(cw) \
+ do { \
+ unsigned int __fwe = 0x80000000 | (cw); \
+ __asm__ volatile ("sr %0, [0x301] \r\n" \
+ : : "r" (__fwe)); \
+ } while (0)
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+#endif
+
+#endif /* fpu_control.h */
diff --git a/libc/sysdeps/linux/arm/bits/shm.h b/libc/sysdeps/linux/arm/bits/shm.h
index 86245faff..aa1a72e54 100644
--- a/libc/sysdeps/linux/arm/bits/shm.h
+++ b/libc/sysdeps/linux/arm/bits/shm.h
@@ -49,12 +49,18 @@ struct shmid_ds
{
struct ipc_perm shm_perm; /* operation permission struct */
size_t shm_segsz; /* size of segment in bytes */
+#if defined(__UCLIBC_USE_TIME64__)
+ __time_t shm_atime;
+ __time_t shm_dtime;
+ __time_t shm_ctime;
+#else
__time_t shm_atime; /* time of last shmat() */
unsigned long int __uclibc_unused1;
__time_t shm_dtime; /* time of last shmdt() */
unsigned long int __uclibc_unused2;
__time_t shm_ctime; /* time of last change by shmctl() */
unsigned long int __uclibc_unused3;
+#endif
__pid_t shm_cpid; /* pid of creator */
__pid_t shm_lpid; /* pid of last shmop */
shmatt_t shm_nattch; /* number of current attaches */
diff --git a/libc/sysdeps/linux/common/Makefile.in b/libc/sysdeps/linux/common/Makefile.in
index e0b280c33..4a4317432 100644
--- a/libc/sysdeps/linux/common/Makefile.in
+++ b/libc/sysdeps/linux/common/Makefile.in
@@ -27,6 +27,7 @@ CSRC-$(UCLIBC_LINUX_SPECIFIC) += \
eventfd_write.c \
fanotify.c \
getrandom.c \
+ getentropy.c \
inotify.c \
ioperm.c \
iopl.c \
diff --git a/libc/sysdeps/linux/common/bits/msq.h b/libc/sysdeps/linux/common/bits/msq.h
index b594cfff2..0cb734263 100644
--- a/libc/sysdeps/linux/common/bits/msq.h
+++ b/libc/sysdeps/linux/common/bits/msq.h
@@ -37,17 +37,31 @@ typedef unsigned long int msglen_t;
struct msqid_ds
{
struct ipc_perm msg_perm; /* structure describing operation permission */
+#if (__WORDSIZE == 32 && defined(__riscv) && defined(__UCLIBC_USE_TIME64__))
+ unsigned long int msg_stime_internal_1;
+ unsigned long int msg_stime_internal_2;
+ unsigned long int msg_rtime_internal_1;
+ unsigned long int msg_rtime_internal_2;
+ unsigned long int msg_ctime_internal_1;
+ unsigned long int msg_ctime_internal_2;
+#else
__time_t msg_stime; /* time of last msgsnd command */
unsigned long int __uclibc_unused1;
__time_t msg_rtime; /* time of last msgrcv command */
unsigned long int __uclibc_unused2;
__time_t msg_ctime; /* time of last change */
unsigned long int __uclibc_unused3;
+#endif
unsigned long int __msg_cbytes; /* current number of bytes on queue */
msgqnum_t msg_qnum; /* number of messages currently on queue */
msglen_t msg_qbytes; /* max number of bytes allowed on queue */
__pid_t msg_lspid; /* pid of last msgsnd() */
__pid_t msg_lrpid; /* pid of last msgrcv() */
+#if (__WORDSIZE == 32 && defined(__riscv) && defined(__UCLIBC_USE_TIME64__))
+ __time_t msg_stime; /* time of last msgsnd command */
+ __time_t msg_rtime; /* time of last msgrcv command */
+ __time_t msg_ctime; /* time of last change */
+#endif
unsigned long int __uclibc_unused4;
unsigned long int __uclibc_unused5;
};
diff --git a/libc/sysdeps/linux/common/bits/sem.h b/libc/sysdeps/linux/common/bits/sem.h
index 24a130981..d855494ee 100644
--- a/libc/sysdeps/linux/common/bits/sem.h
+++ b/libc/sysdeps/linux/common/bits/sem.h
@@ -45,8 +45,8 @@ struct semid_ds
#else
__time_t sem_otime; /* last semop() time */
#endif
-#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__)) || \
- ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__)) && !defined(__UCLIBC_USE_TIME64__))
+#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__) && !defined(__riscv)) || \
+ ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__) || defined(__riscv)) && !defined(__UCLIBC_USE_TIME64__))
unsigned long int __uclibc_unused1;
#endif
#if defined(__UCLIBC_USE_TIME64__)
@@ -55,8 +55,8 @@ struct semid_ds
#else
__time_t sem_ctime; /* last time changed by semctl() */
#endif
-#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__)) || \
- ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__)) && !defined(__UCLIBC_USE_TIME64__))
+#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__) && !defined(__riscv)) || \
+ ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__) || defined(__riscv)) && !defined(__UCLIBC_USE_TIME64__))
unsigned long int __uclibc_unused2;
#endif
unsigned long int sem_nsems; /* number of semaphores in set */
diff --git a/libc/sysdeps/linux/common/getentropy.c b/libc/sysdeps/linux/common/getentropy.c
new file mode 100644
index 000000000..d255310b6
--- /dev/null
+++ b/libc/sysdeps/linux/common/getentropy.c
@@ -0,0 +1,46 @@
+/*
+ * getentropy() by wrapping getrandom(), for µClibc-ng
+ *
+ * © 2025 mirabilos Ⓕ CC0 or MirBSD or GNU LGPLv2
+ *
+ * Note: may be a thread cancellation point, unlike the
+ * implementations in glibc and musl libc. Should this
+ * ever become a concern, it will need patching.
+ */
+
+#define _DEFAULT_SOURCE
+#include <errno.h>
+#include <unistd.h>
+#include <sys/random.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_getrandom
+int
+getentropy(void *__buf, size_t __len)
+{
+ ssize_t n;
+
+ if (__len > 256U) {
+ errno = EIO;
+ return (-1);
+ }
+
+ again:
+ if ((n = getrandom(__buf, __len, 0)) == -1)
+ switch (errno) {
+ case EAGAIN: /* should not happen but better safe than sorry */
+ case EINTR:
+ goto again;
+ default:
+ errno = EIO;
+ /* FALLTHROUGH */
+ case EFAULT:
+ case ENOSYS:
+ return (-1);
+ }
+ if ((size_t)n != __len)
+ /* also shouldn’t happen (safety net) */
+ goto again;
+ return (0);
+}
+#endif
diff --git a/libc/sysdeps/linux/common/getrandom.c b/libc/sysdeps/linux/common/getrandom.c
index bb9841463..1db1663b9 100644
--- a/libc/sysdeps/linux/common/getrandom.c
+++ b/libc/sysdeps/linux/common/getrandom.c
@@ -8,6 +8,7 @@
#include <sys/syscall.h>
#include <sys/random.h>
+
#ifdef __NR_getrandom
-_syscall3(int, getrandom, void *, buf, size_t, buflen, unsigned int, flags)
+_syscall3(ssize_t, getrandom, void *, buf, size_t, buflen, unsigned int, flags)
#endif
diff --git a/libc/sysdeps/linux/common/sys/random.h b/libc/sysdeps/linux/common/sys/random.h
index 3d24e439b..c3d9cf575 100644
--- a/libc/sysdeps/linux/common/sys/random.h
+++ b/libc/sysdeps/linux/common/sys/random.h
@@ -4,11 +4,19 @@
#ifndef _SYS_RANDOM_H
#define _SYS_RANDOM_H 1
+
#include <features.h>
#include <stddef.h>
__BEGIN_DECLS
+#include <bits/types.h>
+
+#ifndef __ssize_t_defined
+typedef __ssize_t ssize_t;
+# define __ssize_t_defined
+#endif
+
#if defined __UCLIBC_LINUX_SPECIFIC__
# if 0 /*def __ASSUME_GETRANDOM_SYSCALL */
# include <linux/random.h>
@@ -26,9 +34,15 @@ __BEGIN_DECLS
# define GRND_RANDOM 0x0002
# define GRND_INSECURE 0x0004
# endif
-/* FIXME: aren't there a couple of __restrict and const missing ? */
-extern int getrandom(void *__buf, size_t count, unsigned int flags)
+extern ssize_t getrandom(void *__buf, size_t count, unsigned int flags)
__nonnull ((1)) __wur;
+
+/* OpenBSD-compatible access to random bytes.
+ May be a cancellation point here, unlike in glibc/musl. */
+# ifndef __getentropy_defined
+extern int getentropy(void *__buf, size_t __len) __nonnull ((1)) __wur;
+# define __getentropy_defined
+# endif
#endif
__END_DECLS
diff --git a/libc/sysdeps/linux/common/utimes.c b/libc/sysdeps/linux/common/utimes.c
index a28594dfd..c471a9b89 100644
--- a/libc/sysdeps/linux/common/utimes.c
+++ b/libc/sysdeps/linux/common/utimes.c
@@ -9,7 +9,7 @@
#include <sys/syscall.h>
#include <sys/time.h>
-#if (defined (__NR_utimensat) || defined(__NR_utimensat_time64)) && !defined __NR_utimes
+#if (defined (__NR_utimensat) || defined(__NR_utimensat_time64)) && (!defined __NR_utimes || defined(__UCLIBC_USE_TIME64__))
# include <fcntl.h>
# include <stddef.h>
int utimes(const char *file, const struct timeval tvp[2])
@@ -50,6 +50,6 @@ int utimes(const char *file, const struct timeval tvp[2])</