Implement kern_adjtime(), kern_readv(), kern_sched_rr_get_interval(),
kern_settimeofday(), and kern_writev() to allow for further stackgap reduction in the compat ABIs.
This commit is contained in:
parent
e392175600
commit
b88ec951e1
@ -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>
|
||||
|
||||
/*
|
||||
@ -926,6 +927,25 @@ struct adjtime_args {
|
||||
/* ARGSUSED */
|
||||
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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -221,27 +221,34 @@ 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);
|
||||
}
|
||||
@ -412,23 +418,31 @@ 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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user