2650 * if the size of the data to transfer is greater
2651 * that that requested then we can't do it this transfer.
2652 */
2653 if (reclen > uresid) {
2654 /*
2655 * Error if no entries have been returned yet.
2656 */
2657 if (uresid == oresid) {
2658 return (EINVAL);
2659 }
2660 break;
2661 }
2662
2663 /*
2664 * uiomove() updates both uiop->uio_resid and uiop->uio_offset
2665 * by the same amount. But we want uiop->uio_offset to change
2666 * in increments of LXPR_SDSIZE, which is different from the
2667 * number of bytes being returned to the user. So we set
2668 * uiop->uio_offset separately, ignoring what uiomove() does.
2669 */
2670 if (error = uiomove((caddr_t)dirent, reclen, UIO_READ, uiop)) {
2671 return (error);
2672 }
2673
2674 uiop->uio_offset = uoffset + LXPR_SDSIZE;
2675 }
2676
2677 /* Have run out of space, but could have just done last table entry */
2678 if (eofp) {
2679 *eofp =
2680 (uiop->uio_offset >= ((dirtablen+2) * LXPR_SDSIZE)) ? 1 : 0;
2681 }
2682 return (0);
2683 }
2684
2685
2686 static int
2687 lxpr_readdir_procdir(lxpr_node_t *lxpnp, uio_t *uiop, int *eofp)
2688 {
2689 /* bp holds one dirent64 structure */
2690 longlong_t bp[DIRENT64_RECLEN(LXPNSIZ) / sizeof (longlong_t)];
2691 dirent64_t *dirent = (dirent64_t *)bp;
2692 ssize_t oresid; /* save a copy for testing later */
2788 * if the size of the data to transfer is greater
2789 * that that requested then we can't do it this transfer.
2790 */
2791 if (reclen > uresid) {
2792 /*
2793 * Error if no entries have been returned yet.
2794 */
2795 if (uresid == oresid)
2796 return (EINVAL);
2797 break;
2798 }
2799
2800 /*
2801 * uiomove() updates both uiop->uio_resid and uiop->uio_offset
2802 * by the same amount. But we want uiop->uio_offset to change
2803 * in increments of LXPR_SDSIZE, which is different from the
2804 * number of bytes being returned to the user. So we set
2805 * uiop->uio_offset separately, in the increment of this for
2806 * the loop, ignoring what uiomove() does.
2807 */
2808 if (error = uiomove((caddr_t)dirent, reclen, UIO_READ, uiop))
2809 return (error);
2810 next:
2811 uiop->uio_offset = uoffset + LXPR_SDSIZE;
2812 }
2813
2814 if (eofp != NULL) {
2815 *eofp = (uiop->uio_offset >=
2816 ((v.v_proc + PROCDIRFILES + 2) * LXPR_SDSIZE)) ? 1 : 0;
2817 }
2818
2819 return (0);
2820 }
2821
2822 static int
2823 lxpr_readdir_piddir(lxpr_node_t *lxpnp, uio_t *uiop, int *eofp)
2824 {
2825 proc_t *p;
2826
2827 ASSERT(lxpnp->lxpr_type == LXPR_PIDDIR);
2828
2920 if (fip->fi_list[fd].uf_file == NULL)
2921 continue;
2922
2923 dirent->d_ino = lxpr_inode(LXPR_PID_FD_FD, lxpnp->lxpr_pid, fd);
2924 len = snprintf(dirent->d_name, LXPNSIZ, "%d", fd);
2925 ASSERT(len < LXPNSIZ);
2926 reclen = DIRENT64_RECLEN(len);
2927
2928 dirent->d_off = (off64_t)(uoffset + LXPR_SDSIZE);
2929 dirent->d_reclen = (ushort_t)reclen;
2930
2931 if (reclen > uresid) {
2932 /*
2933 * Error if no entries have been returned yet.
2934 */
2935 if (uresid == oresid)
2936 error = EINVAL;
2937 goto out;
2938 }
2939
2940 if (error = uiomove((caddr_t)dirent, reclen, UIO_READ, uiop))
2941 goto out;
2942 }
2943
2944 if (eofp != NULL) {
2945 *eofp =
2946 (uiop->uio_offset >= ((fddirsize+2) * LXPR_SDSIZE)) ? 1 : 0;
2947 }
2948
2949 out:
2950 mutex_exit(&fip->fi_lock);
2951 return (error);
2952 }
2953
2954
2955 /*
2956 * lxpr_readlink(): Vnode operation for VOP_READLINK()
2957 */
2958 /* ARGSUSED */
2959 static int
2960 lxpr_readlink(vnode_t *vp, uio_t *uiop, cred_t *cr, caller_context_t *ct)
|
2650 * if the size of the data to transfer is greater
2651 * that that requested then we can't do it this transfer.
2652 */
2653 if (reclen > uresid) {
2654 /*
2655 * Error if no entries have been returned yet.
2656 */
2657 if (uresid == oresid) {
2658 return (EINVAL);
2659 }
2660 break;
2661 }
2662
2663 /*
2664 * uiomove() updates both uiop->uio_resid and uiop->uio_offset
2665 * by the same amount. But we want uiop->uio_offset to change
2666 * in increments of LXPR_SDSIZE, which is different from the
2667 * number of bytes being returned to the user. So we set
2668 * uiop->uio_offset separately, ignoring what uiomove() does.
2669 */
2670 if ((error = uiomove((caddr_t)dirent, reclen, UIO_READ,
2671 uiop)) != 0)
2672 return (error);
2673
2674 uiop->uio_offset = uoffset + LXPR_SDSIZE;
2675 }
2676
2677 /* Have run out of space, but could have just done last table entry */
2678 if (eofp) {
2679 *eofp =
2680 (uiop->uio_offset >= ((dirtablen+2) * LXPR_SDSIZE)) ? 1 : 0;
2681 }
2682 return (0);
2683 }
2684
2685
2686 static int
2687 lxpr_readdir_procdir(lxpr_node_t *lxpnp, uio_t *uiop, int *eofp)
2688 {
2689 /* bp holds one dirent64 structure */
2690 longlong_t bp[DIRENT64_RECLEN(LXPNSIZ) / sizeof (longlong_t)];
2691 dirent64_t *dirent = (dirent64_t *)bp;
2692 ssize_t oresid; /* save a copy for testing later */
2788 * if the size of the data to transfer is greater
2789 * that that requested then we can't do it this transfer.
2790 */
2791 if (reclen > uresid) {
2792 /*
2793 * Error if no entries have been returned yet.
2794 */
2795 if (uresid == oresid)
2796 return (EINVAL);
2797 break;
2798 }
2799
2800 /*
2801 * uiomove() updates both uiop->uio_resid and uiop->uio_offset
2802 * by the same amount. But we want uiop->uio_offset to change
2803 * in increments of LXPR_SDSIZE, which is different from the
2804 * number of bytes being returned to the user. So we set
2805 * uiop->uio_offset separately, in the increment of this for
2806 * the loop, ignoring what uiomove() does.
2807 */
2808 if ((error = uiomove((caddr_t)dirent, reclen, UIO_READ,
2809 uiop)) != 0)
2810 return (error);
2811 next:
2812 uiop->uio_offset = uoffset + LXPR_SDSIZE;
2813 }
2814
2815 if (eofp != NULL) {
2816 *eofp = (uiop->uio_offset >=
2817 ((v.v_proc + PROCDIRFILES + 2) * LXPR_SDSIZE)) ? 1 : 0;
2818 }
2819
2820 return (0);
2821 }
2822
2823 static int
2824 lxpr_readdir_piddir(lxpr_node_t *lxpnp, uio_t *uiop, int *eofp)
2825 {
2826 proc_t *p;
2827
2828 ASSERT(lxpnp->lxpr_type == LXPR_PIDDIR);
2829
2921 if (fip->fi_list[fd].uf_file == NULL)
2922 continue;
2923
2924 dirent->d_ino = lxpr_inode(LXPR_PID_FD_FD, lxpnp->lxpr_pid, fd);
2925 len = snprintf(dirent->d_name, LXPNSIZ, "%d", fd);
2926 ASSERT(len < LXPNSIZ);
2927 reclen = DIRENT64_RECLEN(len);
2928
2929 dirent->d_off = (off64_t)(uoffset + LXPR_SDSIZE);
2930 dirent->d_reclen = (ushort_t)reclen;
2931
2932 if (reclen > uresid) {
2933 /*
2934 * Error if no entries have been returned yet.
2935 */
2936 if (uresid == oresid)
2937 error = EINVAL;
2938 goto out;
2939 }
2940
2941 if ((error = uiomove((caddr_t)dirent, reclen, UIO_READ,
2942 uiop)) != 0)
2943 goto out;
2944 }
2945
2946 if (eofp != NULL) {
2947 *eofp =
2948 (uiop->uio_offset >= ((fddirsize+2) * LXPR_SDSIZE)) ? 1 : 0;
2949 }
2950
2951 out:
2952 mutex_exit(&fip->fi_lock);
2953 return (error);
2954 }
2955
2956
2957 /*
2958 * lxpr_readlink(): Vnode operation for VOP_READLINK()
2959 */
2960 /* ARGSUSED */
2961 static int
2962 lxpr_readlink(vnode_t *vp, uio_t *uiop, cred_t *cr, caller_context_t *ct)
|