criov.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /* $OpenBSD: criov.c,v 1.20 2015/03/14 03:38:46 jsg Exp $ */
  2. /*
  3. * Copyright (c) 1999 Theo de Raadt
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  17. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  18. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  19. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  20. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  21. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  22. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  24. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include <sys/param.h>
  27. #include <sys/systm.h>
  28. #include <sys/errno.h>
  29. #include <sys/kernel.h>
  30. #include <sys/mbuf.h>
  31. void
  32. cuio_copydata(struct uio *uio, int off, int len, caddr_t cp)
  33. {
  34. struct iovec *iov = uio->uio_iov;
  35. int iol = uio->uio_iovcnt;
  36. unsigned count;
  37. if (off < 0)
  38. panic("cuio_copydata: off %d < 0", off);
  39. if (len < 0)
  40. panic("cuio_copydata: len %d < 0", len);
  41. while (off > 0) {
  42. if (iol == 0)
  43. panic("iov_copydata: empty in skip");
  44. if (off < iov->iov_len)
  45. break;
  46. off -= iov->iov_len;
  47. iol--;
  48. iov++;
  49. }
  50. while (len > 0) {
  51. if (iol == 0)
  52. panic("cuio_copydata: empty");
  53. count = min(iov->iov_len - off, len);
  54. bcopy(((caddr_t)iov->iov_base) + off, cp, count);
  55. len -= count;
  56. cp += count;
  57. off = 0;
  58. iol--;
  59. iov++;
  60. }
  61. }
  62. void
  63. cuio_copyback(struct uio *uio, int off, int len, const void *_cp)
  64. {
  65. struct iovec *iov = uio->uio_iov;
  66. int iol = uio->uio_iovcnt;
  67. unsigned count;
  68. caddr_t cp = (caddr_t)_cp;
  69. if (off < 0)
  70. panic("cuio_copyback: off %d < 0", off);
  71. if (len < 0)
  72. panic("cuio_copyback: len %d < 0", len);
  73. while (off > 0) {
  74. if (iol == 0)
  75. panic("cuio_copyback: empty in skip");
  76. if (off < iov->iov_len)
  77. break;
  78. off -= iov->iov_len;
  79. iol--;
  80. iov++;
  81. }
  82. while (len > 0) {
  83. if (iol == 0)
  84. panic("uio_copyback: empty");
  85. count = min(iov->iov_len - off, len);
  86. bcopy(cp, ((caddr_t)iov->iov_base) + off, count);
  87. len -= count;
  88. cp += count;
  89. off = 0;
  90. iol--;
  91. iov++;
  92. }
  93. }
  94. int
  95. cuio_getptr(struct uio *uio, int loc, int *off)
  96. {
  97. int ind, len;
  98. ind = 0;
  99. while (loc >= 0 && ind < uio->uio_iovcnt) {
  100. len = uio->uio_iov[ind].iov_len;
  101. if (len > loc) {
  102. *off = loc;
  103. return (ind);
  104. }
  105. loc -= len;
  106. ind++;
  107. }
  108. if (ind > 0 && loc == 0) {
  109. ind--;
  110. *off = uio->uio_iov[ind].iov_len;
  111. return (ind);
  112. }
  113. return (-1);
  114. }
  115. int
  116. cuio_apply(struct uio *uio, int off, int len,
  117. int (*f)(caddr_t, caddr_t, unsigned int), caddr_t fstate)
  118. {
  119. int rval, ind, uiolen;
  120. unsigned int count;
  121. if (len < 0)
  122. panic("cuio_apply: len %d < 0", len);
  123. if (off < 0)
  124. panic("cuio_apply: off %d < 0", off);
  125. ind = 0;
  126. while (off > 0) {
  127. if (ind >= uio->uio_iovcnt)
  128. panic("cuio_apply: ind %d >= uio_iovcnt %d for off",
  129. ind, uio->uio_iovcnt);
  130. uiolen = uio->uio_iov[ind].iov_len;
  131. if (off < uiolen)
  132. break;
  133. off -= uiolen;
  134. ind++;
  135. }
  136. while (len > 0) {
  137. if (ind >= uio->uio_iovcnt)
  138. panic("cuio_apply: ind %d >= uio_iovcnt %d for len",
  139. ind, uio->uio_iovcnt);
  140. count = min(uio->uio_iov[ind].iov_len - off, len);
  141. rval = f(fstate, (char *)uio->uio_iov[ind].iov_base + off,
  142. count);
  143. if (rval)
  144. return (rval);
  145. len -= count;
  146. off = 0;
  147. ind++;
  148. }
  149. return (0);
  150. }