123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- #include <types.h>
- #include <lib.h>
- #include <uio.h>
- #include <proc.h>
- #include <current.h>
- #include <copyinout.h>
- int
- uiomove(void *ptr, size_t n, struct uio *uio)
- {
- struct iovec *iov;
- size_t size;
- int result;
- if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE) {
- panic("uiomove: Invalid uio_rw %d\n", (int) uio->uio_rw);
- }
- if (uio->uio_segflg==UIO_SYSSPACE) {
- KASSERT(uio->uio_space == NULL);
- }
- else {
- KASSERT(uio->uio_space == curproc_getas());
- }
- while (n > 0 && uio->uio_resid > 0) {
-
- iov = uio->uio_iov;
- size = iov->iov_len;
- if (size > n) {
- size = n;
- }
- if (size == 0) {
-
- uio->uio_iov++;
- uio->uio_iovcnt--;
- if (uio->uio_iovcnt == 0) {
-
- panic("uiomove: ran out of buffers\n");
- }
- continue;
- }
- switch (uio->uio_segflg) {
- case UIO_SYSSPACE:
- result = 0;
- if (uio->uio_rw == UIO_READ) {
- memmove(iov->iov_kbase, ptr, size);
- }
- else {
- memmove(ptr, iov->iov_kbase, size);
- }
- iov->iov_kbase = ((char *)iov->iov_kbase+size);
- break;
- case UIO_USERSPACE:
- case UIO_USERISPACE:
- if (uio->uio_rw == UIO_READ) {
- result = copyout(ptr, iov->iov_ubase,size);
- }
- else {
- result = copyin(iov->iov_ubase, ptr, size);
- }
- if (result) {
- return result;
- }
- iov->iov_ubase += size;
- break;
- default:
- panic("uiomove: Invalid uio_segflg %d\n",
- (int)uio->uio_segflg);
- }
- iov->iov_len -= size;
- uio->uio_resid -= size;
- uio->uio_offset += size;
- ptr = ((char *)ptr + size);
- n -= size;
- }
- return 0;
- }
- int
- uiomovezeros(size_t n, struct uio *uio)
- {
-
- static char zeros[16];
- size_t amt;
- int result;
-
- KASSERT(uio->uio_rw == UIO_READ);
- while (n > 0) {
- amt = sizeof(zeros);
- if (amt > n) {
- amt = n;
- }
- result = uiomove(zeros, amt, uio);
- if (result) {
- return result;
- }
- n -= amt;
- }
- return 0;
- }
- void
- uio_kinit(struct iovec *iov, struct uio *u,
- void *kbuf, size_t len, off_t pos, enum uio_rw rw)
- {
- iov->iov_kbase = kbuf;
- iov->iov_len = len;
- u->uio_iov = iov;
- u->uio_iovcnt = 1;
- u->uio_offset = pos;
- u->uio_resid = len;
- u->uio_segflg = UIO_SYSSPACE;
- u->uio_rw = rw;
- u->uio_space = NULL;
- }
|