The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/netbsd32/netbsd32_time.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: netbsd32_time.c,v 1.34 2008/07/15 16:18:08 christos Exp $      */
    2 
    3 /*
    4  * Copyright (c) 1998, 2001 Matthew R. Green
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
   23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __KERNEL_RCSID(0, "$NetBSD: netbsd32_time.c,v 1.34 2008/07/15 16:18:08 christos Exp $");
   31 
   32 #if defined(_KERNEL_OPT)
   33 #include "opt_ntp.h"
   34 #include "opt_compat_netbsd.h"
   35 #endif
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/mount.h>
   40 #include <sys/time.h>
   41 #include <sys/timex.h>
   42 #include <sys/timevar.h>
   43 #include <sys/timetc.h>
   44 #include <sys/proc.h>
   45 #include <sys/pool.h>
   46 #include <sys/resourcevar.h>
   47 #include <sys/dirent.h>
   48 #include <sys/kauth.h>
   49 
   50 #include <compat/netbsd32/netbsd32.h>
   51 #include <compat/netbsd32/netbsd32_syscallargs.h>
   52 #include <compat/netbsd32/netbsd32_conv.h>
   53 
   54 #ifdef NTP
   55 
   56 int
   57 netbsd32_ntp_gettime(struct lwp *l, const struct netbsd32_ntp_gettime_args *uap, register_t *retval)
   58 {
   59         /* {
   60                 syscallarg(netbsd32_ntptimevalp_t) ntvp;
   61         } */
   62         struct netbsd32_ntptimeval ntv32;
   63         struct ntptimeval ntv;
   64         int error = 0;
   65 
   66         if (SCARG_P32(uap, ntvp)) {
   67                 ntp_gettime(&ntv);
   68 
   69                 ntv32.time.tv_sec = ntv.time.tv_sec;
   70                 ntv32.time.tv_nsec = ntv.time.tv_nsec;
   71                 ntv32.maxerror = (netbsd32_long)ntv.maxerror;
   72                 ntv32.esterror = (netbsd32_long)ntv.esterror;
   73                 ntv32.tai = (netbsd32_long)ntv.tai;
   74                 ntv32.time_state = ntv.time_state;
   75                 error = copyout(&ntv32, SCARG_P32(uap, ntvp), sizeof(ntv32));
   76         }
   77         if (!error) {
   78                 *retval = ntp_timestatus();
   79         }
   80 
   81         return (error);
   82 }
   83 
   84 #ifdef COMPAT_30
   85 int
   86 compat_30_netbsd32_ntp_gettime(struct lwp *l, const struct compat_30_netbsd32_ntp_gettime_args *uap, register_t *retval)
   87 {
   88         /* {
   89                 syscallarg(netbsd32_ntptimevalp_t) ntvp;
   90         } */
   91         struct netbsd32_ntptimeval30 ntv32;
   92         struct ntptimeval ntv;
   93         int error = 0;
   94 
   95         if (SCARG_P32(uap, ntvp)) {
   96                 ntp_gettime(&ntv);
   97 
   98                 ntv32.time.tv_sec = ntv.time.tv_sec;
   99                 ntv32.time.tv_usec = ntv.time.tv_nsec / 1000;
  100                 ntv32.maxerror = (netbsd32_long)ntv.maxerror;
  101                 ntv32.esterror = (netbsd32_long)ntv.esterror;
  102                 error = copyout(&ntv32, SCARG_P32(uap, ntvp), sizeof(ntv32));
  103         }
  104         if (!error) {
  105                 *retval = ntp_timestatus();
  106         }
  107 
  108         return (error);
  109 }
  110 #endif
  111 
  112 int
  113 netbsd32_ntp_adjtime(struct lwp *l, const struct netbsd32_ntp_adjtime_args *uap, register_t *retval)
  114 {
  115         /* {
  116                 syscallarg(netbsd32_timexp_t) tp;
  117         } */
  118         struct netbsd32_timex ntv32;
  119         struct timex ntv;
  120         int error = 0;
  121         int modes;
  122 
  123         if ((error = copyin(SCARG_P32(uap, tp), &ntv32, sizeof(ntv32))))
  124                 return (error);
  125 
  126         netbsd32_to_timex(&ntv32, &ntv);
  127 
  128         /*
  129          * Update selected clock variables - only the superuser can
  130          * change anything. Note that there is no error checking here on
  131          * the assumption the superuser should know what it is doing.
  132          */
  133         modes = ntv.modes;
  134         if (modes != 0 && (error = kauth_authorize_system(l->l_cred,
  135             KAUTH_SYSTEM_TIME, KAUTH_REQ_SYSTEM_TIME_NTPADJTIME, NULL, NULL,
  136             NULL)))
  137                 return (error);
  138 
  139         ntp_adjtime1(&ntv);
  140 
  141         netbsd32_from_timex(&ntv, &ntv32);
  142         error = copyout(&ntv32, SCARG_P32(uap, tp), sizeof(ntv32));
  143         if (!error) {
  144                 *retval = ntp_timestatus();
  145         }
  146         return error;
  147 }
  148 #else /* !NTP */
  149 int
  150 netbsd32_ntp_gettime(struct lwp *l, const struct netbsd32_ntp_gettime_args *uap, register_t *retval)
  151 {
  152 
  153         return (ENOSYS);
  154 }
  155 
  156 #ifdef COMPAT_30
  157 int
  158 compat_30_netbsd32_ntp_gettime(struct lwp *l, const struct compat_30_netbsd32_ntp_gettime_args *uap, register_t *retval)
  159 {
  160 
  161         return (ENOSYS);
  162 }
  163 #endif
  164 
  165 int
  166 netbsd32_ntp_adjtime(struct lwp *l, const struct netbsd32_ntp_adjtime_args *uap, register_t *retval)
  167 {
  168 
  169         return (ENOSYS);
  170 }
  171 #endif /* NTP */
  172 
  173 int
  174 netbsd32_setitimer(struct lwp *l, const struct netbsd32_setitimer_args *uap, register_t *retval)
  175 {
  176         /* {
  177                 syscallarg(int) which;
  178                 syscallarg(const netbsd32_itimervalp_t) itv;
  179                 syscallarg(netbsd32_itimervalp_t) oitv;
  180         } */
  181         struct proc *p = l->l_proc;
  182         struct netbsd32_itimerval s32it, *itv32;
  183         int which = SCARG(uap, which);
  184         struct netbsd32_getitimer_args getargs;
  185         struct itimerval aitv;
  186         int error;
  187 
  188         if ((u_int)which > ITIMER_PROF)
  189                 return (EINVAL);
  190         itv32 = SCARG_P32(uap, itv);
  191         if (itv32) {
  192                 if ((error = copyin(itv32, &s32it, sizeof(s32it))))
  193                         return (error);
  194                 netbsd32_to_itimerval(&s32it, &aitv);
  195         }
  196         if (SCARG_P32(uap, oitv) != 0) {
  197                 SCARG(&getargs, which) = which;
  198                 SCARG(&getargs, itv) = SCARG(uap, oitv);
  199                 if ((error = netbsd32_getitimer(l, &getargs, retval)) != 0)
  200                         return (error);
  201         }
  202         if (itv32 == 0)
  203                 return 0;
  204 
  205         return dosetitimer(p, which, &aitv);
  206 }
  207 
  208 int
  209 netbsd32_getitimer(struct lwp *l, const struct netbsd32_getitimer_args *uap, register_t *retval)
  210 {
  211         /* {
  212                 syscallarg(int) which;
  213                 syscallarg(netbsd32_itimervalp_t) itv;
  214         } */
  215         struct proc *p = l->l_proc;
  216         struct netbsd32_itimerval s32it;
  217         struct itimerval aitv;
  218         int error;
  219 
  220         error = dogetitimer(p, SCARG(uap, which), &aitv);
  221         if (error)
  222                 return error;
  223 
  224         netbsd32_from_itimerval(&aitv, &s32it);
  225         return copyout(&s32it, SCARG_P32(uap, itv), sizeof(s32it));
  226 }
  227 
  228 int
  229 netbsd32_gettimeofday(struct lwp *l, const struct netbsd32_gettimeofday_args *uap, register_t *retval)
  230 {
  231         /* {
  232                 syscallarg(netbsd32_timevalp_t) tp;
  233                 syscallarg(netbsd32_timezonep_t) tzp;
  234         } */
  235         struct timeval atv;
  236         struct netbsd32_timeval tv32;
  237         int error = 0;
  238         struct netbsd32_timezone tzfake;
  239 
  240         if (SCARG_P32(uap, tp)) {
  241                 microtime(&atv);
  242                 netbsd32_from_timeval(&atv, &tv32);
  243                 error = copyout(&tv32, SCARG_P32(uap, tp), sizeof(tv32));
  244                 if (error)
  245                         return (error);
  246         }
  247         if (SCARG_P32(uap, tzp)) {
  248                 /*
  249                  * NetBSD has no kernel notion of time zone, so we just
  250                  * fake up a timezone struct and return it if demanded.
  251                  */
  252                 tzfake.tz_minuteswest = 0;
  253                 tzfake.tz_dsttime = 0;
  254                 error = copyout(&tzfake, SCARG_P32(uap, tzp), sizeof(tzfake));
  255         }
  256         return (error);
  257 }
  258 
  259 int
  260 netbsd32_settimeofday(struct lwp *l, const struct netbsd32_settimeofday_args *uap, register_t *retval)
  261 {
  262         /* {
  263                 syscallarg(const netbsd32_timevalp_t) tv;
  264                 syscallarg(const netbsd32_timezonep_t) tzp;
  265         } */
  266         struct netbsd32_timeval atv32;
  267         struct timeval atv;
  268         struct timespec ats;
  269         int error;
  270         struct proc *p = l->l_proc;
  271 
  272         /* Verify all parameters before changing time. */
  273 
  274         /*
  275          * NetBSD has no kernel notion of time zone, and only an
  276          * obsolete program would try to set it, so we log a warning.
  277          */
  278         if (SCARG_P32(uap, tzp))
  279                 printf("pid %d attempted to set the "
  280                     "(obsolete) kernel time zone\n", p->p_pid);
  281 
  282         if (SCARG_P32(uap, tv) == 0)
  283                 return 0;
  284 
  285         if ((error = copyin(SCARG_P32(uap, tv), &atv32, sizeof(atv32))) != 0)
  286                 return error;
  287 
  288         netbsd32_to_timeval(&atv32, &atv);
  289         TIMEVAL_TO_TIMESPEC(&atv, &ats);
  290         return settime(p, &ats);
  291 }
  292 
  293 int
  294 netbsd32_adjtime(struct lwp *l, const struct netbsd32_adjtime_args *uap, register_t *retval)
  295 {
  296         /* {
  297                 syscallarg(const netbsd32_timevalp_t) delta;
  298                 syscallarg(netbsd32_timevalp_t) olddelta;
  299         } */
  300         struct netbsd32_timeval atv;
  301         int error;
  302 
  303         extern int time_adjusted;     /* in kern_ntptime.c */
  304         extern int64_t time_adjtime;  /* in kern_ntptime.c */
  305 
  306         if ((error = kauth_authorize_system(l->l_cred,
  307             KAUTH_SYSTEM_TIME, KAUTH_REQ_SYSTEM_TIME_ADJTIME, NULL, NULL,
  308             NULL)) != 0)
  309                 return (error);
  310 
  311         if (SCARG_P32(uap, olddelta)) {
  312                 atv.tv_sec = time_adjtime / 1000000;
  313                 atv.tv_usec = time_adjtime % 1000000;
  314                 if (atv.tv_usec < 0) {
  315                         atv.tv_usec += 1000000;
  316                         atv.tv_sec--;
  317                 }
  318                 (void) copyout(&atv,
  319                                SCARG_P32(uap, olddelta), 
  320                                sizeof(atv));
  321                 if (error)
  322                         return (error);
  323         }
  324         
  325         if (SCARG_P32(uap, delta)) {
  326                 error = copyin(SCARG_P32(uap, delta), &atv,
  327                                sizeof(struct timeval));
  328                 if (error)
  329                         return (error);
  330 
  331                 time_adjtime = (int64_t)atv.tv_sec * 1000000 + atv.tv_usec;
  332 
  333                 if (time_adjtime)
  334                         /* We need to save the system time during shutdown */
  335                         time_adjusted |= 1;
  336         }
  337 
  338         return (0);
  339 }
  340 
  341 int
  342 netbsd32_clock_gettime(struct lwp *l, const struct netbsd32_clock_gettime_args *uap, register_t *retval)
  343 {
  344         /* {
  345                 syscallarg(netbsd32_clockid_t) clock_id;
  346                 syscallarg(netbsd32_timespecp_t) tp;
  347         } */
  348         clockid_t clock_id;
  349         struct timespec ats;
  350         struct netbsd32_timespec ts32;
  351 
  352         clock_id = SCARG(uap, clock_id);
  353         if (clock_id != CLOCK_REALTIME)
  354                 return (EINVAL);
  355 
  356         nanotime(&ats);
  357         netbsd32_from_timespec(&ats, &ts32);
  358 
  359         return copyout(&ts32, SCARG_P32(uap, tp), sizeof(ts32));
  360 }
  361 
  362 int
  363 netbsd32_clock_settime(struct lwp *l, const struct netbsd32_clock_settime_args *uap, register_t *retval)
  364 {
  365         /* {
  366                 syscallarg(netbsd32_clockid_t) clock_id;
  367                 syscallarg(const netbsd32_timespecp_t) tp;
  368         } */
  369         struct netbsd32_timespec ts32;
  370         clockid_t clock_id;
  371         struct timespec ats;
  372         int error;
  373 
  374         clock_id = SCARG(uap, clock_id);
  375         if (clock_id != CLOCK_REALTIME)
  376                 return (EINVAL);
  377 
  378         if ((error = copyin(SCARG_P32(uap, tp), &ts32, sizeof(ts32))) != 0)
  379                 return (error);
  380 
  381         netbsd32_to_timespec(&ts32, &ats);
  382         return settime(l->l_proc, &ats);
  383 }
  384 
  385 int
  386 netbsd32_clock_getres(struct lwp *l, const struct netbsd32_clock_getres_args *uap, register_t *retval)
  387 {
  388         /* {
  389                 syscallarg(netbsd32_clockid_t) clock_id;
  390                 syscallarg(netbsd32_timespecp_t) tp;
  391         } */
  392         struct netbsd32_timespec ts32;
  393         clockid_t clock_id;
  394         struct timespec ts;
  395         int error = 0;
  396 
  397         clock_id = SCARG(uap, clock_id);
  398         if (clock_id != CLOCK_REALTIME)
  399                 return (EINVAL);
  400 
  401         if (SCARG_P32(uap, tp)) {
  402                 ts.tv_sec = 0;
  403                 ts.tv_nsec = 1000000000 / hz;
  404 
  405                 netbsd32_from_timespec(&ts, &ts32);
  406                 error = copyout(&ts, SCARG_P32(uap, tp), sizeof(ts));
  407         }
  408 
  409         return error;
  410 }
  411 
  412 int
  413 netbsd32_nanosleep(struct lwp *l, const struct netbsd32_nanosleep_args *uap, register_t *retval)
  414 {
  415         /* {
  416                 syscallarg(const netbsd32_timespecp_t) rqtp;
  417                 syscallarg(netbsd32_timespecp_t) rmtp;
  418         } */
  419         static int nanowait;
  420         struct netbsd32_timespec ts32;
  421         struct timespec rqt, ctime, rmt;
  422         int error, timo;
  423 
  424         error = copyin(SCARG_P32(uap, rqtp), &ts32, sizeof(ts32));
  425         if (error)
  426                 return (error);
  427 
  428         netbsd32_to_timespec(&ts32, &rqt);
  429         if (itimespecfix(&rqt))
  430                 return (EINVAL);
  431 
  432         getnanotime(&ctime);
  433         timespecadd(&rqt, &ctime, &rqt);
  434         timo = tshzto(&rqt);
  435         /*
  436          * Avoid inadvertantly sleeping forever
  437          */
  438         if (timo == 0)
  439                 timo = 1;
  440 
  441         error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep", timo);
  442         if (error == ERESTART)
  443                 error = EINTR;
  444         if (error == EWOULDBLOCK)
  445                 error = 0;
  446 
  447         if (SCARG_P32(uap, rmtp)) {
  448                 int error1;
  449 
  450                 getnanotime(&rmt);
  451 
  452                 timespecsub(&rqt, &rmt, &rmt);
  453                 if (rmt.tv_sec < 0)
  454                         timespecclear(&rmt);
  455 
  456                 netbsd32_from_timespec(&rmt, &ts32);
  457                 error1 = copyout(&ts32, SCARG_P32(uap,rmtp), sizeof(ts32));
  458                 if (error1)
  459                         return (error1);
  460         }
  461 
  462         return error;
  463 }
  464 
  465 static int
  466 netbsd32_timer_create_fetch(const void *src, void *dst, size_t size)
  467 {
  468         struct sigevent *evp = dst;
  469         struct netbsd32_sigevent ev32;
  470         int error;
  471 
  472         error = copyin(src, &ev32, sizeof(ev32));
  473         if (error)
  474                 return error;
  475 
  476         netbsd32_to_sigevent(&ev32, evp);
  477         return 0;
  478 }
  479 
  480 int
  481 netbsd32_timer_create(struct lwp *l, const struct netbsd32_timer_create_args *uap, register_t *retval)
  482 {
  483         /* {
  484                 syscallarg(netbsd32_clockid_t) clock_id;
  485                 syscallarg(netbsd32_sigeventp_t) evp;
  486                 syscallarg(netbsd32_timerp_t) timerid;
  487         } */
  488 
  489         return timer_create1(SCARG_P32(uap, timerid),
  490             SCARG(uap, clock_id), SCARG_P32(uap, evp),
  491             netbsd32_timer_create_fetch, l);
  492 }
  493 
  494 int
  495 netbsd32_timer_delete(struct lwp *l, const struct netbsd32_timer_delete_args *uap, register_t *retval)
  496 {
  497         /* {
  498                 syscallarg(netbsd32_timer_t) timerid;
  499         } */
  500         struct sys_timer_delete_args ua;
  501 
  502         NETBSD32TO64_UAP(timerid);
  503         return sys_timer_delete(l, (void *)&ua, retval);
  504 }
  505 
  506 int
  507 netbsd32_timer_settime(struct lwp *l, const struct netbsd32_timer_settime_args *uap, register_t *retval)
  508 {
  509         /* {
  510                 syscallarg(netbsd32_timer_t) timerid;
  511                 syscallarg(int) flags;
  512                 syscallarg(const netbsd32_itimerspecp_t) value;
  513                 syscallarg(netbsd32_itimerspecp_t) ovalue;
  514         } */
  515         int error;
  516         struct itimerspec value, ovalue, *ovp = NULL;
  517         struct netbsd32_itimerspec its32;
  518 
  519         if ((error = copyin(SCARG_P32(uap, value), &its32, sizeof(its32))) != 0)
  520                 return (error);
  521         netbsd32_to_timespec(&its32.it_interval, &value.it_interval);
  522         netbsd32_to_timespec(&its32.it_value, &value.it_value);
  523 
  524         if (SCARG_P32(uap, ovalue))
  525                 ovp = &ovalue;
  526 
  527         if ((error = dotimer_settime(SCARG(uap, timerid), &value, ovp,
  528             SCARG(uap, flags), l->l_proc)) != 0)
  529                 return error;
  530 
  531         if (ovp) {
  532                 netbsd32_from_timespec(&ovp->it_interval, &its32.it_interval);
  533                 netbsd32_from_timespec(&ovp->it_value, &its32.it_value);
  534                 return copyout(&its32, SCARG_P32(uap, ovalue), sizeof(its32));
  535         }
  536         return 0;
  537 }
  538 
  539 int
  540 netbsd32_timer_gettime(struct lwp *l, const struct netbsd32_timer_gettime_args *uap, register_t *retval)
  541 {
  542         /* {
  543                 syscallarg(netbsd32_timer_t) timerid;
  544                 syscallarg(netbsd32_itimerspecp_t) value;
  545         } */
  546         int error;
  547         struct itimerspec its;
  548         struct netbsd32_itimerspec its32;
  549 
  550         if ((error = dotimer_gettime(SCARG(uap, timerid), l->l_proc,
  551             &its)) != 0)
  552                 return error;
  553 
  554         netbsd32_from_timespec(&its.it_interval, &its32.it_interval);
  555         netbsd32_from_timespec(&its.it_value, &its32.it_value);
  556 
  557         return copyout(&its32, SCARG_P32(uap, value), sizeof(its32));
  558 }
  559 
  560 int
  561 netbsd32_timer_getoverrun(struct lwp *l, const struct netbsd32_timer_getoverrun_args *uap, register_t *retval)
  562 {
  563         /* {
  564                 syscallarg(netbsd32_timer_t) timerid;
  565         } */
  566         struct sys_timer_getoverrun_args ua;
  567 
  568         NETBSD32TO64_UAP(timerid);
  569         return sys_timer_getoverrun(l, (void *)&ua, retval);
  570 }

Cache object: e1e3360025a7887a09ee3950ff2d3eed


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.