--- //depot/projects/smpng/sys/alpha/osf1/osf1_misc.c 2005/03/01 16:04:42 +++ //depot/user/jhb/proc/alpha/osf1/osf1_misc.c 2005/03/01 19:12:19 @@ -993,52 +993,61 @@ char *iov_base; int iov_len; }; -#define STACKGAPLEN 400 + +static int +osf1_copyinuio(struct osf1_iovec *iovp, u_int iovcnt, struct uio **uiop) +{ + struct osf1_iovec oiov; + struct iovec *iov; + struct uio *uio; + u_int iovlen; + int error, i; + + *uiop = NULL; + if (iovcnt > UIO_MAXIOV) + return (EINVAL); + iovlen = iovcnt * sizeof(struct iovec); + uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK); + iov = (struct iovec *)(uio + 1); + for (i = 0; i < iovcnt; i++) { + error = copyin(&iovp[i], &oiov, sizeof(struct osf1_iovec)); + if (error) { + free(uio, M_IOV); + return (error); + } + iov[i].iov_base = oiov.iov_base; + iov[i].iov_len = oiov.iov_len; + } + uio->uio_iov = iov; + uio->uio_iovcnt = iovcnt; + uio->uio_segflg = UIO_USERSPACE; + uio->uio_offset = -1; + uio->uio_resid = 0; + for (i = 0; i < iovcnt; i++) { + if (iov->iov_len > INT_MAX - uio->uio_resid) { + free(uio, M_IOV); + return (EINVAL); + } + uio->uio_resid += iov->iov_len; + iov++; + } + *uiop = uio; + return (0); +} + int osf1_readv(td, uap) struct thread *td; struct osf1_readv_args *uap; { - int error, osize, nsize, i; - caddr_t sg; - struct readv_args /* { - syscallarg(int) fd; - syscallarg(struct iovec *) iovp; - syscallarg(u_int) iovcnt; - } */ a; - struct osf1_iovec *oio; - struct iovec *nio; + struct uio *auio; + int error; - sg = stackgap_init(); - - if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) - return (EINVAL); - - osize = uap->iovcnt * sizeof (struct osf1_iovec); - nsize = uap->iovcnt * sizeof (struct iovec); - - oio = malloc(osize, M_TEMP, M_WAITOK); - nio = malloc(nsize, M_TEMP, M_WAITOK); - - error = 0; - if ((error = copyin(uap->iovp, oio, osize))) - goto punt; - for (i = 0; i < uap->iovcnt; i++) { - nio[i].iov_base = oio[i].iov_base; - nio[i].iov_len = oio[i].iov_len; - } - - a.fd = uap->fd; - a.iovp = stackgap_alloc(&sg, nsize); - a.iovcnt = uap->iovcnt; - - if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) - goto punt; - error = readv(td, &a); - -punt: - free(oio, M_TEMP); - free(nio, M_TEMP); + error = osf1_copyinuio(uap->iovp, uap->iovcnt, &auio); + if (error) + return (error); + error = kern_readv(td, uap->fd, auio); + free(auio, M_IOV); return (error); } @@ -1048,46 +1057,14 @@ struct thread *td; struct osf1_writev_args *uap; { - int error, i, nsize, osize; - caddr_t sg; - struct writev_args /* { - syscallarg(int) fd; - syscallarg(struct iovec *) iovp; - syscallarg(u_int) iovcnt; - } */ a; - struct osf1_iovec *oio; - struct iovec *nio; + struct uio *auio; + int error; - sg = stackgap_init(); - - if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) - return (EINVAL); - - osize = uap->iovcnt * sizeof (struct osf1_iovec); - nsize = uap->iovcnt * sizeof (struct iovec); - - oio = malloc(osize, M_TEMP, M_WAITOK); - nio = malloc(nsize, M_TEMP, M_WAITOK); - - error = 0; - if ((error = copyin(uap->iovp, oio, osize))) - goto punt; - for (i = 0; i < uap->iovcnt; i++) { - nio[i].iov_base = oio[i].iov_base; - nio[i].iov_len = oio[i].iov_len; - } - - a.fd = uap->fd; - a.iovp = stackgap_alloc(&sg, nsize); - a.iovcnt = uap->iovcnt; - - if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) - goto punt; - error = writev(td, &a); - -punt: - free(oio, M_TEMP); - free(nio, M_TEMP); + error = osf1_copyinuio(uap->iovp, uap->iovcnt, &auio); + if (error) + return (error); + error = kern_writev(td, uap->fd, auio); + free(auio, M_IOV); return (error); } --- //depot/projects/smpng/sys/amd64/linux32/linux32_machdep.c 2005/03/01 16:04:42 +++ //depot/user/jhb/proc/amd64/linux32/linux32_machdep.c 2005/03/01 19:50:31 @@ -212,99 +212,75 @@ u_int32_t iov_base; int iov_len; }; -#define STACKGAPLEN 400 CTASSERT(sizeof(struct iovec32) == 8); -int -linux_readv(struct thread *td, struct linux_readv_args *uap) +static int +linux32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) { - int error, osize, nsize, i; - caddr_t sg; - struct readv_args /* { - syscallarg(int) fd; - syscallarg(struct iovec *) iovp; - syscallarg(u_int) iovcnt; - } */ a; - struct iovec32 *oio; - struct iovec *nio; + struct iovec32 iov32; + struct iovec *iov; + struct uio *uio; + u_int iovlen; + int error, i; - sg = stackgap_init(); - - if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) + *uiop = NULL; + if (iovcnt > UIO_MAXIOV) return (EINVAL); - - osize = uap->iovcnt * sizeof (struct iovec32); - nsize = uap->iovcnt * sizeof (struct iovec); - - oio = malloc(osize, M_TEMP, M_WAITOK); - nio = malloc(nsize, M_TEMP, M_WAITOK); - - error = 0; - if ((error = copyin(uap->iovp, oio, osize))) - goto punt; - for (i = 0; i < uap->iovcnt; i++) { - nio[i].iov_base = PTRIN(oio[i].iov_base); - nio[i].iov_len = oio[i].iov_len; + iovlen = iovcnt * sizeof(struct iovec); + uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK); + iov = (struct iovec *)(uio + 1); + for (i = 0; i < iovcnt; i++) { + error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); + if (error) { + free(uio, M_IOV); + return (error); + } + iov[i].iov_base = PTRIN(iov32.iov_base); + iov[i].iov_len = iov32.iov_len; + } + uio->uio_iov = iov; + uio->uio_iovcnt = iovcnt; + uio->uio_segflg = UIO_USERSPACE; + uio->uio_offset = -1; + uio->uio_resid = 0; + for (i = 0; i < iovcnt; i++) { + if (iov->iov_len > INT_MAX - uio->uio_resid) { + free(uio, M_IOV); + return (EINVAL); + } + uio->uio_resid += iov->iov_len; + iov++; } + *uiop = uio; + return (0); +} - a.fd = uap->fd; - a.iovp = stackgap_alloc(&sg, nsize); - a.iovcnt = uap->iovcnt; +int +linux_readv(struct thread *td, struct linux_readv_args *uap) +{ + struct uio *auio; + int error; - if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) - goto punt; - error = readv(td, &a); - -punt: - free(oio, M_TEMP); - free(nio, M_TEMP); + error = linux32_copyinuio(uap->iovp, uap->iovcnt, &auio); + if (error) + return (error); + error = kern_readv(td, uap->fd, auio); + free(auio, M_IOV); return (error); } int linux_writev(struct thread *td, struct linux_writev_args *uap) { - int error, i, nsize, osize; - caddr_t sg; - struct writev_args /* { - syscallarg(int) fd; - syscallarg(struct iovec *) iovp; - syscallarg(u_int) iovcnt; - } */ a; - struct iovec32 *oio; - struct iovec *nio; + struct uio *auio; + int error; - sg = stackgap_init(); - - if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) - return (EINVAL); - - osize = uap->iovcnt * sizeof (struct iovec32); - nsize = uap->iovcnt * sizeof (struct iovec); - - oio = malloc(osize, M_TEMP, M_WAITOK); - nio = malloc(nsize, M_TEMP, M_WAITOK); - - error = 0; - if ((error = copyin(uap->iovp, oio, osize))) - goto punt; - for (i = 0; i < uap->iovcnt; i++) { - nio[i].iov_base = PTRIN(oio[i].iov_base); - nio[i].iov_len = oio[i].iov_len; - } - - a.fd = uap->fd; - a.iovp = stackgap_alloc(&sg, nsize); - a.iovcnt = uap->iovcnt; - - if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) - goto punt; - error = writev(td, &a); - -punt: - free(oio, M_TEMP); - free(nio, M_TEMP); + error = linux32_copyinuio(uap->iovp, uap->iovcnt, &auio); + if (error) + return (error); + error = kern_writev(td, uap->fd, auio); + free(auio, M_IOV); return (error); } @@ -399,7 +375,7 @@ a.shmid = args->arg1; a.shmaddr = args->ptr; a.shmflg = args->arg2; - a.raddr = PTRIN(args->arg3); + a.raddr = PTRIN((l_uint)args->arg3); return (linux_shmat(td, &a)); } case LINUX_SHMDT: { @@ -565,11 +541,11 @@ /* XXX move */ struct l_mmap_argv { l_ulong addr; - l_int len; - l_int prot; - l_int flags; - l_int fd; - l_int pos; + l_ulong len; + l_ulong prot; + l_ulong flags; + l_ulong fd; + l_ulong pgoff; }; #define STACK_SIZE (2 * 1024 * 1024) @@ -594,7 +570,7 @@ linux_args.prot = args->prot; linux_args.flags = args->flags; linux_args.fd = args->fd; - linux_args.pos = args->pgoff * PAGE_SIZE; + linux_args.pgoff = args->pgoff; return (linux_mmap_common(td, &linux_args)); } @@ -616,6 +592,9 @@ linux_args.prot, linux_args.flags, linux_args.fd, linux_args.pos); #endif + if ((linux_args.pgoff % PAGE_SIZE) != 0) + return (EINVAL); + linux_args.pgoff /= PAGE_SIZE; return (linux_mmap_common(td, &linux_args)); } @@ -727,7 +706,7 @@ bsd_args.fd = -1; else bsd_args.fd = linux_args->fd; - bsd_args.pos = linux_args->pos; + bsd_args.pos = (off_t)linux_args->pgoff * PAGE_SIZE; bsd_args.pad = 0; #ifdef DEBUG @@ -1010,20 +989,11 @@ linux_sched_rr_get_interval(struct thread *td, struct linux_sched_rr_get_interval_args *uap) { - struct sched_rr_get_interval_args bsd_args; - caddr_t sg, psgts; struct timespec ts; struct l_timespec ts32; int error; - sg = stackgap_init(); - psgts = stackgap_alloc(&sg, sizeof(struct timespec)); - bsd_args.pid = uap->pid; - bsd_args.interval = (void *)psgts; - error = sched_rr_get_interval(td, &bsd_args); - if (error != 0) - return (error); - error = copyin(psgts, &ts, sizeof(ts)); + error = kern_sched_rr_get_interval(td, uap->pid, &ts); if (error != 0) return (error); ts32.tv_sec = ts.tv_sec; --- //depot/projects/smpng/sys/compat/freebsd32/freebsd32_misc.c 2005/03/01 18:15:27 +++ //depot/user/jhb/proc/compat/freebsd32/freebsd32_misc.c 2005/03/01 19:37:07 @@ -680,99 +680,75 @@ u_int32_t iov_base; int iov_len; }; -#define STACKGAPLEN 400 CTASSERT(sizeof(struct iovec32) == 8); -int -freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) +static int +freebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) { - int error, osize, nsize, i; - caddr_t sg; - struct readv_args /* { - syscallarg(int) fd; - syscallarg(struct iovec *) iovp; - syscallarg(u_int) iovcnt; - } */ a; - struct iovec32 *oio; - struct iovec *nio; + struct iovec32 iov32; + struct iovec *iov; + struct uio *uio; + u_int iovlen; + int error, i; - sg = stackgap_init(); - - if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) + *uiop = NULL; + if (iovcnt > UIO_MAXIOV) return (EINVAL); - - osize = uap->iovcnt * sizeof (struct iovec32); - nsize = uap->iovcnt * sizeof (struct iovec); - - oio = malloc(osize, M_TEMP, M_WAITOK); - nio = malloc(nsize, M_TEMP, M_WAITOK); - - error = 0; - if ((error = copyin(uap->iovp, oio, osize))) - goto punt; - for (i = 0; i < uap->iovcnt; i++) { - nio[i].iov_base = PTRIN(oio[i].iov_base); - nio[i].iov_len = oio[i].iov_len; + iovlen = iovcnt * sizeof(struct iovec); + uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK); + iov = (struct iovec *)(uio + 1); + for (i = 0; i < iovcnt; i++) { + error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); + if (error) { + free(uio, M_IOV); + return (error); + } + iov[i].iov_base = PTRIN(iov32.iov_base); + iov[i].iov_len = iov32.iov_len; + } + uio->uio_iov = iov; + uio->uio_iovcnt = iovcnt; + uio->uio_segflg = UIO_USERSPACE; + uio->uio_offset = -1; + uio->uio_resid = 0; + for (i = 0; i < iovcnt; i++) { + if (iov->iov_len > INT_MAX - uio->uio_resid) { + free(uio, M_IOV); + return (EINVAL); + } + uio->uio_resid += iov->iov_len; + iov++; } + *uiop = uio; + return (0); +} - a.fd = uap->fd; - a.iovp = stackgap_alloc(&sg, nsize); - a.iovcnt = uap->iovcnt; +int +freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) +{ + struct uio *auio; + int error; - if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) - goto punt; - error = readv(td, &a); - -punt: - free(oio, M_TEMP); - free(nio, M_TEMP); + error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); + if (error) + return (error); + error = kern_readv(td, uap->fd, auio); + free(auio, M_IOV); return (error); } int freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) { - int error, i, nsize, osize; - caddr_t sg; - struct writev_args /* { - syscallarg(int) fd; - syscallarg(struct iovec *) iovp; - syscallarg(u_int) iovcnt; - } */ a; - struct iovec32 *oio; - struct iovec *nio; + struct uio *auio; + int error; - sg = stackgap_init(); - - if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) - return (EINVAL); - - osize = uap->iovcnt * sizeof (struct iovec32); - nsize = uap->iovcnt * sizeof (struct iovec); - - oio = malloc(osize, M_TEMP, M_WAITOK); - nio = malloc(nsize, M_TEMP, M_WAITOK); - - error = 0; - if ((error = copyin(uap->iovp, oio, osize))) - goto punt; - for (i = 0; i < uap->iovcnt; i++) { - nio[i].iov_base = PTRIN(oio[i].iov_base); - nio[i].iov_len = oio[i].iov_len; - } - - a.fd = uap->fd; - a.iovp = stackgap_alloc(&sg, nsize); - a.iovcnt = uap->iovcnt; - - if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) - goto punt; - error = writev(td, &a); - -punt: - free(oio, M_TEMP); - free(nio, M_TEMP); + error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); + if (error) + return (error); + error = kern_readv(td, uap->fd, auio); + free(auio, M_IOV); return (error); } @@ -780,26 +756,28 @@ freebsd32_settimeofday(struct thread *td, struct freebsd32_settimeofday_args *uap) { + struct timeval32 tv32; + struct timeval tv, *tvp; + struct timezone tz, *tzp; int error; - caddr_t sg; - struct timeval32 *p32, s32; - struct timeval *p = NULL, s; - p32 = uap->tv; - if (p32) { - sg = stackgap_init(); - p = stackgap_alloc(&sg, sizeof(struct timeval)); - uap->tv = (struct timeval32 *)p; - error = copyin(p32, &s32, sizeof(s32)); + if (uap->tv) { + error = copyin(uap->tv, &tv32, sizeof(tv32)); if (error) return (error); - CP(s32, s, tv_sec); - CP(s32, s, tv_usec); - error = copyout(&s, p, sizeof(s)); + CP(tv32, tv, tv_sec); + CP(tv32, tv, tv_usec); + tvp = &tv; + } else + tvp = NULL; + if (uap->tzp) { + error = copyin(uap->tzp, &tz, sizeof(tz)); if (error) return (error); - } - return (settimeofday(td, (struct settimeofday_args *) uap)); + tzp = &tz; + } else + tzp = NULL; + return (kern_settimeofday(td, tvp, tzp); } int @@ -826,41 +804,24 @@ int freebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) { + struct timeval32 tv32; + struct timeval delta, olddelta, *deltap; int error; - caddr_t sg; - struct timeval32 *p32, *op32, s32; - struct timeval *p = NULL, *op = NULL, s; - p32 = uap->delta; - if (p32) { - sg = stackgap_init(); - p = stackgap_alloc(&sg, sizeof(struct timeval)); - uap->delta = (struct timeval32 *)p; - error = copyin(p32, &s32, sizeof(s32)); + if (uap->delta) { + error = copyin(uap->delta, &tv32, sizeof(tv32)); if (error) return (error); - CP(s32, s, tv_sec); - CP(s32, s, tv_usec); - error = copyout(&s, p, sizeof(s)); - if (error) - return (error); - } - op32 = uap->olddelta; - if (op32) { - sg = stackgap_init(); - op = stackgap_alloc(&sg, sizeof(struct timeval)); - uap->olddelta = (struct timeval32 *)op; - } - error = adjtime(td, (struct adjtime_args *) uap); - if (error) - return error; - if (op32) { - error = copyin(op, &s, sizeof(s)); - if (error) - return (error); - CP(s, s32, tv_sec); - CP(s, s32, tv_usec); - error = copyout(&s32, op32, sizeof(s32)); + CP(tv32, delta, tv_sec); + CP(tv32, delta, tv_usec); + deltap = δ + } else + deltap = NULL; + error = kern_adjtime(td, deltap, &olddelta); + if (uap->olddelta && error == 0) { + CP(olddelta, tv32, tv_sec); + CP(olddelta, tv32, tv_usec); + error = copyout(&tv32, uap->olddelta, sizeof(tv32)); } return (error); } --- //depot/projects/smpng/sys/i386/ibcs2/ibcs2_misc.c 2005/02/07 22:31:33 +++ //depot/user/jhb/proc/i386/ibcs2/ibcs2_misc.c 2005/03/01 19:27:23 @@ -899,19 +899,19 @@ struct thread *td; struct ibcs2_stime_args *uap; { + struct timeval tv; + long secs; int error; - struct settimeofday_args sa; - caddr_t sg = stackgap_init(); - sa.tv = stackgap_alloc(&sg, sizeof(*sa.tv)); - sa.tzp = NULL; - if ((error = copyin((caddr_t)uap->timep, - &(sa.tv->tv_sec), sizeof(long))) != 0) - return error; - sa.tv->tv_usec = 0; - if ((error = settimeofday(td, &sa)) != 0) - return EPERM; - return 0; + error = copyin(uap->timep, &secs, sizeof(long)); + if (error) + return (error); + tv.tv_sec = secs; + tv.tv_usec = 0; + error = kern_settimeofday(td, &tv, NULL); + if (error) + error = EPERM; + return (error); } int --- //depot/projects/smpng/sys/kern/kern_ntptime.c 2005/01/07 18:05:05 +++ //depot/user/jhb/proc/kern/kern_ntptime.c 2005/03/02 17:53:25 @@ -46,6 +46,7 @@ #include #include #include +#include #include /* @@ -927,6 +928,25 @@ 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 @@ 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); } --- //depot/projects/smpng/sys/kern/kern_time.c 2005/02/07 22:31:33 +++ //depot/user/jhb/proc/kern/kern_time.c 2005/03/02 17:53:25 @@ -374,36 +374,53 @@ 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 --- //depot/projects/smpng/sys/kern/sys_generic.c 2005/03/01 16:04:42 +++ //depot/user/jhb/proc/kern/sys_generic.c 2005/03/01 19:12:19 @@ -222,26 +222,33 @@ 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 @@ #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 @@ 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 @@ #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); } --- //depot/projects/smpng/sys/posix4/p1003_1b.c 2005/01/07 18:05:05 +++ //depot/user/jhb/proc/posix4/p1003_1b.c 2005/03/02 17:53:25 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -305,35 +306,41 @@ int sched_rr_get_interval(struct thread *td, struct sched_rr_get_interval_args *uap) { + struct timespec timespec; + int error; + + error = kern_sched_rr_get_interval(td, uap->pid, ×pec); + if (error == 0) + error = copyout(×pec, uap->interval, sizeof(timespec)); + return (error); +} + +int kern_sched_rr_get_interval(struct thread *td, pid_t pid, + struct timespec *ts) +{ int e; struct thread *targettd; - struct timespec timespec; struct proc *targetp; mtx_lock(&Giant); - if (uap->pid == 0) { + if (pid == 0) { targettd = td; targetp = td->td_proc; PROC_LOCK(targetp); } else { - targetp = pfind(uap->pid); + targetp = pfind(pid); if (targetp == NULL) { - e = ESRCH; - goto done2; + mtx_unlock(&Giant); + return (ESRCH); } targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */ } e = p_cansee(td, targetp); + if (e == 0) + e = ksched_rr_get_interval(&td->td_retval[0], ksched, targettd, + ts); PROC_UNLOCK(targetp); - if (e == 0) { - e = ksched_rr_get_interval(&td->td_retval[0], ksched, targettd, - ×pec); - if (e == 0) - e = copyout(×pec, uap->interval, - sizeof(timespec)); - } -done2: mtx_unlock(&Giant); return (e); } --- //depot/projects/smpng/sys/sys/syscallsubr.h 2005/03/01 18:15:27 +++ //depot/user/jhb/proc/sys/syscallsubr.h 2005/03/01 19:50:31 @@ -49,6 +49,8 @@ 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 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_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 @@ 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 */