static int soo_stat(struct file *fp, struct stat *ub, struct ucred *active_cred, struct thread *td) { struct socket *so = fp->f_data; #ifdef MAC int error; #endif bzero((caddr_t)ub, sizeof (*ub)); ub->st_mode = S_IFSOCK; #ifdef MAC error = mac_socket_check_stat(active_cred, so); if (error) return (error); #endif /* * If SBS_CANTRCVMORE is set, but there's still data left in the * receive buffer, the socket is still readable. */ SOCKBUF_LOCK(&so->so_rcv); if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) == 0 || so->so_rcv.sb_cc != 0) ub->st_mode |= S_IRUSR | S_IRGRP | S_IROTH; ub->st_size = so->so_rcv.sb_cc - so->so_rcv.sb_ctl; SOCKBUF_UNLOCK(&so->so_rcv); /* Unlocked read. */ if ((so->so_snd.sb_state & SBS_CANTSENDMORE) == 0) ub->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; ub->st_uid = so->so_cred->cr_uid; ub->st_gid = so->so_cred->cr_gid; return (*so->so_proto->pr_usrreqs->pru_sense)(so, ub); }
int soo_stat(struct socket *so, void *ub, int isstat64) { int ret; /* warning avoidance ; protected by isstat64 */ struct stat *sb = (struct stat *)0; /* warning avoidance ; protected by isstat64 */ struct stat64 *sb64 = (struct stat64 *)0; #if CONFIG_MACF_SOCKET ret = mac_socket_check_stat(kauth_cred_get(), so); if (ret) return (ret); #endif if (isstat64 != 0) { sb64 = (struct stat64 *)ub; bzero((caddr_t)sb64, sizeof (*sb64)); } else { sb = (struct stat *)ub; bzero((caddr_t)sb, sizeof (*sb)); } socket_lock(so, 1); if (isstat64 != 0) { sb64->st_mode = S_IFSOCK; if ((so->so_state & SS_CANTRCVMORE) == 0 || so->so_rcv.sb_cc != 0) sb64->st_mode |= S_IRUSR | S_IRGRP | S_IROTH; if ((so->so_state & SS_CANTSENDMORE) == 0) sb64->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; sb64->st_size = so->so_rcv.sb_cc - so->so_rcv.sb_ctl; sb64->st_uid = kauth_cred_getuid(so->so_cred); sb64->st_gid = kauth_cred_getgid(so->so_cred); } else { sb->st_mode = S_IFSOCK; if ((so->so_state & SS_CANTRCVMORE) == 0 || so->so_rcv.sb_cc != 0) sb->st_mode |= S_IRUSR | S_IRGRP | S_IROTH; if ((so->so_state & SS_CANTSENDMORE) == 0) sb->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; sb->st_size = so->so_rcv.sb_cc - so->so_rcv.sb_ctl; sb->st_uid = kauth_cred_getuid(so->so_cred); sb->st_gid = kauth_cred_getgid(so->so_cred); } ret = (*so->so_proto->pr_usrreqs->pru_sense)(so, ub, isstat64); socket_unlock(so, 1); return (ret); }