summaryrefslogtreecommitdiffstats
path: root/sys/compat/linux
diff options
context:
space:
mode:
authordchagin <dchagin@FreeBSD.org>2016-03-20 11:40:52 +0000
committerdchagin <dchagin@FreeBSD.org>2016-03-20 11:40:52 +0000
commit0fe879224d0f65dcaeef238ff8075b49a863b1f2 (patch)
tree623ad476cb43c49ee9e0eb58175c20367740ee7b /sys/compat/linux
parentf835afd5ed2447f09706dc54af65a491a65f99ff (diff)
downloadFreeBSD-src-0fe879224d0f65dcaeef238ff8075b49a863b1f2.zip
FreeBSD-src-0fe879224d0f65dcaeef238ff8075b49a863b1f2.tar.gz
Rework r296543:
1. Limit secs to INT32_MAX / 2 to avoid errors from kern_setitimer(). Assert that kern_setitimer() returns 0. Remove bogus cast of secs. Fix style(9) issues. 2. Increment the return value if the remaining tv_usec value more than 500000 as a Linux does. Pointed out by: [1] Bruce Evans MFC after: 1 week
Diffstat (limited to 'sys/compat/linux')
-rw-r--r--sys/compat/linux/linux_misc.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 7e9a0d5..cdadd41 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -191,32 +191,33 @@ linux_alarm(struct thread *td, struct linux_alarm_args *args)
{
struct itimerval it, old_it;
u_int secs;
+ int error;
#ifdef DEBUG
if (ldebug(alarm))
printf(ARGS(alarm, "%u"), args->secs);
#endif
-
secs = args->secs;
-
- if (secs > INT_MAX)
- secs = INT_MAX;
-
- it.it_value.tv_sec = (long) secs;
- it.it_value.tv_usec = 0;
- it.it_interval.tv_sec = 0;
- it.it_interval.tv_usec = 0;
/*
- * According to POSIX and Linux implementation
- * the alarm() system call is always successfull.
- * Ignore errors and return 0 as a Linux does.
+ * Linux alarm() is always successfull. Limit secs to INT32_MAX / 2
+ * to match kern_setitimer()'s limit to avoid error from it.
+ *
+ * XXX. Linux limit secs to INT_MAX on 32 and does not limit on 64-bit
+ * platforms.
*/
- kern_setitimer(td, ITIMER_REAL, &it, &old_it);
- if (timevalisset(&old_it.it_value)) {
- if (old_it.it_value.tv_usec != 0)
- old_it.it_value.tv_sec++;
- td->td_retval[0] = old_it.it_value.tv_sec;
- }
+ if (secs > INT32_MAX / 2)
+ secs = INT32_MAX / 2;
+
+ it.it_value.tv_sec = secs;
+ it.it_value.tv_usec = 0;
+ timevalclear(&it.it_interval);
+ error = kern_setitimer(td, ITIMER_REAL, &it, &old_it);
+ KASSERT(error == 0, ("kern_setitimer returns %d", error));
+
+ if ((old_it.it_value.tv_sec == 0 && old_it.it_value.tv_usec > 0) ||
+ old_it.it_value.tv_usec >= 500000)
+ old_it.it_value.tv_sec++;
+ td->td_retval[0] = old_it.it_value.tv_sec;
return (0);
}
OpenPOWER on IntegriCloud