| 1216 | } |
| 1217 | |
| 1218 | static int |
| 1219 | uipc_ready(struct socket *so, struct mbuf *m, int count) |
| 1220 | { |
| 1221 | struct unpcb *unp, *unp2; |
| 1222 | struct socket *so2; |
| 1223 | int error, i; |
| 1224 | |
| 1225 | unp = sotounpcb(so); |
| 1226 | |
| 1227 | KASSERT(so->so_type == SOCK_STREAM, |
| 1228 | ("%s: unexpected socket type for %p", __func__, so)); |
| 1229 | |
| 1230 | UNP_PCB_LOCK(unp); |
| 1231 | if ((unp2 = unp_pcb_lock_peer(unp)) != NULL) { |
| 1232 | UNP_PCB_UNLOCK(unp); |
| 1233 | so2 = unp2->unp_socket; |
| 1234 | SOCKBUF_LOCK(&so2->so_rcv); |
| 1235 | if ((error = sbready(&so2->so_rcv, m, count)) == 0) |
| 1236 | sorwakeup_locked(so2); |
| 1237 | else |
| 1238 | SOCKBUF_UNLOCK(&so2->so_rcv); |
| 1239 | UNP_PCB_UNLOCK(unp2); |
| 1240 | return (error); |
| 1241 | } |
| 1242 | UNP_PCB_UNLOCK(unp); |
| 1243 | |
| 1244 | /* |
| 1245 | * The receiving socket has been disconnected, but may still be valid. |
| 1246 | * In this case, the now-ready mbufs are still present in its socket |
| 1247 | * buffer, so perform an exhaustive search before giving up and freeing |
| 1248 | * the mbufs. |
| 1249 | */ |
| 1250 | UNP_LINK_RLOCK(); |
| 1251 | LIST_FOREACH(unp, &unp_shead, unp_link) { |
| 1252 | if (uipc_ready_scan(unp->unp_socket, m, count, &error)) |
| 1253 | break; |
| 1254 | } |
| 1255 | UNP_LINK_RUNLOCK(); |
| 1256 | |
| 1257 | if (unp == NULL) { |
| 1258 | for (i = 0; i < count; i++) |
| 1259 | m = m_free(m); |
| 1260 | error = ECONNRESET; |
| 1261 | } |
| 1262 | return (error); |
| 1263 | } |
| 1264 | |
| 1265 | static int |
| 1266 | uipc_sense(struct socket *so, struct stat *sb) |
nothing calls this directly
no test coverage detected