to->mode = from->mode;
to->seq = from->seq;
}
-
-COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsems,
- unsigned, nsops,
- const struct compat_timespec __user *, timeout)
-{
- struct timespec __user *ts64;
- if (compat_convert_timespec(&ts64, timeout))
- return -EFAULT;
- return sys_semtimedop(semid, tsems, nsops, ts64);
-}
return un;
}
-SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
- unsigned, nsops, const struct timespec __user *, timeout)
+static long do_semtimedop(int semid, struct sembuf __user *tsops,
+ unsigned nsops, const struct timespec *timeout)
{
int error = -EINVAL;
struct sem_array *sma;
}
if (timeout) {
- struct timespec _timeout;
- if (copy_from_user(&_timeout, timeout, sizeof(*timeout))) {
- error = -EFAULT;
- goto out_free;
- }
- if (_timeout.tv_sec < 0 || _timeout.tv_nsec < 0 ||
- _timeout.tv_nsec >= 1000000000L) {
+ if (timeout->tv_sec < 0 || timeout->tv_nsec < 0 ||
+ timeout->tv_nsec >= 1000000000L) {
error = -EINVAL;
goto out_free;
}
- jiffies_left = timespec_to_jiffies(&_timeout);
+ jiffies_left = timespec_to_jiffies(timeout);
}
max = 0;
return error;
}
+SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
+ unsigned, nsops, const struct timespec __user *, timeout)
+{
+ if (timeout) {
+ struct timespec ts;
+ if (copy_from_user(&ts, timeout, sizeof(*timeout)))
+ return -EFAULT;
+ return do_semtimedop(semid, tsops, nsops, &ts);
+ }
+ return do_semtimedop(semid, tsops, nsops, NULL);
+}
+
+#ifdef CONFIG_COMPAT
+COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsems,
+ unsigned, nsops,
+ const struct compat_timespec __user *, timeout)
+{
+ if (timeout) {
+ struct timespec ts;
+ if (compat_get_timespec(&ts, timeout))
+ return -EFAULT;
+ return do_semtimedop(semid, tsems, nsops, &ts);
+ }
+ return do_semtimedop(semid, tsems, nsops, NULL);
+}
+#endif
+
SYSCALL_DEFINE3(semop, int, semid, struct sembuf __user *, tsops,
unsigned, nsops)
{
- return sys_semtimedop(semid, tsops, nsops, NULL);
+ return do_semtimedop(semid, tsops, nsops, NULL);
}
/* If CLONE_SYSVSEM is set, establish sharing of SEM_UNDO state between
}
EXPORT_SYMBOL_GPL(compat_put_timespec);
-int compat_convert_timespec(struct timespec __user **kts,
- const void __user *cts)
-{
- struct timespec ts;
- struct timespec __user *uts;
-
- if (!cts || COMPAT_USE_64BIT_TIME) {
- *kts = (struct timespec __user *)cts;
- return 0;
- }
-
- uts = compat_alloc_user_space(sizeof(ts));
- if (!uts)
- return -EFAULT;
- if (compat_get_timespec(&ts, cts))
- return -EFAULT;
- if (copy_to_user(uts, &ts, sizeof(ts)))
- return -EFAULT;
-
- *kts = uts;
- return 0;
-}
-
int get_compat_itimerval(struct itimerval *o, const struct compat_itimerval __user *i)
{
struct compat_itimerval v32;