| 104 | |
| 105 | #ifndef FSTACK |
| 106 | static int |
| 107 | pcblist_kvm(u_long count_off, u_long gencnt_off, u_long head_off, char **bufp) |
| 108 | { |
| 109 | struct unp_head head; |
| 110 | struct unpcb *unp, unp0, unp_conn; |
| 111 | u_char sun_len; |
| 112 | struct socket so; |
| 113 | struct xunpgen xug; |
| 114 | struct xunpcb xu; |
| 115 | unp_gen_t unp_gencnt; |
| 116 | u_int unp_count; |
| 117 | char *buf, *p; |
| 118 | size_t len; |
| 119 | |
| 120 | if (count_off == 0 || gencnt_off == 0) |
| 121 | return (-2); |
| 122 | if (head_off == 0) |
| 123 | return (-1); |
| 124 | kread(count_off, &unp_count, sizeof(unp_count)); |
| 125 | len = 2 * sizeof(xug) + (unp_count + unp_count / 8) * sizeof(xu); |
| 126 | if ((buf = malloc(len)) == NULL) { |
| 127 | xo_warnx("malloc %lu bytes", (u_long)len); |
| 128 | return (-2); |
| 129 | } |
| 130 | p = buf; |
| 131 | |
| 132 | #define COPYOUT(obj, size) do { \ |
| 133 | if (len < (size)) { \ |
| 134 | xo_warnx("buffer size exceeded"); \ |
| 135 | goto fail; \ |
| 136 | } \ |
| 137 | bcopy((obj), p, (size)); \ |
| 138 | len -= (size); \ |
| 139 | p += (size); \ |
| 140 | } while (0) |
| 141 | |
| 142 | #define KREAD(off, buf, len) do { \ |
| 143 | if (kread((uintptr_t)(off), (buf), (len)) != 0) \ |
| 144 | goto fail; \ |
| 145 | } while (0) |
| 146 | |
| 147 | /* Write out header. */ |
| 148 | kread(gencnt_off, &unp_gencnt, sizeof(unp_gencnt)); |
| 149 | xug.xug_len = sizeof xug; |
| 150 | xug.xug_count = unp_count; |
| 151 | xug.xug_gen = unp_gencnt; |
| 152 | xug.xug_sogen = 0; |
| 153 | COPYOUT(&xug, sizeof xug); |
| 154 | |
| 155 | /* Walk the PCB list. */ |
| 156 | xu.xu_len = sizeof xu; |
| 157 | KREAD(head_off, &head, sizeof(head)); |
| 158 | LIST_FOREACH(unp, &head, unp_link) { |
| 159 | xu.xu_unpp = (uintptr_t)unp; |
| 160 | KREAD(unp, &unp0, sizeof (*unp)); |
| 161 | unp = &unp0; |
| 162 | |
| 163 | if (unp->unp_gencnt > unp_gencnt) |