diff options
author | Dmitry Chagin <dchagin@FreeBSD.org> | 2022-05-06 17:02:59 +0000 |
---|---|---|
committer | Dmitry Chagin <dchagin@FreeBSD.org> | 2022-05-06 17:02:59 +0000 |
commit | 3245a2ecea21ace3d97cec1266fbe29c88ba1a59 (patch) | |
tree | a92a298be90b1c824c5508d0a2e562d05f1fda2f /sys/compat | |
parent | 430460d7178285a26087d294177627e6c88ad369 (diff) | |
download | src-3245a2ecea21ace3d97cec1266fbe29c88ba1a59.tar.gz src-3245a2ecea21ace3d97cec1266fbe29c88ba1a59.zip |
linux(4): Implement semtimedop syscalls.
On i386 are two semtimedop. The old one is called via multiplexor and
uses 32-bit timespec, and new semtimedop_tim64, which is uses 64-bit
timespec.
MFC after: 2 weeks
Diffstat (limited to 'sys/compat')
-rw-r--r-- | sys/compat/linux/linux_ipc.c | 45 | ||||
-rw-r--r-- | sys/compat/linux/linux_ipc.h | 13 |
2 files changed, 58 insertions, 0 deletions
diff --git a/sys/compat/linux/linux_ipc.c b/sys/compat/linux/linux_ipc.c index 3e810c303a2c..51bf18dcd097 100644 --- a/sys/compat/linux/linux_ipc.c +++ b/sys/compat/linux/linux_ipc.c @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #endif #include <compat/linux/linux_ipc.h> #include <compat/linux/linux_ipc64.h> +#include <compat/linux/linux_timer.h> #include <compat/linux/linux_util.h> /* @@ -504,6 +505,50 @@ linux_shminfo_pushdown(l_int ver, struct l_shminfo64 *linux_shminfo64, } } +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) +int +linux_semtimedop_time64(struct thread *td, struct linux_semtimedop_time64_args *args) +{ + struct timespec ts, *tsa; + struct l_timespec64 lts; + int error; + + if (args->timeout) { + if ((error = copyin(args->timeout, <s, sizeof(lts)))) + return (error); + error = linux_to_native_timespec64(&ts, <s); + if (error != 0) + return (error); + tsa = &ts; + } else + tsa = NULL; + + return (kern_semop(td, args->semid, PTRIN(args->tsops), + args->nsops, tsa)); +} +#endif /* __i386__) || (__amd64__ && COMPAT_LINUX32) */ + +int +linux_semtimedop(struct thread *td, struct linux_semtimedop_args *args) +{ + struct timespec ts, *tsa; + struct l_timespec lts; + int error; + + if (args->timeout) { + if ((error = copyin(args->timeout, <s, sizeof(lts)))) + return (error); + error = linux_to_native_timespec(&ts, <s); + if (error != 0) + return (error); + tsa = &ts; + } else + tsa = NULL; + + return (kern_semop(td, args->semid, PTRIN(args->tsops), + args->nsops, tsa)); +} + int linux_semget(struct thread *td, struct linux_semget_args *args) { diff --git a/sys/compat/linux/linux_ipc.h b/sys/compat/linux/linux_ipc.h index beef18a09507..a148814b8273 100644 --- a/sys/compat/linux/linux_ipc.h +++ b/sys/compat/linux/linux_ipc.h @@ -37,6 +37,7 @@ #define LINUX_SEMOP 1 #define LINUX_SEMGET 2 #define LINUX_SEMCTL 3 +#define LINUX_SEMTIMEDOP 4 #define LINUX_MSGSND 11 #define LINUX_MSGRCV 12 #define LINUX_MSGGET 13 @@ -82,4 +83,16 @@ #define LINUX_IPC_64 0x0100 /* New version (support 32-bit UIDs, bigger message sizes, etc. */ +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) +struct linux_semtimedop_args +{ + l_int semid; + struct sembuf *tsops; + l_uint nsops; + struct l_timespec *timeout; +}; + +int linux_semtimedop(struct thread *, struct linux_semtimedop_args *); +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ + #endif /* _LINUX_IPC_H_ */ |