diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_ntptime.c | 36 | ||||
-rw-r--r-- | sys/kern/kern_time.c | 51 | ||||
-rw-r--r-- | sys/kern/sys_generic.c | 51 | ||||
-rw-r--r-- | sys/sys/syscallsubr.h | 8 |
4 files changed, 99 insertions, 47 deletions
diff --git a/sys/kern/kern_ntptime.c b/sys/kern/kern_ntptime.c index 15a239c..bddbc3b 100644 --- a/sys/kern/kern_ntptime.c +++ b/sys/kern/kern_ntptime.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include <sys/timex.h> #include <sys/timetc.h> #include <sys/timepps.h> +#include <sys/syscallsubr.h> #include <sys/sysctl.h> /* @@ -927,6 +928,25 @@ struct adjtime_args { int adjtime(struct thread *td, struct adjtime_args *uap) { + struct timeval delta, olddelta, *deltap; + int error; + + if (uap->delta) { + error = copyin(uap->delta, &delta, sizeof(delta)); + if (error) + return (error); + deltap = δ + } else + deltap = NULL; + error = kern_adjtime(td, deltap, &olddelta); + if (uap->olddelta && error == 0) + error = copyout(&olddelta, uap->olddelta, sizeof(olddelta)); + return (error); +} + +int +kern_adjtime(struct thread *td, struct timeval *delta, struct timeval *olddelta) +{ struct timeval atv; int error; @@ -934,24 +954,18 @@ adjtime(struct thread *td, struct adjtime_args *uap) return (error); mtx_lock(&Giant); - if (uap->olddelta) { + if (olddelta) { atv.tv_sec = time_adjtime / 1000000; atv.tv_usec = time_adjtime % 1000000; if (atv.tv_usec < 0) { atv.tv_usec += 1000000; atv.tv_sec--; } - error = copyout(&atv, uap->olddelta, sizeof(atv)); - if (error) - goto done2; + *olddelta = atv; } - if (uap->delta) { - error = copyin(uap->delta, &atv, sizeof(atv)); - if (error) - goto done2; - time_adjtime = (int64_t)atv.tv_sec * 1000000 + atv.tv_usec; - } -done2: + if (delta) + time_adjtime = (int64_t)delta->tv_sec * 1000000 + + delta->tv_usec; mtx_unlock(&Giant); return (error); } diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index a71e995..d0c3f9e 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -374,36 +374,53 @@ struct settimeofday_args { int settimeofday(struct thread *td, struct settimeofday_args *uap) { - struct timeval atv; - struct timezone atz; - int error = 0; + struct timeval atv, *tvp; + struct timezone atz, *tzp; + int error; + + if (uap->tv) { + error = copyin(uap->tv, &atv, sizeof(atv)); + if (error) + return (error); + tvp = &atv; + } else + tvp = NULL; + if (uap->tzp) { + error = copyin(uap->tzp, &atz, sizeof(atz)); + if (error) + return (error); + tzp = &atz; + } else + tzp = NULL; + return (kern_settimeofday(td, tvp, tzp)); +} + +int +kern_settimeofday(struct thread *td, struct timeval *tv, struct timezone *tzp) +{ + int error; #ifdef MAC error = mac_check_system_settime(td->td_ucred); if (error) return (error); #endif - if ((error = suser(td))) + error = suser(td); + if (error) return (error); /* Verify all parameters before changing time. */ - if (uap->tv) { - if ((error = copyin(uap->tv, &atv, sizeof(atv)))) - return (error); - if (atv.tv_usec < 0 || atv.tv_usec >= 1000000) + if (tv) { + if (tv->tv_usec < 0 || tv->tv_usec >= 1000000) return (EINVAL); + error = settime(td, tv); } - if (uap->tzp && - (error = copyin(uap->tzp, &atz, sizeof(atz)))) - return (error); - - if (uap->tv && (error = settime(td, &atv))) - return (error); - if (uap->tzp) { - tz_minuteswest = atz.tz_minuteswest; - tz_dsttime = atz.tz_dsttime; + if (tzp && error == 0) { + tz_minuteswest = tzp->tz_minuteswest; + tz_dsttime = tzp->tz_dsttime; } return (error); } + /* * Get value of an interval timer. The process virtual and * profiling virtual time timers are kept in the p_stats area, since diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index d731fee..bd02f16 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -222,26 +222,33 @@ struct readv_args { int readv(struct thread *td, struct readv_args *uap) { + struct uio *auio; + int error; + + error = copyinuio(uap->iovp, uap->iovcnt, &auio); + if (error) + return (error); + error = kern_readv(td, uap->fd, auio); + free(auio, M_IOV); + return (error); +} + +int +kern_readv(struct thread *td, int fd, struct uio *auio) +{ struct file *fp; - struct uio *auio = NULL; long cnt; int error; #ifdef KTRACE struct uio *ktruio = NULL; #endif - error = fget_read(td, uap->fd, &fp); + error = fget_read(td, fd, &fp); if (error) return (error); - error = copyinuio(uap->iovp, uap->iovcnt, &auio); - if (error) { - fdrop(fp, td); - return (error); - } /* Finish zero length reads right here */ if (auio->uio_resid == 0) { td->td_retval[0] = 0; - free(auio, M_IOV); fdrop(fp, td); return(0); } @@ -261,11 +268,10 @@ readv(struct thread *td, struct readv_args *uap) #ifdef KTRACE if (ktruio != NULL) { ktruio->uio_resid = cnt; - ktrgenio(uap->fd, UIO_READ, ktruio, error); + ktrgenio(fd, UIO_READ, ktruio, error); } #endif td->td_retval[0] = cnt; - free(auio, M_IOV); fdrop(fp, td); return (error); } @@ -413,22 +419,30 @@ struct writev_args { int writev(struct thread *td, struct writev_args *uap) { + struct uio *auio; + int error; + + error = copyinuio(uap->iovp, uap->iovcnt, &auio); + if (error) + return (error); + error = kern_writev(td, uap->fd, auio); + free(auio, M_IOV); + return (error); +} + +int +kern_writev(struct thread *td, int fd, struct uio *auio) +{ struct file *fp; - struct uio *auio = NULL; long cnt; int error; #ifdef KTRACE struct uio *ktruio = NULL; #endif - error = fget_write(td, uap->fd, &fp); + error = fget_write(td, fd, &fp); if (error) return (EBADF); - error = copyinuio(uap->iovp, uap->iovcnt, &auio); - if (error) { - fdrop(fp, td); - return (error); - } auio->uio_rw = UIO_WRITE; auio->uio_td = td; #ifdef KTRACE @@ -452,12 +466,11 @@ writev(struct thread *td, struct writev_args *uap) #ifdef KTRACE if (ktruio != NULL) { ktruio->uio_resid = cnt; - ktrgenio(uap->fd, UIO_WRITE, ktruio, error); + ktrgenio(fd, UIO_WRITE, ktruio, error); } #endif td->td_retval[0] = cnt; fdrop(fp, td); - free(auio, M_IOV); return (error); } diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index 69f873c..86fa772 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -49,6 +49,8 @@ int kern___getcwd(struct thread *td, u_char *buf, enum uio_seg bufseg, u_int buflen); int kern_access(struct thread *td, char *path, enum uio_seg pathseg, int flags); +int kern_adjtime(struct thread *td, struct timeval *delta, + struct timeval *olddelta); int kern_alternate_path(struct thread *td, const char *prefix, char *path, enum uio_seg pathseg, char **pathbuf, int create); int kern_bind(struct thread *td, int fd, struct sockaddr *sa); @@ -98,9 +100,12 @@ int kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data); int kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf, enum uio_seg bufseg, int count); +int kern_readv(struct thread *td, int fd, struct uio *auio); int kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg); int kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg); +int kern_sched_rr_get_interval(struct thread *td, pid_t pid, + struct timespec *ts); int kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou, fd_set *fd_ex, struct timeval *tvp); int kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags, @@ -110,6 +115,8 @@ int kern_setitimer(struct thread *, u_int, struct itimerval *, int kern_setrlimit(struct thread *, u_int, struct rlimit *); int kern_setsockopt(struct thread *td, int s, int level, int name, void *optval, enum uio_seg valseg, socklen_t valsize); +int kern_settimeofday(struct thread *td, struct timeval *tv, + struct timezone *tzp); int kern_shmat(struct thread *td, int shmid, const void *shmaddr, int shmflg); int kern_shmctl(struct thread *td, int shmid, int cmd, void *buf, @@ -133,6 +140,7 @@ int kern_utimes(struct thread *td, char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg); int kern_wait(struct thread *td, pid_t pid, int *status, int options, struct rusage *rup); +int kern_writev(struct thread *td, int fd, struct uio *auio); /* flags for kern_sigaction */ #define KSA_OSIGSET 0x0001 /* uses osigact_t */ |