diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 02c38a0c594a..e589737bf767 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -1286,6 +1286,37 @@ freebsd4_freebsd32_sigaction(struct thread *td, } #endif +int +freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap) +{ + struct timespec32 rmt32, rqt32; + struct timespec rmt, rqt; + int error; + + error = copyin(uap->rqtp, &rqt32, sizeof(rqt)); + if (error) + return (error); + + CP(rqt32, rqt, tv_sec); + CP(rqt32, rqt, tv_nsec); + + if (uap->rmtp && + !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) + return (EFAULT); + error = kern_nanosleep(td, &rqt, &rmt); + if (error && uap->rmtp) { + int error2; + + CP(rmt, rmt32, tv_sec); + CP(rmt, rmt32, tv_nsec); + + error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt)); + if (error2) + error = error2; + } + return (error); +} + #if 0 int diff --git a/sys/compat/freebsd32/freebsd32_proto.h b/sys/compat/freebsd32/freebsd32_proto.h index 973fbb66fd43..e74348123343 100644 --- a/sys/compat/freebsd32/freebsd32_proto.h +++ b/sys/compat/freebsd32/freebsd32_proto.h @@ -179,6 +179,10 @@ struct freebsd32_sysctl_args { char new_l_[PADL_(void *)]; void * new; char new_r_[PADR_(void *)]; char newlen_l_[PADL_(u_int32_t)]; u_int32_t newlen; char newlen_r_[PADR_(u_int32_t)]; }; +struct freebsd32_nanosleep_args { + char rqtp_l_[PADL_(const struct timespec *)]; const struct timespec * rqtp; char rqtp_r_[PADR_(const struct timespec *)]; + char rmtp_l_[PADL_(struct timespec *)]; struct timespec * rmtp; char rmtp_r_[PADR_(struct timespec *)]; +}; struct freebsd32_kevent_args { char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; char changelist_l_[PADL_(const struct kevent *)]; const struct kevent * changelist; char changelist_r_[PADR_(const struct kevent *)]; @@ -231,6 +235,7 @@ int freebsd32_lseek(struct thread *, struct freebsd32_lseek_args *); int freebsd32_truncate(struct thread *, struct freebsd32_truncate_args *); int freebsd32_ftruncate(struct thread *, struct freebsd32_ftruncate_args *); int freebsd32_sysctl(struct thread *, struct freebsd32_sysctl_args *); +int freebsd32_nanosleep(struct thread *, struct freebsd32_nanosleep_args *); int freebsd32_kevent(struct thread *, struct freebsd32_kevent_args *); int freebsd32_sendfile(struct thread *, struct freebsd32_sendfile_args *); int freebsd32_sigaction(struct thread *, struct freebsd32_sigaction_args *); diff --git a/sys/compat/freebsd32/freebsd32_syscall.h b/sys/compat/freebsd32/freebsd32_syscall.h index e224c7360a1b..21e1e3ed9fd4 100644 --- a/sys/compat/freebsd32/freebsd32_syscall.h +++ b/sys/compat/freebsd32/freebsd32_syscall.h @@ -201,7 +201,7 @@ #define FREEBSD32_SYS_clock_gettime 232 #define FREEBSD32_SYS_clock_settime 233 #define FREEBSD32_SYS_clock_getres 234 -#define FREEBSD32_SYS_nanosleep 240 +#define FREEBSD32_SYS_freebsd32_nanosleep 240 #define FREEBSD32_SYS_minherit 250 #define FREEBSD32_SYS_rfork 251 #define FREEBSD32_SYS_openbsd_poll 252 diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c index f7a3016fb661..854d512b7e74 100644 --- a/sys/compat/freebsd32/freebsd32_syscalls.c +++ b/sys/compat/freebsd32/freebsd32_syscalls.c @@ -247,7 +247,7 @@ const char *freebsd32_syscallnames[] = { "#237", /* 237 = timer_settime */ "#238", /* 238 = timer_gettime */ "#239", /* 239 = timer_getoverrun */ - "nanosleep", /* 240 = nanosleep */ + "freebsd32_nanosleep", /* 240 = freebsd32_nanosleep */ "#241", /* 241 = nosys */ "#242", /* 242 = nosys */ "#243", /* 243 = nosys */ diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c index 59308a13eb45..87ab73a7f4ba 100644 --- a/sys/compat/freebsd32/freebsd32_sysent.c +++ b/sys/compat/freebsd32/freebsd32_sysent.c @@ -265,7 +265,7 @@ struct sysent freebsd32_sysent[] = { { 0, (sy_call_t *)nosys }, /* 237 = timer_settime */ { 0, (sy_call_t *)nosys }, /* 238 = timer_gettime */ { 0, (sy_call_t *)nosys }, /* 239 = timer_getoverrun */ - { SYF_MPSAFE | AS(nanosleep_args), (sy_call_t *)nanosleep }, /* 240 = nanosleep */ + { SYF_MPSAFE | AS(freebsd32_nanosleep_args), (sy_call_t *)freebsd32_nanosleep }, /* 240 = freebsd32_nanosleep */ { 0, (sy_call_t *)nosys }, /* 241 = nosys */ { 0, (sy_call_t *)nosys }, /* 242 = nosys */ { 0, (sy_call_t *)nosys }, /* 243 = nosys */ diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index 5b0d757a35d8..6ee58758c412 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -352,7 +352,7 @@ 237 UNIMPL timer_settime 238 UNIMPL timer_gettime 239 UNIMPL timer_getoverrun -240 MNOPROTO { int nanosleep(const struct timespec *rqtp, \ +240 MSTD { int freebsd32_nanosleep(const struct timespec *rqtp, \ struct timespec *rmtp); } 241 UNIMPL nosys 242 UNIMPL nosys diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 38a788acfb9b..e08a765e4c05 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -65,8 +65,6 @@ int tz_dsttime; * timers when they expire. */ -static int nanosleep1(struct thread *td, struct timespec *rqt, - struct timespec *rmt); static int settime(struct thread *, struct timeval *); static void timevalfix(struct timeval *); static void no_lease_updatetime(int); @@ -261,8 +259,8 @@ clock_getres(struct thread *td, struct clock_getres_args *uap) static int nanowait; -static int -nanosleep1(struct thread *td, struct timespec *rqt, struct timespec *rmt) +int +kern_nanosleep(struct thread *td, struct timespec *rqt, struct timespec *rmt) { struct timespec ts, ts2, ts3; struct timeval tv; @@ -322,7 +320,7 @@ nanosleep(struct thread *td, struct nanosleep_args *uap) if (uap->rmtp && !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) return (EFAULT); - error = nanosleep1(td, &rqt, &rmt); + error = kern_nanosleep(td, &rqt, &rmt); if (error && uap->rmtp) { int error2; diff --git a/sys/sys/time.h b/sys/sys/time.h index 5371838dd5a0..6e83f5f2e29b 100644 --- a/sys/sys/time.h +++ b/sys/sys/time.h @@ -297,6 +297,10 @@ int ratecheck(struct timeval *, const struct timeval *); void timevaladd(struct timeval *t1, const struct timeval *t2); void timevalsub(struct timeval *t1, const struct timeval *t2); int tvtohz(struct timeval *tv); + +struct thread; +int kern_nanosleep(struct thread *td, struct timespec *rqt, + struct timespec *rmt); #else /* !_KERNEL */ #include