|
|
1.1 root 1: #define _DDI_DKI 1
2: #define _SYSV3 1
3:
4: /*
5: * Implementations of the functions which manipulate the uio(4) structure
6: * under the DDI/DKI. This function runs in _SYSV3 mode to interface with
7: * the iBCS2 Coherent kernel.
8: */
9: /*
10: *-IMPORTS:
11: * <common/ccompat.h>
12: * __CONST__
13: * __EXTERN_C_BEGIN__
14: * __EXTERN_C_END__
15: * __USE_PROTO__
16: * __ARGS ()
17: * __PROTO ()
18: * <sys/debug.h>
19: * ASSERT ()
20: * <sys/types.h>
21: * _VOID
22: * size_t
23: * <sys/errno.h>
24: * EFAULT
25: * <limits.h>
26: * CHAR_BIT
27: * UCHAR_MAX
28: * <string.h>
29: * memcpy ()
30: */
31:
32: #include <common/ccompat.h>
33: #include <sys/debug.h>
34: #include <sys/types.h>
35: #include <sys/errno.h>
36: #include <limits.h>
37: #include <string.h>
38:
39: #include <sys/uio.h>
40:
41: #if __COHERENT__
42:
43: #include <sys/coherent.h>
44:
45:
46: /*
47: * Routines to perform transfers between the user and kernel address spaces.
48: */
49:
50: __EXTERN_C_BEGIN__
51:
52: int kucopy __PROTO ((__CONST__ caddr_t ker, caddr_t usr,
53: size_t n));
54: int ukcopy __PROTO ((__CONST__ caddr_t usr, caddr_t ker,
55: size_t n));
56: int getubd __PROTO ((__CONST__ caddr_t usr));
57: void putubd __PROTO ((caddr_t usr, int ch));
58:
59: __EXTERN_C_END__
60:
61: #define TOUSER(usr,ker,n) kucopy ((caddr_t) ker, (caddr_t) usr, n)
62: #define FROMUSER(ker,usr,n) ukcopy ((caddr_t) usr, (caddr_t) ker, n)
63:
64: #define PUTBYTE(c,usr) (putubd (usr, c), u.u_error)
65: #define GETBYTE(usr) ((unsigned char) getubd (usr) - \
66: (u.u_error > 0 ? UCHAR_MAX : 0))
67:
68: #else /* if ! defined (COHERENT) */
69:
70:
71: #define TOUSER(usr,ker,n) (memcpy ((usr), (ker), (n)), (n))
72: #define FROMUSER(ker,usr,n) (memcpy ((ker), (usr), (n)), (n))
73:
74: #define PUTBYTE(c,usr) (* (usr) = (c), 0)
75: #define GETBYTE(usr) (* (unsigned char *) (usr))
76:
77:
78: #endif
79:
80:
81: /*
82: * For some reason the System V DDI/DKI uses "longs" and "ints" in many cases
83: * where a size_t is far more appropriate. We will only work for cases where
84: * the request does not exceed the half range of a size_t.
85: */
86:
87: #define SIZE_T_MAX ((1UL << (sizeof (size_t) * CHAR_BIT - 1)) - 1)
88:
89:
90: /*
91: *-STATUS:
92: * DDI/DKI
93: *
94: *-NAME:
95: * bcopy Copy data between address locations in the kernel.
96: *
97: *-SYNOPSIS:
98: * #include <sys/types.h>
99: *
100: * void bcopy (caddr_t from, caddr_t to, size_t bcount);
101: *
102: *-ARGUMENTS:
103: * from Source address from which the copy is made.
104: *
105: * to Destination address to which the copy is made.
106: *
107: * bcount Number of bytes to be copied.
108: *
109: *-DESCRIPTION:
110: * bcopy () copies "bcount" bytes from one kernel address to another. It
111: * chooses the best algorithm based on address alignment and number of
112: * bytes to copy. If the input and output addresses over, the function
113: * executes, but the results are undefined.
114: *
115: *-RETURN VALUE:
116: * None.
117: *
118: *-LEVEL:
119: * Base or interrupt.
120: *
121: *-NOTES:
122: * Does not sleep.
123: *
124: * Driver-defined basic locks, read/write locks, and sleep locks may be
125: * held across calls to this function.
126: *
127: * The source and destination address ranges must both be within the
128: * kernel address space and must be memory resident. No range checking is
129: * done. Since there is no mechanism by which drivers that conform to the
130: * rules of the DDI/DKI can obtain and use a kernel address which is not
131: * memory resident (an address which is paged out), DDI/DKI conforming
132: * drivers can assume that any address to which they have access is
133: * memory resident and therefore a valid argument to bcopy (). Addresses
134: * within user space are not valid arguments, and specifying such an
135: * address may cause the driver to corrupt the system in an unpredictable
136: * way. For copying between kernel and user space, drivers must use an
137: * appropriate function defined for that purpose (for example, copyin (),
138: * copyout (), uiomove (), ureadc (), or uwritec ()).
139: *
140: *-SEE ALSO:
141: * bzero (), copyin (), copyout (), uiomove (), ureadc (), uwritec ()
142: */
143:
144: #if __USE_PROTO__
145: void (bcopy) (__CONST__ _VOID * from, _VOID * to, size_t bcount)
146: #else
147: void
148: bcopy __ARGS ((from, to, bcount))
149: __CONST__ _VOID
150: * from;
151: _VOID * to;
152: size_t bcount;
153: #endif
154: {
155: ASSERT (to != NULL);
156:
157: (void) memcpy (to, from, bcount);
158: }
159:
160:
161: /*
162: *-STATUS:
163: * DDI/DKI
164: *
165: *-NAME:
166: * bzero Clear memory for a given number of bytes.
167: *
168: *-SYNOPSIS:
169: * #include <sys/types.h>
170: *
171: * void bzero (caddr_t addr, size_t bytes);
172: *
173: *-ARGUMENTS:
174: * addr Starting virtual address of memory to be cleared.
175: *
176: * bytes Number of bytes to clear.
177: *
178: *-DESCRIPTION:
179: * The bzero () function clears a contiguous portion of memory by filling
180: * the memory with zeroes. It chooses the best algorithm based on address
181: * alignment and number of bytes to clear.
182: *
183: *-RETURN VALUE:
184: * None.
185: *
186: *-LEVEL:
187: * Base or interrupt.
188: *
189: *-NOTES:
190: * Does not sleep.
191: *
192: * Driver-defined basic locks, read/write locks, and sleep locks may be
193: * held across calls to this function.
194: *
195: * There are no alignment restrictions on "addr", and no length
196: * restrictions on "bytes", other than the address range specified must
197: * be within the kernel address space and must be memory resident. No
198: * range checking is done. Since there is no mechanism by which drivers
199: * that conform to the rules of the DDI/DKI can obtain and use a kernel
200: * address that is not memory resident (an address that is paged out),
201: * DDI/DKI conforming drivers can assume that any address to which they
202: * have access is memory resident and therefore a valid argument to
203: * bzero (). An address within user space is not a valid argument to
204: * bzero (), and specifying such an address may cause the driver to
205: * corrupt the system in an unpredictable way.
206: *
207: *-SEE ALSO:
208: * bcopy (), kmem_zalloc ()
209: */
210:
211: #if __USE_PROTO__
212: void (bzero) (_VOID * addr, size_t bytes)
213: #else
214: void
215: bzero __ARGS ((addr, bytes))
216: _VOID * addr;
217: size_t bytes;
218: #endif
219: {
220: ASSERT (addr != NULL);
221:
222: (void) memset (addr, 0, bytes);
223: }
224:
225:
226: /*
227: *-STATUS:
228: * DDI/DKI
229: *
230: *-NAME:
231: * copyin Copy data from a user buffer to a driver buffer.
232: *
233: *-SYNOPSIS:
234: * #include <sys/types.h>
235: *
236: * int copyin (caddr_t userbuf, caddr_t driverbuf, size_t count);
237: *
238: *-ARGUMENTS:
239: * userbuf User source address from which copy is made.
240: *
241: * driverbuf Driver destination address to which copy is made.
242: *
243: * count Number of bytes to copy.
244: *
245: *-DESCRIPTION:
246: * copyin () copies "count" bytes of data from the user virtual address
247: * specified by "userbuf" to the kernel virtual address specified by
248: * "driverbuf". The driver must ensure that adequate space is allocated
249: * for the destination address.
250: *
251: * copyin () chooses the best algorithm based on address alignment and
252: * number of bytes to copy. Although the source and destination addresses
253: * are not required to be word aligned, word aligned addresses may result
254: * in a more efficient copy.
255: *
256: *-RETURN VALUE:
257: * If the copy is successful, 0 is returned. Otherwise, -1 is returned to
258: * indicate the specified user address range is invalid.
259: *
260: *-LEVEL:
261: * Base only.
262: *
263: *-NOTES:
264: * May sleep.
265: *
266: * Drivers usually convert a return value of -1 to an EFAULT error.
267: *
268: * Driver-defined basic locks and read/write locks may not be held across
269: * calls to this function.
270: *
271: * Driver-defined sleep locks may be held across calls to this function.
272: *
273: * When holding sleep locks across calls to this function, drivers must
274: * be careful to avoid creating a deadlock. During the data transfer,
275: * page fault resolution might result in another I/O to the same device.
276: * For example, this could occur if the driver controls the disk drive
277: * used as the swap device.
278: *
279: * The driver destination buffer must be completely within the kernel
280: * address space, or the system can panic.
281: *
282: *-SEE ALSO:
283: * copyout (), uiomove (), ureadc (), uwritec ()
284: */
285:
286: #if __USE_PROTO__
287: int (copyin) (_VOID * userbuf, _VOID * driverbuf, size_t count)
288: #else
289: int
290: copyin __ARGS ((userbuf, driverbuf, count))
291: _VOID * userbuf;
292: _VOID * driverbuf;
293: size_t count;
294: #endif
295: {
296: ASSERT (driverbuf != 0);
297:
298: return FROMUSER (driverbuf, userbuf, count) != count ? -1 : 0;
299: }
300:
301:
302: /*
303: *-STATUS:
304: * DDI/DKI
305: *
306: *-NAME:
307: * copyout Copy data from a driver buffer to a user buffer.
308: *
309: *-SYNOPSIS:
310: * #include <sys/types.h>
311: *
312: * int copyout (caddr_t driverbuf, caddr_t userbuf, size_t count);
313: *
314: *-ARGUMENTS:
315: * driverbuf Driver source address from which copy is made.
316: *
317: * userbuf User destination address to which copy is made.
318: *
319: * count Number of bytes to copy.
320: *
321: *-DESCRIPTION:
322: * copyout () copies "count" bytes of data from the kernel virtual
323: * address specified by "driverbuf" to the user virtual address specified
324: * by "userbuf".
325: *
326: * copyout () chooses the best algorithm based on address alignment and
327: * number of bytes to copy. Although the source and destination addresses
328: * are not required to be word aligned, word aligned addresses may result
329: * in a more efficient copy.
330: *
331: *-RETURN VALUE:
332: * If the copy is successful, 0 is returned. Otherwise, -1 is returned to
333: * indicate that the specified user address range is not valid.
334: *
335: *-LEVEL:
336: * Base only.
337: *
338: *-NOTES:
339: * May sleep.
340: *
341: * Drivers usually convert a return value of -1 into an EFAULT error.
342: *
343: * Driver-defined basic locks and read/write locks may not be held across
344: * calls to this function.
345: *
346: * Driver-defined sleep locks may be held across calls to this function.
347: *
348: * When holding sleep locks across calls to this function, drivers must
349: * be careful to avoid creating a deadlock. During the data transfer,
350: * page fault resolution may result in another I/O to the same device.
351: * For example, this could occur if the driver controls the disk drive
352: * used as the swap device.
353: *
354: * The driver source buffer must be completely within the kernel address
355: * space, or the system can panic.
356: *
357: *-SEE ALSO:
358: * copyin (), uiomove (), ureadc (), uwritec ()
359: */
360:
361: #if __USE_PROTO__
362: int (copyout) (_VOID * driverbuf, _VOID * userbuf, size_t count)
363: #else
364: int
365: copyout __ARGS ((driverbuf, userbuf, count))
366: _VOID * driverbuf;
367: _VOID * userbuf;
368: size_t count;
369: #endif
370: {
371: ASSERT (driverbuf != NULL);
372:
373: return TOUSER (userbuf, driverbuf, count) != count ? -1 : 0;
374: }
375:
376:
377: /*
378: *-STATUS:
379: * DDI/DKI
380: *
381: *-NAME:
382: * uiomove Copy data using uio structure.
383: *
384: *-SYNOPSIS:
385: * #include <sys/types.h>
386: * #include <sys/uio.h>
387: *
388: * int uiomove (caddr_t addr, long nbytes, uio_rw_t rwflag, uio_t * uiop);
389: *
390: *-ARGUMENTS:
391: * addr Source/destination kernel address of the copy.
392: *
393: * nbytes Number of bytes to copy.
394: *
395: * rwflag Flag indicating read or write operation. Possible
396: * values are UIO_READ and UIO_WRITE.
397: *
398: * uiop Pointer to the "uio" structure for the copy.
399: *
400: *-DESCRIPTION:
401: * The uiomove () function copies "nbytes" of data between the kernel
402: * address "addr" and the space defined by the "uio" structure pointed to
403: * by "uiop". If "rwflg" is "UIO_READ", the data is copied from "addr" to
404: * the space described by the "uio" structure. If "rwflag" is "UIO_WRITE",
405: * the data is copied from the space described by the "uio" structure to
406: * "addr".
407: *
408: * The "uio_segflg" member of the "uio" structure specifies the type of
409: * space described by the "uio" structure. If "uio_segflg" is set to
410: * "UIO_SYSSPACE" the "uio" structure describes a portion of the kernel
411: * address space. If "uio_segflg" is set to "UIO_USERSPACE" the "uio"
412: * structure describes a portion of the user address space.
413: *
414: * If the copy is successful, uiomove () updates the appropriate members
415: * of the "uio" and "iovec" structures to reflect the copy ("uio_offset"
416: * and "iov_base" and increased by "nbytes" and "uio_resid" and "iov_len"
417: * are decreased by "nbytes").
418: *
419: *-RETURN VALUE:
420: * uiomove () returns 0 on success or an error number on failure. If a
421: * partial transfer occurs, the "uio" structure is updated to indicate
422: * the amount not transferred and an error is returned.
423: *
424: *-LEVEL:
425: * Base only if "uio_segflg" is set to "UIO_USERSPACE". Base or interrupt
426: * if "uio_segflg" is set to "UIO_SYSSPACE".
427: *
428: *-NOTES:
429: * May sleep if "uio_segflg" is set to "UIO_USERSPACE".
430: *
431: * Driver-defined basic locks and read/write locks may be held across
432: * calls to this function if "uio_segflg" is "UIO_SYSSPACE" but may not be
433: * held if "uio_segflg" is "UIO_USERSPACE".
434: *
435: * Driver-defined sleep locks may be held across calls to this function
436: * regardless of the value of "uio_segflg".
437: *
438: * When holding locks across calls to this function, drivers must be
439: * careful to avoid creating a deadlock. During the data transfer, page
440: * fault resolution might result in another I/O to the same device. For
441: * example, this could occur if the driver controls the disk drive used
442: * as the swap device.
443: *
444: * If "addr" specifies an address in user space, or if the value of
445: * "uio_segflg" is not consistent with the type of address space
446: * described by the "uio" structure, the system can panic.
447: *
448: *-SEE ALSO:
449: * bcopy (), copyin (), copyout (), ureadc (), uwritec (), iovec, uio
450: */
451:
452: #if __USE_PROTO__
453: int (uiomove) (caddr_t addr, long nbytes, uio_rw_t rwflag, uio_t * uiop)
454: #else
455: int
456: uiomove __ARGS ((addr, nbytes, rwflag, uiop))
457: caddr_t addr;
458: long nbytes;
459: uio_rw_t rwflag;
460: uio_t * uiop;
461: #endif
462: {
463: iovec_t * scan;
464: iovec_t * end;
465:
466: ASSERT (addr != NULL);
467: ASSERT (uiop != NULL);
468: ASSERT (nbytes > 0);
469: ASSERT (nbytes <= SIZE_T_MAX);
470: ASSERT (uiop->uio_resid <= SIZE_T_MAX);
471: ASSERT (rwflag == UIO_READ || rwflag == UIO_WRITE);
472: ASSERT (uiop->uio_segflg == UIO_SYSSPACE ||
473: uiop->uio_segflg == UIO_USERSPACE);
474: ASSERT (uiop->uio_resid > 0);
475:
476: for (scan = uiop->uio_iov, end = scan + uiop->uio_iovcnt ;
477: nbytes > 0 ; scan ++) {
478: size_t size;
479:
480:
481: /*
482: * Now we are going to move a single block of the scatter/
483: * gather request. We assume that scan->iov_len is
484: * less than or equal to uiop->uio_resid!
485: */
486:
487: ASSERT (scan < end);
488: ASSERT (scan->iov_len > 0);
489: ASSERT (scan->iov_len <= uiop->uio_resid);
490:
491: if (nbytes < (size = (size_t) uiop->uio_iov->iov_len))
492: size = (size_t) nbytes;
493:
494: if (size == 0)
495: continue;
496:
497:
498: /*
499: * Transfer a segment as indicated.
500: */
501:
502: if (rwflag == UIO_READ) {
503:
504: if (uiop->uio_segflg == UIO_USERSPACE) {
505: /*
506: * Transfers involving user memory may sleep
507: * due to paging!
508: */
509:
510: if (TOUSER (scan->iov_base, addr,
511: size) != size)
512: break;
513: } else
514: memcpy (scan->iov_base, addr, size);
515: } else {
516:
517: if (uiop->uio_segflg == UIO_USERSPACE) {
518: /*
519: * Transfers involving user memory may sleep
520: * due to paging!
521: */
522:
523:
524: if (FROMUSER (addr, scan->iov_base,
525: size) != size)
526: break;
527: } else
528: memcpy (addr, scan->iov_base, size);
529: }
530:
531: addr += size;
532: nbytes -= size;
533:
534: uiop->uio_resid -= size;
535: uiop->uio_offset += size;
536:
537: scan->iov_len -= size;
538: scan->iov_base += size;
539: }
540:
541: return nbytes == 0 ? 0 : EFAULT;
542: }
543:
544:
545: /*
546: *-STATUS:
547: * DDI/DKI
548: *
549: *-NAME:
550: * ureadc Copy a character to space described by a "uio"
551: * structure.
552: *
553: *-SYNOPSIS:
554: * #include <sys/uio.h>
555: *
556: * int ureadc (int c, uio_t * uiop);
557: *
558: *-ARGUMENTS:
559: * c The character to be copied.
560: *
561: * uiop Pointer to the "uio" structure.
562: *
563: *-DESCRIPTION:
564: * ureadc () copies the character "c" into the space described by the
565: * "uio" structure pointed to by "uiop".
566: *
567: * The "uio_segflg" member of the "uio" structure specifies the type of
568: * space to which the copy is made. If "uio_segflg" is set to
569: * "UIO_SYSSPACE" the character is copied to a kernel address. If
570: * "uio_segflg" is set to "UIO_USERSPACE" the character is copied to a
571: * user address.
572: *
573: * If the character is successfully copied, ureadc () updates the
574: * appropriate members of the "uio" and "iovec" structures to reflect
575: * the copy ("uio_offset" and "iov_base" are incremented and "uio_resid"
576: * and "iov_len" are decremented).
577: *
578: *-RETURN VALUE:
579: * ureadc () returns 0 on success or an error number on failure.
580: *
581: *-LEVEL:
582: * Base only if "uio_segflg" is set to "UIO_USERSPACE". Base or interrupt
583: * if "uio_segflg" is set to "UIO_SYSSPACE".
584: *
585: *-NOTES:
586: * May sleep if "uio_segflg" is set to "UIO_USERSPACE".
587: *
588: * Driver-defined basic locks and read/write locks may be held across
589: * calls to this function if "uio_segflg" is set to "UIO_SYSSPACE" but
590: * may not be held if "uio_segflg" is set to "UIO_USERSPACE".
591: *
592: * Driver-defined sleep locks may be held across calls to this function
593: * regardless of the value of "uio_segflg".
594: *
595: * When holding locks across calls to this function, drivers must be
596: * careful to avoid creating a deadlock. During the data transfer, page
597: * fault resolution might result in another I/O to the same device. For
598: * example, this could occur if the driver controls the disk drive used
599: * as the swap device.
600: *
601: *-SEE ALSO:
602: * uiomove (), uwritec (), iovec, uio
603: */
604:
605: #if __USE_PROTO__
606: int (ureadc) (int c, uio_t * uiop)
607: #else
608: int
609: ureadc __ARGS ((c, uiop))
610: int c;
611: uio_t * uiop;
612: #endif
613: {
614: iovec_t * scan;
615:
616:
617: ASSERT (uiop != NULL);
618: ASSERT (uiop->uio_segflg == UIO_SYSSPACE ||
619: uiop->uio_segflg == UIO_USERSPACE);
620: ASSERT (uiop->uio_segflg == UIO_SYSSPACE ||
621: uiop->uio_segflg == UIO_USERSPACE);
622: ASSERT (uiop->uio_resid > 0);
623:
624: /*
625: * What to do if the structure is empty? As indicated above, I
626: * consider that an error worthy of a kernel panic. At a minimum we
627: * should make it a recoverable error as the code below does.
628: */
629:
630: if (uiop->uio_resid <= 0)
631: return EFAULT;
632:
633:
634: /*
635: * For now, we loop over any initial empty segments. It is not clear
636: * to me whether this code can alter "uio_iov" or not, although we
637: * definitely are permitted to maintain a separate entry in the
638: * structure to the same effect.
639: */
640:
641: for (scan = uiop->uio_iov ; scan->iov_len == 0 ; scan ++)
642: ;
643:
644: ASSERT (scan < uiop->uio_iov + uiop->uio_iovcnt);
645:
646: /*
647: * Now, write a single character to the space indicated.
648: */
649:
650: if (uiop->uio_segflg == UIO_USERSPACE) {
651:
652: if (PUTBYTE (c, scan->iov_base) != 0)
653: return EFAULT;
654:
655: scan->iov_base ++;
656: } else
657: * scan->iov_base ++ = c;
658:
659: scan->iov_len ++;
660:
661: uiop->uio_resid --;
662: uiop->uio_offset ++;
663:
664: return 0;
665: }
666:
667:
668: /*
669: *-STATUS:
670: * DDI/DKI
671: *
672: *-NAME:
673: * uwritec Return a character from space described by a "uio"
674: * structure.
675: *
676: *-SYNOPSIS:
677: * #include <sys/uio.h>
678: *
679: * int uwritec (uio_t * uiop);
680: *
681: *-ARGUMENTS:
682: * uiop Pointer to the "uio" structure.
683: *
684: *-DESCRIPTION:
685: * uwritec () copies a character from the space described by the "uio"
686: * structure pointed to by "uiop" and returns the character to the
687: * caller.
688: *
689: * The "uio_segflg" member of the "uio" structure specifies the type of
690: * space from which the copy is made. If "uio_segflg" is set to
691: * "UIO_SYSSPACE" the character is copied from a kernel address. If
692: * "uio_segflg" is set to "UIO_USERSPACE" the character is copied from a
693: * user address.
694: *
695: * If the character is successfully copied, uwritec () updates the
696: * appropriate members of the "uio" and "iovec" structures to reflect the
697: * copy ("uio_offset" and "iov_base" are incremented and "uio_resid" and
698: * "iov_len" are decremented).
699: *
700: *-RETURN VALUE:
701: * If successful, uwritec () returns the character. -1 is returned if the
702: * space described by the "uio" structure is empty or if there is an
703: * error.
704: *
705: *-LEVEL:
706: * Base only if "uio_segflg" is set to "UIO_USERSPACE". Base or interrupt
707: * if "uio_segflg" is set to "UIO_SYSSPACE".
708: *
709: *-NOTES:
710: * May sleep if "uio_segflg" is set to "UIO_USERSPACE".
711: * Driver-defined basic locks and read/write locks may be held across
712: * calls to this function if "uio_segflg" is "UIO_SYSSPACE" but may not
713: * be held if "uio_segflg" is "UIO_USERSPACE".
714: *
715: * Driver-defined sleep locks may be held across calls to this function
716: * regardless of the value of "uio_segflg".
717: *
718: * When holding locks across calls to this function, drivers must be
719: * careful to avoid creating a deadlock. During the data transfer, page
720: * fault resolution might result in another I/O to the same device. For
721: * example, this could occur if the driver controls the disk drive used
722: * as the swap device.
723: *
724: *-SEE ALSO:
725: * uiomove (), ureadc (), iovec, uio
726: */
727:
728: #if __USE_PROTO__
729: int (uwritec) (uio_t * uiop)
730: #else
731: int
732: uwritec __ARGS ((uiop))
733: uio_t * uiop;
734: #endif
735: {
736: iovec_t * scan;
737: int c;
738:
739:
740: ASSERT (uiop != NULL);
741: ASSERT (uiop->uio_segflg == UIO_SYSSPACE ||
742: uiop->uio_segflg == UIO_USERSPACE);
743: ASSERT (uiop->uio_segflg == UIO_SYSSPACE ||
744: uiop->uio_segflg == UIO_USERSPACE);
745:
746: /*
747: * What to do if the structure is empty? Unlike ureadc (), we are
748: * allowed to return -1.
749: */
750:
751: if (uiop->uio_resid <= 0)
752: return -1;
753:
754:
755: /*
756: * For now, we loop over any initial empty segments. It is not clear
757: * to me whether this code can alter "uio_iov" or not, although we
758: * definitely are permitted to maintain a separate entry in the
759: * structure to the same effect.
760: */
761:
762: for (scan = uiop->uio_iov ; scan->iov_len == 0 ; scan ++)
763: ;
764:
765: ASSERT (scan < uiop->uio_iov + uiop->uio_iovcnt);
766:
767: /*
768: * Now, read a single character from the space indicated.
769: */
770:
771: if (uiop->uio_segflg == UIO_USERSPACE) {
772:
773: if ((c = GETBYTE (scan->iov_base)) < 0)
774: return -1;
775:
776: scan->iov_base ++;
777: } else
778: c = * scan->iov_base ++;
779:
780: scan->iov_len --;
781:
782: uiop->uio_resid --;
783: uiop->uio_offset ++;
784:
785: return c;
786: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.