diff options
-rw-r--r-- | sys/compat/linux/linux_futex.c | 6 | ||||
-rw-r--r-- | sys/compat/linux/linux_misc.c | 150 | ||||
-rw-r--r-- | sys/compat/linux/linux_misc.h | 30 | ||||
-rw-r--r-- | sys/compat/linux/linux_time.c | 244 | ||||
-rw-r--r-- | sys/compat/linux/linux_time.h | 31 | ||||
-rw-r--r-- | sys/compat/linux/linux_types.h | 32 | ||||
-rw-r--r-- | sys/compat/linux/syscalls.master | 35 |
7 files changed, 412 insertions, 116 deletions
diff --git a/sys/compat/linux/linux_futex.c b/sys/compat/linux/linux_futex.c index 31fabdadba4..8b92876d083 100644 --- a/sys/compat/linux/linux_futex.c +++ b/sys/compat/linux/linux_futex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_futex.c,v 1.14 2013/04/10 13:17:41 pirofti Exp $ */ +/* $OpenBSD: linux_futex.c,v 1.15 2013/10/25 04:51:38 guenther Exp $ */ /* $NetBSD: linux_futex.c,v 1.26 2010/07/07 01:30:35 chs Exp $ */ /*- @@ -118,7 +118,7 @@ linux_sys_futex(struct proc *p, void *v, register_t *retval) syscallarg(int) val3; } */ *uap = v; - struct l_timespec lts; + struct linux_timespec lts; struct timespec ts = {0, 0}; int error; @@ -128,7 +128,7 @@ linux_sys_futex(struct proc *p, void *v, register_t *retval) <s, sizeof(lts))) != 0) { return error; } - linux_to_native_timespec(&ts, <s); + linux_to_bsd_timespec(&ts, <s); } return linux_do_futex(p, uap, retval, &ts); diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index d78c56f9989..48d41a20c6e 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_misc.c,v 1.81 2013/08/13 05:52:21 guenther Exp $ */ +/* $OpenBSD: linux_misc.c,v 1.82 2013/10/25 04:51:39 guenther Exp $ */ /* $NetBSD: linux_misc.c,v 1.27 1996/05/20 01:59:21 fvdl Exp $ */ /*- @@ -70,6 +70,7 @@ #include <uvm/uvm_extern.h> #include <compat/linux/linux_types.h> +#include <compat/linux/linux_time.h> #include <compat/linux/linux_fcntl.h> #include <compat/linux/linux_misc.h> #include <compat/linux/linux_mmap.h> @@ -83,12 +84,16 @@ #include <compat/common/compat_dir.h> /* linux_misc.c */ -static void bsd_to_linux_statfs(struct statfs *, struct linux_statfs *); +void bsd_to_linux_statfs(const struct statfs *, struct linux_statfs *); +void bsd_to_linux_statfs64(const struct statfs *, struct linux_statfs64 *); int linux_select1(struct proc *, register_t *, int, fd_set *, - fd_set *, fd_set *, struct timeval *); -static int getdents_common(struct proc *, void *, register_t *, int); -static void linux_to_bsd_mmap_args(struct sys_mmap_args *, - const struct linux_sys_mmap2_args *); + fd_set *, fd_set *, struct linux_timeval *); +int getdents_common(struct proc *, void *, register_t *, int); +void linux_to_bsd_mmap_args(struct sys_mmap_args *, + const struct linux_sys_mmap2_args *); +void bsd_to_linux_rusage(struct linux_rusage *, const struct rusage *); +void bsd_to_linux_wstat(int *); + /* * The information on a terminated (or stopped) process needs @@ -109,6 +114,20 @@ bsd_to_linux_wstat(status) } /* + * Convert an rusage to Linux format: small time_t in the timevals + */ +void +bsd_to_linux_rusage(struct linux_rusage *lrup, const struct rusage *rup) +{ + bsd_to_linux_timeval(&lrup->ru_utime, &rup->ru_utime); + bsd_to_linux_timeval(&lrup->ru_utime, &rup->ru_utime); + memcpy(&lrup->ru_maxrss, &rup->ru_maxrss, + offsetof(struct rusage, ru_nivcsw) - + offsetof(struct rusage, ru_maxrss) + + sizeof(lrup->ru_nivcsw)); +} + +/* * waitpid(2). Just forward on to linux_sys_wait4 with a NULL rusage. */ int @@ -133,9 +152,8 @@ linux_sys_waitpid(p, v, retval) } /* - * wait4(2). Passed on to the OpenBSD call, surrounded by code to reserve - * some space for an OpenBSD-style wait status, and converting it to what - * Linux wants. + * wait4(2): handle conversion of the options on entry and status and rusage + * on return. */ int linux_sys_wait4(p, v, retval) @@ -147,17 +165,10 @@ linux_sys_wait4(p, v, retval) syscallarg(int) pid; syscallarg(int *) status; syscallarg(int) options; - syscallarg(struct rusage *) rusage; + syscallarg(struct linux_rusage *) rusage; } */ *uap = v; - struct sys_wait4_args w4a; - int error, *status, tstat, linux_options, options; - caddr_t sg; - - if (SCARG(uap, status) != NULL) { - sg = stackgap_init(p->p_emul); - status = (int *) stackgap_alloc(&sg, sizeof *status); - } else - status = NULL; + struct rusage ru; + int error, status, linux_options, options; linux_options = SCARG(uap, options); options = 0; @@ -172,27 +183,55 @@ linux_sys_wait4(p, v, retval) if (linux_options & LINUX_WAIT4_WCLONE) options |= WALTSIG; - SCARG(&w4a, pid) = SCARG(uap, pid); - SCARG(&w4a, status) = status; - SCARG(&w4a, options) = options; - SCARG(&w4a, rusage) = SCARG(uap, rusage); - - if ((error = sys_wait4(p, &w4a, retval))) + if ((error = dowait4(p, SCARG(uap, pid), + SCARG(uap, status) ? &status : NULL, options, + SCARG(uap, rusage) ? &ru : NULL, retval))) return error; atomic_clearbits_int(&p->p_siglist, sigmask(SIGCHLD)); - if (status != NULL) { - if ((error = copyin(status, &tstat, sizeof tstat))) - return error; + if (SCARG(uap, rusage) != NULL) { + struct linux_rusage lru; - bsd_to_linux_wstat(&tstat); - return copyout(&tstat, SCARG(uap, status), sizeof tstat); + bsd_to_linux_rusage(&lru, &ru); + if ((error = copyout(&lru, SCARG(uap, rusage), sizeof lru))) + return error; + } + if (SCARG(uap, status) != NULL) { + bsd_to_linux_wstat(&status); + return copyout(&status, SCARG(uap, status), sizeof status); } return 0; } +/* + * getrusage(2): convert rusage on return + */ +int +linux_sys_getrusage(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct linux_sys_getrusage_args /* { + syscallarg(int) who; + syscallarg(struct linux_rusage *) rusage; + } */ *uap = v; + struct rusage ru; + int error; + + error = dogetrusage(p, SCARG(uap, who), &ru); + if (error == 0) { + struct linux_rusage lru; + + bsd_to_linux_rusage(&lru, &ru); + error = copyout(&lru, SCARG(uap, rusage), sizeof lru); + } + return error; +} + + int linux_sys_setresgid16(p, v, retval) struct proc *p; @@ -365,8 +404,8 @@ linux_sys_time(p, v, retval) * the length of a name in a dir entry in a field, which * we fake (probably the wrong way). */ -static void -bsd_to_linux_statfs(struct statfs *bsp, struct linux_statfs *lsp) +void +bsd_to_linux_statfs(const struct statfs *bsp, struct linux_statfs *lsp) { /* @@ -447,8 +486,8 @@ linux_sys_statfs(p, v, retval) return copyout((caddr_t) <mp, (caddr_t) SCARG(uap, sp), sizeof ltmp); } -static void -bsd_to_linux_statfs64(struct statfs *bsp, struct linux_statfs64 *lsp) +void +bsd_to_linux_statfs64(const struct statfs *bsp, struct linux_statfs64 *lsp) { /* @@ -763,7 +802,7 @@ linux_sys_mmap2(p, v, retval) return sys_mmap(p, &cma, retval); } -static void +void linux_to_bsd_mmap_args(cma, uap) struct sys_mmap_args *cma; const struct linux_sys_mmap2_args *uap; @@ -853,7 +892,7 @@ linux_sys_times(p, v, retval) register_t *retval; { struct linux_sys_times_args /* { - syscallarg(struct times *) tms; + syscallarg(struct linux_tms *) tms; } */ *uap = v; struct timeval t, ut, st; struct linux_tms ltms; @@ -1135,7 +1174,7 @@ linux_sys_getdents(p, v, retval) return getdents_common(p, v, retval, 0); } -static int +int getdents_common(p, v, retval, is64bit) struct proc *p; void *v; @@ -1222,7 +1261,7 @@ linux_sys_select(p, v, retval) syscallarg(fd_set *) readfds; syscallarg(fd_set *) writefds; syscallarg(fd_set *) exceptfds; - syscallarg(struct timeval *) timeout; + syscallarg(struct linux_timeval *) timeout; } */ *uap = v; return linux_select1(p, retval, SCARG(uap, nfds), SCARG(uap, readfds), @@ -1236,14 +1275,11 @@ linux_sys_select(p, v, retval) * 2) select never returns ERESTART on Linux, always return EINTR */ int -linux_select1(p, retval, nfds, readfds, writefds, exceptfds, timeout) - struct proc *p; - register_t *retval; - int nfds; - fd_set *readfds, *writefds, *exceptfds; - struct timeval *timeout; +linux_select1(struct proc *p, register_t *retval, int nfds, fd_set *readfds, + fd_set *writefds, fd_set *exceptfds, struct linux_timeval *timeout) { struct sys_select_args bsa; + struct linux_timeval lutv; struct timeval tv0, tv1, utv, *tvp; caddr_t sg; int error; @@ -1252,22 +1288,20 @@ linux_select1(p, retval, nfds, readfds, writefds, exceptfds, timeout) SCARG(&bsa, in) = readfds; SCARG(&bsa, ou) = writefds; SCARG(&bsa, ex) = exceptfds; - SCARG(&bsa, tv) = timeout; /* * Store current time for computation of the amount of * time left. */ if (timeout) { - if ((error = copyin(timeout, &utv, sizeof(utv)))) + if ((error = copyin(timeout, &lutv, sizeof(lutv)))) return error; + linux_to_bsd_timeval(&utv, &lutv); if (itimerfix(&utv)) { /* * The timeval was invalid. Convert it to something * valid that will act as it does under Linux. */ - sg = stackgap_init(p->p_emul); - tvp = stackgap_alloc(&sg, sizeof(utv)); utv.tv_sec += utv.tv_usec / 1000000; utv.tv_usec %= 1000000; if (utv.tv_usec < 0) { @@ -1276,12 +1310,16 @@ linux_select1(p, retval, nfds, readfds, writefds, exceptfds, timeout) } if (utv.tv_sec < 0) timerclear(&utv); - if ((error = copyout(&utv, tvp, sizeof(utv)))) - return error; - SCARG(&bsa, tv) = tvp; } + + sg = stackgap_init(p->p_emul); + tvp = stackgap_alloc(&sg, sizeof(utv)); + if ((error = copyout(&utv, tvp, sizeof(utv)))) + return error; + SCARG(&bsa, tv) = tvp; microtime(&tv0); - } + } else + SCARG(&bsa, tv) = NULL; error = sys_select(p, &bsa, retval); if (error) { @@ -1291,7 +1329,8 @@ linux_select1(p, retval, nfds, readfds, writefds, exceptfds, timeout) */ if (error == ERESTART) error = EINTR; - return error; + else if (error != EINTR) + return error; } if (timeout) { @@ -1309,11 +1348,12 @@ linux_select1(p, retval, nfds, readfds, writefds, exceptfds, timeout) timerclear(&utv); } else timerclear(&utv); - if ((error = copyout(&utv, timeout, sizeof(utv)))) + bsd_to_linux_timeval(&lutv, &utv); /* can't fail */ + if ((error = copyout(&lutv, timeout, sizeof(lutv)))) return error; } - return 0; + return (error); } /* diff --git a/sys/compat/linux/linux_misc.h b/sys/compat/linux/linux_misc.h index a556cba3159..c4e5924d4c8 100644 --- a/sys/compat/linux/linux_misc.h +++ b/sys/compat/linux/linux_misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_misc.h,v 1.6 2011/12/14 08:33:18 robert Exp $ */ +/* $OpenBSD: linux_misc.h,v 1.7 2013/10/25 04:51:39 guenther Exp $ */ /* $NetBSD: linux_misc.h,v 1.3 1999/05/13 00:31:57 thorpej Exp $ */ /*- @@ -64,6 +64,26 @@ struct linux_sysinfo { char _f[20-2*sizeof(long)-sizeof(int)]; }; +struct linux_rusage { + struct linux_timeval ru_utime; /* user time used */ + struct linux_timeval ru_stime; /* system time used */ + long ru_maxrss; /* max resident set size */ + long ru_ixrss; /* integral shared text memory size */ + long ru_idrss; /* integral unshared data " */ + long ru_isrss; /* integral unshared stack " */ + long ru_minflt; /* page reclaims */ + long ru_majflt; /* page faults */ + long ru_nswap; /* swaps */ + long ru_inblock; /* block input operations */ + long ru_oublock; /* block output operations */ + long ru_msgsnd; /* messages sent */ + long ru_msgrcv; /* messages received */ + long ru_nsignals; /* signals received */ + long ru_nvcsw; /* voluntary context switches */ + long ru_nivcsw; /* involuntary " */ +}; + + /* * Options passed to the Linux wait4() system call. */ @@ -71,12 +91,4 @@ struct linux_sysinfo { #define LINUX_WAIT4_WUNTRACED 0x00000002 #define LINUX_WAIT4_WCLONE 0x80000000 -#ifdef _KERNEL -__BEGIN_DECLS -void bsd_to_linux_wstat(int *); -int linux_select1(struct proc *, register_t *, int, fd_set *, fd_set *, - fd_set *, struct timeval *); -__END_DECLS -#endif /* !_KERNEL */ - #endif /* !_LINUX_MISC_H_ */ diff --git a/sys/compat/linux/linux_time.c b/sys/compat/linux/linux_time.c index 5f66d7d3da8..f60a2ff6926 100644 --- a/sys/compat/linux/linux_time.c +++ b/sys/compat/linux/linux_time.c @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_time.c,v 1.4 2013/05/10 10:31:16 pirofti Exp $ */ +/* $OpenBSD: linux_time.c,v 1.5 2013/10/25 04:51:39 guenther Exp $ */ /* * Copyright (c) 2010, 2011 Paul Irofti <pirofti@openbsd.org> * @@ -23,6 +23,7 @@ #include <sys/time.h> #include <sys/systm.h> #include <sys/proc.h> +#include <sys/kernel.h> #include <sys/syscallargs.h> @@ -43,11 +44,10 @@ #define LINUX_CLOCK_MONOTONIC 1 #define LINUX_CLOCK_PROCESS_CPUTIME_ID 2 #define LINUX_CLOCK_THREAD_CPUTIME_ID 3 -#define LINUX_CLOCK_REALTIME_HR 4 -#define LINUX_CLOCK_MONOTONIC_HR 5 + int -native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp) +bsd_to_linux_timespec(struct linux_timespec *ltp, const struct timespec *ntp) { if (ntp->tv_sec > LINUX_TIME_MAX) return EOVERFLOW; @@ -57,14 +57,34 @@ native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp) } void -linux_to_native_timespec(struct timespec *ntp, struct l_timespec *ltp) +linux_to_bsd_timespec(struct timespec *ntp, const struct linux_timespec *ltp) { ntp->tv_sec = ltp->tv_sec; ntp->tv_nsec = ltp->tv_nsec; } int -linux_to_native_clockid(clockid_t *n, clockid_t l) +bsd_to_linux_itimerval(struct linux_itimerval *ltp, + const struct itimerval *ntp) +{ + int error; + + error = bsd_to_linux_timeval(<p->it_interval, &ntp->it_interval); + if (error) + return (error); + return (bsd_to_linux_timeval(<p->it_value, &ntp->it_value)); +} + +void +linux_to_bsd_itimerval(struct itimerval *ntp, + const struct linux_itimerval *ltp) +{ + linux_to_bsd_timeval(&ntp->it_interval, <p->it_interval); + linux_to_bsd_timeval(&ntp->it_value, <p->it_value); +} + +int +linux_to_bsd_clockid(clockid_t *n, clockid_t l) { switch (l) { case LINUX_CLOCK_REALTIME: @@ -74,9 +94,11 @@ linux_to_native_clockid(clockid_t *n, clockid_t l) *n = CLOCK_MONOTONIC; break; case LINUX_CLOCK_PROCESS_CPUTIME_ID: + *n = CLOCK_PROCESS_CPUTIME_ID; + break; case LINUX_CLOCK_THREAD_CPUTIME_ID: - case LINUX_CLOCK_REALTIME_HR: - case LINUX_CLOCK_MONOTONIC_HR: + *n = CLOCK_THREAD_CPUTIME_ID; + break; default: return (EINVAL); break; @@ -89,35 +111,34 @@ int linux_sys_clock_getres(struct proc *p, void *v, register_t *retval) { struct linux_sys_clock_getres_args *uap = v; - struct sys_clock_getres_args cgr; - + struct linux_timespec ltp; + clockid_t clockid; int error; if (SCARG(uap, tp) == NULL) return 0; - error = linux_to_native_clockid(&SCARG(&cgr, clock_id), - SCARG(uap, which)); + error = linux_to_bsd_clockid(&clockid, SCARG(uap, which)); if (error != 0) return error; - SCARG(&cgr, tp) = (struct timespec *)SCARG(uap, tp); - return sys_clock_getres(p, &cgr, retval); + /* ahhh, just give a good guess */ + ltp.tv_sec = 0; + ltp.tv_nsec = 1000000000 / hz; + + return (copyout(<p, SCARG(uap, tp), sizeof ltp)); } int linux_sys_clock_gettime(struct proc *p, void *v, register_t *retval) { struct linux_sys_clock_gettime_args *uap = v; - - clockid_t clockid = 0; - struct timespec tp; - struct l_timespec ltp; - + struct linux_timespec ltp; + clockid_t clockid; int error; - error = linux_to_native_clockid(&clockid, SCARG(uap, which)); + error = linux_to_bsd_clockid(&clockid, SCARG(uap, which)); if (error != 0) return error; @@ -125,9 +146,190 @@ linux_sys_clock_gettime(struct proc *p, void *v, register_t *retval) if (error != 0) return error; - error = native_to_linux_timespec(<p, &tp); + error = bsd_to_linux_timespec(<p, &tp); if (error != 0) return error; return (copyout(<p, SCARG(uap, tp), sizeof ltp)); } + +int +linux_sys_nanosleep(struct proc *p, void *v, register_t *retval) +{ + static int nanowait; + struct linux_sys_nanosleep_args /* { + syscallarg(const struct linux_timespec *) rqtp; + syscallarg(struct linux_timespec *) rmtp; + } */ *uap = v; + struct linux_timespec lts; + struct timespec rqt, rmt; + struct timespec sts, ets; + struct linux_timespec *rmtp; + struct timeval tv; + int error, error1; + + rmtp = SCARG(uap, rmtp); + error = copyin(SCARG(uap, rqtp), <s, sizeof(lts)); + if (error) + return (error); + linux_to_bsd_timespec(&rqt, <s); + + TIMESPEC_TO_TIMEVAL(&tv, &rqt); + if (itimerfix(&tv)) + return (EINVAL); + + if (rmtp) + getnanouptime(&sts); + + error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep", + MAX(1, tvtohz(&tv))); + if (error == ERESTART) + error = EINTR; + if (error == EWOULDBLOCK) + error = 0; + + if (rmtp) { + getnanouptime(&ets); + + timespecsub(&ets, &sts, &sts); + timespecsub(&rqt, &sts, &rmt); + + if (rmt.tv_sec < 0) + timespecclear(&rmt); + + if ((error1 = bsd_to_linux_timespec(<s, &rmt)) || + (error1 = copyout(<s, rmtp, sizeof(lts)))) + error = error1; + } + + return error; +} + +int +linux_sys_gettimeofday(struct proc *p, void *v, register_t *retval) +{ + struct linux_sys_gettimeofday_args /* { + syscallarg(struct linux_timeval *) tp; + syscallarg(struct timezone *) tzp; + } */ *uap = v; + struct timeval atv; + struct linux_timeval latv; + struct linux_timeval *tp; + struct timezone *tzp; + int error = 0; + + tp = SCARG(uap, tp); + tzp = SCARG(uap, tzp); + + if (tp) { + microtime(&atv); + if ((error = bsd_to_linux_timeval(&latv, &atv)) || + (error = copyout(&latv, tp, sizeof (latv)))) + return (error); + } + if (tzp) + error = copyout(&tz, tzp, sizeof (tz)); + return (error); +} + +int +linux_sys_getitimer(struct proc *p, void *v, register_t *retval) +{ + struct linux_sys_getitimer_args /* { + syscallarg(int) which; + syscallarg(struct linux_itimerval *) itv; + } */ *uap = v; + struct itimerval aitv; + struct linux_itimerval laitv; + int s, which, error; + + which = SCARG(uap, which); + + if (which < ITIMER_REAL || which > ITIMER_PROF) + return (EINVAL); + s = splclock(); + aitv = p->p_p->ps_timer[which]; + + if (which == ITIMER_REAL) { + struct timeval now; + + getmicrouptime(&now); + /* + * Convert from absolute to relative time in .it_value + * part of real time timer. If time for real time timer + * has passed return 0, else return difference between + * current time and time for the timer to go off. + */ + if (timerisset(&aitv.it_value)) { + if (timercmp(&aitv.it_value, &now, <)) + timerclear(&aitv.it_value); + else + timersub(&aitv.it_value, &now, + &aitv.it_value); + } + } + splx(s); + if ((error = bsd_to_linux_itimerval(&laitv, &aitv))) + return error; + return (copyout(&laitv, SCARG(uap, itv), sizeof(laitv))); +} + +int +linux_sys_setitimer(struct proc *p, void *v, register_t *retval) +{ + struct linux_sys_setitimer_args /* { + syscallarg(int) which; + syscallarg(const struct linux_itimerval *) itv; + syscallarg(struct linux_itimerval *) oitv; + } */ *uap = v; + struct linux_sys_getitimer_args getargs; + struct itimerval aitv; + struct linux_itimerval laitv; + const struct linux_itimerval *itvp; + struct linux_itimerval *oitv; + struct process *pr = p->p_p; + int error; + int timo; + int which; + + which = SCARG(uap, which); + itvp = SCARG(uap, itv); + oitv = SCARG(uap, oitv); + + if (which < ITIMER_REAL || which > ITIMER_PROF) + return (EINVAL); + if (itvp && (error = copyin(itvp, &laitv, sizeof(laitv)))) + return (error); + if (oitv != NULL) { + SCARG(&getargs, which) = which; + SCARG(&getargs, itv) = oitv; + if ((error = linux_sys_getitimer(p, &getargs, retval))) + return (error); + } + if (itvp == 0) + return (0); + linux_to_bsd_itimerval(&aitv, &laitv); + if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval)) + return (EINVAL); + if (which == ITIMER_REAL) { + struct timeval ctv; + + timeout_del(&pr->ps_realit_to); + getmicrouptime(&ctv); + if (timerisset(&aitv.it_value)) { + timo = tvtohz(&aitv.it_value); + timeout_add(&pr->ps_realit_to, timo); + timeradd(&aitv.it_value, &ctv, &aitv.it_value); + } + pr->ps_timer[ITIMER_REAL] = aitv; + } else { + int s; + + itimerround(&aitv.it_interval); + s = splclock(); + pr->ps_timer[which] = aitv; + splx(s); + } + + return (0); +} diff --git a/sys/compat/linux/linux_time.h b/sys/compat/linux/linux_time.h index 64ab0dda245..875d3b1adf9 100644 --- a/sys/compat/linux/linux_time.h +++ b/sys/compat/linux/linux_time.h @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_time.h,v 1.3 2013/05/10 10:31:16 pirofti Exp $ */ +/* $OpenBSD: linux_time.h,v 1.4 2013/10/25 04:51:39 guenther Exp $ */ /* * Copyright (c) 2011 Paul Irofti <pirofti@openbsd.org> * @@ -18,8 +18,31 @@ #ifndef _LINUX_TIME_H_ #define _LINUX_TIME_H_ -int native_to_linux_timespec(struct l_timespec *, struct timespec *); -void linux_to_native_timespec(struct timespec *, struct l_timespec *); -int linux_to_native_clockid(clockid_t *, clockid_t); +/* BSD to linux can fail with EOVERFLOW */ +int bsd_to_linux_timespec(struct linux_timespec *, + const struct timespec *); +int bsd_to_linux_itimerval(struct linux_itimerval *, + const struct itimerval *); + +/* linux to BSD can't fail for time_t-based stuff, but can for clockid_t */ +void linux_to_bsd_timespec(struct timespec *, + const struct linux_timespec *); +void linux_to_bsd_itimerval(struct itimerval *, + const struct linux_itimerval *); +int linux_to_bsd_clockid(clockid_t *, clockid_t); + + +/* the timespec conversion functions also handle timeval */ +static inline int +bsd_to_linux_timeval(struct linux_timeval *ltp, const struct timeval *ntp) +{ + return (bsd_to_linux_timespec((void *)ltp, (const void *)ntp)); +} +static inline void +linux_to_bsd_timeval(struct timeval *ntp, const struct linux_timeval *ltp) +{ + linux_to_bsd_timespec((void *)ntp, (const void *)ltp); +} + #endif diff --git a/sys/compat/linux/linux_types.h b/sys/compat/linux/linux_types.h index d700a04b906..9f477c780c4 100644 --- a/sys/compat/linux/linux_types.h +++ b/sys/compat/linux/linux_types.h @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_types.h,v 1.12 2013/05/10 10:31:16 pirofti Exp $ */ +/* $OpenBSD: linux_types.h,v 1.13 2013/10/25 04:51:39 guenther Exp $ */ /* $NetBSD: linux_types.h,v 1.5 1996/05/20 01:59:28 fvdl Exp $ */ /* @@ -68,6 +68,27 @@ typedef int linux_pid_t; #define LINUX_FSTYPE_UDF 0x15013346 #define LINUX_FSTYPE_AFS 0x5346414f +/* + * Linux version of time-based structures, passed to many system calls + */ +struct linux_timespec { + linux_time_t tv_sec; + long tv_nsec; +}; + +struct linux_timeval { + linux_time_t tv_sec; + long tv_usec; +}; + +struct linux_itimerval { + struct linux_timeval it_interval; + struct linux_timeval it_value; +}; + +/* + * Passed to the statfs(2) system call family + */ struct linux_statfs { long l_ftype; long l_fbsize; @@ -95,7 +116,7 @@ struct linux_statfs64 { }; /* - * Structure for uname(2) + * Passed to the uname(2) system call */ struct linux_utsname { char l_sysname[65]; @@ -142,7 +163,7 @@ struct linux_select { fd_set *readfds; fd_set *writefds; fd_set *exceptfds; - struct timeval *timeout; + struct linux_timeval *timeout; }; struct linux_stat { @@ -225,9 +246,4 @@ struct linux_stat64 { linux_ino64_t lst_ino; }; -struct l_timespec { - linux_time_t tv_sec; - long tv_nsec; -}; - #endif /* !_LINUX_TYPES_H_ */ diff --git a/sys/compat/linux/syscalls.master b/sys/compat/linux/syscalls.master index 911efc9a464..c8eecd5dd2f 100644 --- a/sys/compat/linux/syscalls.master +++ b/sys/compat/linux/syscalls.master @@ -1,4 +1,4 @@ - $OpenBSD: syscalls.master,v 1.72 2013/08/13 05:52:22 guenther Exp $ + $OpenBSD: syscalls.master,v 1.73 2013/10/25 04:51:39 guenther Exp $ ; $NetBSD: syscalls.master,v 1.15 1995/12/18 14:35:10 fvdl Exp $ ; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 @@ -98,7 +98,7 @@ 40 STD { int linux_sys_rmdir(char *path); } 41 NOARGS { int sys_dup(u_int fd); } 42 NOARGS { int sys_pipe(int *fdp); } -43 STD { int linux_sys_times(struct times *tms); } +43 STD { int linux_sys_times(struct linux_tms *tms); } 44 STD { int linux_sys_prof(void); } 45 STD { int linux_sys_brk(char *nsize); } 46 NOARGS linux_setgid16 { int sys_setgid(gid_t gid); } @@ -143,8 +143,9 @@ struct linux_rlimit *rlp); } 76 STD { int linux_sys_getrlimit(u_int which, \ struct linux_rlimit *rlp); } -77 NOARGS { int sys_getrusage(int who, struct rusage *rusage); } -78 NOARGS { int t32_sys_gettimeofday(struct timeval *tp, \ +77 STD { int linux_sys_getrusage(int who, \ + struct linux_rusage *rusage); } +78 STD { int linux_sys_gettimeofday(struct linux_timeval *tp, \ struct timezone *tzp); } 79 NOARGS { int sys_settimeofday(struct timeval *tp, \ struct timezone *tzp); } @@ -185,10 +186,11 @@ #endif 102 STD { int linux_sys_socketcall(int what, void *args); } 103 STD { int linux_sys_klog(void); } -104 NOARGS { int sys_setitimer(u_int which, \ - struct itimerval *itv, struct itimerval *oitv); } -105 NOARGS { int sys_getitimer(u_int which, \ - struct itimerval *itv); } +104 STD { int linux_sys_setitimer(u_int which, \ + struct linux_itimerval *itv, \ + struct linux_itimerval *oitv); } +105 STD { int linux_sys_getitimer(u_int which, \ + struct linux_itimerval *itv); } 106 STD { int linux_sys_stat(char *path, \ struct linux_stat *sp); } 107 STD { int linux_sys_lstat(char *path, \ @@ -204,9 +206,9 @@ 112 STD { int linux_sys_idle(void); } 113 STD { int linux_sys_vm86old(void); } 114 STD { int linux_sys_wait4(int pid, int *status, \ - int options, struct rusage *rusage); } + int options, struct linux_rusage *rusage); } 115 STD { int linux_sys_swapoff(void); } -116 STD { int linux_sys_sysinfo(struct linux_sys_sysinfo_args *sysinfo); } +116 STD { int linux_sys_sysinfo(struct linux_sysinfo *sysinfo); } 117 STD { int linux_sys_ipc(int what, int a1, int a2, int a3, \ caddr_t ptr); } 118 NOARGS { int sys_fsync(int fd); } @@ -244,7 +246,7 @@ unsigned count); } 142 STD { int linux_sys_select(int nfds, fd_set *readfds, \ fd_set *writefds, fd_set *exceptfds, \ - struct timeval *timeout); } + struct linux_timeval *timeout); } 143 NOARGS { int sys_flock(int fd, int how); } 144 NOARGS { int sys_msync(void *addr, int len, int fl); } 145 NOARGS { int sys_readv(int fd, struct iovec *iovp, \ @@ -269,8 +271,9 @@ 159 STD { int linux_sys_sched_get_priority_max(int policy); } 160 STD { int linux_sys_sched_get_priority_min(int policy); } 161 STD { int linux_sys_sched_rr_get_interval(void); } -162 NOARGS { int t32_sys_nanosleep(const struct timespec32 *rqtp, \ - struct timespec32 *rmtp); } +162 STD { int linux_sys_nanosleep( \ + const struct linux_timespec *rqtp, \ + struct linux_timespec *rmtp); } 163 STD { int linux_sys_mremap(void *old_address, \ size_t old_size, size_t new_size, long flags); } 164 STD { int linux_sys_setresuid16(u_int16_t ruid, \ @@ -383,7 +386,7 @@ 238 UNIMPL linux_sys_tkill 239 UNIMPL linux_sys_sendfile64 240 STD { int linux_sys_futex(int *uaddr, int op, int val, \ - const struct linux_timespec *timeout, \ + const struct linux_timespec *timeout, \ int *uaddr2, int val3); } 241 UNIMPL linux_sys_sched_setaffinity 242 UNIMPL linux_sys_sched_getaffinity @@ -412,9 +415,9 @@ 263 UNIMPL linux_sys_timer_delete 264 UNIMPL linux_sys_clock_settime 265 STD { int linux_sys_clock_gettime(clockid_t which, \ - struct l_timespec *tp); } + struct linux_timespec *tp); } 266 STD { int linux_sys_clock_getres(clockid_t which, \ - struct l_timespec *tp); } + struct linux_timespec *tp); } 267 UNIMPL linux_sys_clock_nanosleep 268 STD { int linux_sys_statfs64(char *path, \ struct linux_statfs64 *sp); } |