+int
+proc_listfd_kqueue(proc_t p, int32_t *fdlist, int len)
+{
+ int numfds;
+ struct fileproc * fp;
+ int n;
+ int count = 0;
+
+ numfds = p->p_fd->fd_nfiles;
+ if (len < numfds) {
+ return -1;
+ }
+
+ proc_fdlock(p);
+ for (n = 0; ((n < numfds) && (n < p->p_fd->fd_nfiles)); n++) {
+ if (((fp = p->p_fd->fd_ofiles[n]) != 0)
+ && ((p->p_fd->fd_ofileflags[n] & UF_RESERVED) == 0)
+ && (FILEGLOB_DTYPE(fp->f_fglob) == PROX_FDTYPE_KQUEUE)) {
+ fdlist[count++] = n;
+ }
+ }
+ proc_fdunlock(p);
+ return count;
+}
+
+int
+proc_kqueue_udata_info(proc_t p, int32_t fd, uint64_t *buffer, int bufsize)
+{
+ struct kqueue *kq;
+ struct fileproc * fp = NULL;
+ int retval;
+
+ if (fd == -1) {
+ /* wqkqueue is initialized on-demand */
+ if ((kq = p->p_wqkqueue) == NULL) {
+ return 0;
+ }
+ } else {
+ int error = fp_getfkq(p, fd, &fp, &kq);
+ if (error != 0) {
+ return 0;
+ }
+ }
+
+ retval = pid_kqueue_udatainfo(p, kq, buffer, bufsize);
+ if (fp) {
+ fp_drop(p, fd, fp , 0);
+ }
+
+ return retval;
+}
+
+int
+proc_list_uptrs(proc_t p, uint64_t *udata_buffer, int size)
+{
+ int32_t *fdlist = NULL;
+ int nfds;
+ int i;
+ int count = 0;
+ int ret;
+ int knote_max = 4096;
+ uint64_t *buffer;
+ int bufsize = knote_max * sizeof(uint64_t);
+
+ fdlist = (int32_t *)kalloc((OPEN_MAX + 1) * sizeof(int32_t));
+ if (!fdlist) {
+ return -1;
+ }
+
+ nfds = proc_listfd_kqueue(p, &fdlist[1], OPEN_MAX);
+ if (nfds < 0 || nfds > OPEN_MAX) {
+ kfree(fdlist, (OPEN_MAX + 1) * sizeof(int32_t));
+ return 0;
+ }
+
+ /* Add FD -1, the implicit workq kqueue */
+ fdlist[0] = -1;
+ nfds++;
+
+ if (size == 0) {
+ bufsize = 0;
+ buffer = NULL;
+ } else {
+ bufsize = knote_max * sizeof(uint64_t);
+ buffer = (uint64_t *)kalloc(bufsize);
+ }
+
+ for (i = 0; i < nfds; i++) {
+again:
+ ret = proc_kqueue_udata_info(p, fdlist[i], buffer, bufsize);
+ if (bufsize != 0 && ret > knote_max) {
+ kfree(buffer, bufsize);
+ knote_max = ret + 32;
+ bufsize = knote_max * sizeof(uint64_t);
+ buffer = kalloc(bufsize);
+ goto again;
+ }
+
+ if (ret == 0)
+ continue;
+
+ /* Copy the udata ptrs */
+ if (size >= (int)((count + ret) * sizeof(uint64_t))) {
+ memcpy(&udata_buffer[count], buffer, ret * sizeof(uint64_t));
+ }
+ count = count + ret;
+ }
+
+ kfree(fdlist, (OPEN_MAX + 1) * sizeof(int32_t));
+ if (buffer) {
+ kfree(buffer, bufsize);
+ }
+ return count;
+}
+