summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_ntptime.c36
-rw-r--r--sys/kern/kern_time.c51
-rw-r--r--sys/kern/sys_generic.c51
-rw-r--r--sys/sys/syscallsubr.h8
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 = &delta;
+ } 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 */
OpenPOWER on IntegriCloud