+
+int
+fill_pipeinfo(struct pipe * cpipe, struct pipe_info * pinfo)
+{
+#if CONFIG_MACF
+ int error;
+#endif
+ struct timeval now;
+ struct vinfo_stat * ub;
+ int pipe_size = 0;
+ int pipe_count;
+
+ if (cpipe == NULL)
+ return (EBADF);
+ PIPE_LOCK(cpipe);
+
+#if CONFIG_MACF
+ error = mac_pipe_check_stat(kauth_cred_get(), cpipe);
+ if (error) {
+ PIPE_UNLOCK(cpipe);
+ return (error);
+ }
+#endif
+ if (cpipe->pipe_buffer.buffer == 0) {
+ /*
+ * must be stat'ing the write fd
+ */
+ if (cpipe->pipe_peer) {
+ /*
+ * the peer still exists, use it's info
+ */
+ pipe_size = cpipe->pipe_peer->pipe_buffer.size;
+ pipe_count = cpipe->pipe_peer->pipe_buffer.cnt;
+ } else {
+ pipe_count = 0;
+ }
+ } else {
+ pipe_size = cpipe->pipe_buffer.size;
+ pipe_count = cpipe->pipe_buffer.cnt;
+ }
+ /*
+ * since peer's buffer is setup ouside of lock
+ * we might catch it in transient state
+ */
+ if (pipe_size == 0)
+ pipe_size = PIPE_SIZE;
+
+ ub = &pinfo->pipe_stat;
+
+ bzero(ub, sizeof(*ub));
+ ub->vst_mode = S_IFIFO | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
+ ub->vst_blksize = pipe_size;
+ ub->vst_size = pipe_count;
+ if (ub->vst_blksize != 0)
+ ub->vst_blocks = (ub->vst_size + ub->vst_blksize - 1) / ub->vst_blksize;
+ ub->vst_nlink = 1;
+
+ ub->vst_uid = kauth_getuid();
+ ub->vst_gid = kauth_getgid();
+
+ microtime(&now);
+ ub->vst_atime = now.tv_sec;
+ ub->vst_atimensec = now.tv_usec * 1000;
+
+ ub->vst_mtime = now.tv_sec;
+ ub->vst_mtimensec = now.tv_usec * 1000;
+
+ ub->vst_ctime = now.tv_sec;
+ ub->vst_ctimensec = now.tv_usec * 1000;
+
+ /*
+ * Left as 0: st_dev, st_ino, st_nlink, st_rdev, st_flags, st_gen, st_uid, st_gid.
+ * XXX (st_dev, st_ino) should be unique.
+ */
+
+ pinfo->pipe_handle = (uint64_t)((uintptr_t)cpipe);
+ pinfo->pipe_peerhandle = (uint64_t)((uintptr_t)(cpipe->pipe_peer));
+ pinfo->pipe_status = cpipe->pipe_state;
+
+ PIPE_UNLOCK(cpipe);
+
+ return (0);
+}