+/*
+ * Wakeup socket readers and writers.
+ * Do asynchronous notification via SIGIO
+ * if the socket has the SS_ASYNC flag set.
+ */
+sowakeup(so, sb)
+ register struct socket *so;
+ struct sockbuf *sb;
+{
+ register struct proc *p;
+
+ sbwakeup(sb);
+ if (so->so_state & SS_ASYNC) {
+ if (so->so_pgrp == 0)
+ return;
+ else if (so->so_pgrp > 0)
+ gsignal(so->so_pgrp, SIGIO);
+ else if ((p = pfind(-so->so_pgrp)) != 0)
+ psignal(p, SIGIO);
+ }
+}
+
+/*
+ * Socket buffer (struct sockbuf) utility routines.
+ *
+ * Each socket contains two socket buffers: one for sending data and
+ * one for receiving data. Each buffer contains a queue of mbufs,
+ * information about the number of mbufs and amount of data in the
+ * queue, and other fields allowing select() statements and notification
+ * on data availability to be implemented.
+ *
+ * Before using a new socket structure it is first necessary to reserve
+ * buffer space to the socket, by calling sbreserve. This commits
+ * some of the available buffer space in the system buffer pool for the
+ * socket. The space should be released by calling sbrelease when the
+ * socket is destroyed.
+ *
+ * The routine sbappend() is normally called to append new mbufs
+ * to a socket buffer, after checking that adequate space is available
+ * comparing the function spspace() with the amount of data to be added.
+ * Data is normally removed from a socket buffer in a protocol by
+ * first calling m_copy on the socket buffer mbuf chain and sending this
+ * to a peer, and then removing the data from the socket buffer with
+ * sbdrop when the data is acknowledged by the peer (or immediately
+ * in the case of unreliable protocols.)
+ *
+ * Protocols which do not require connections place both source address
+ * and data information in socket buffer queues. The source addresses
+ * are stored in single mbufs after each data item, and are easily found
+ * as the data items are all marked with end of record markers. The
+ * sbappendaddr() routine stores a datum and associated address in
+ * a socket buffer. Note that, unlike sbappend(), this routine checks
+ * for the caller that there will be enough space to store the data.
+ * It fails if there is not enough space, or if it cannot find
+ * a mbuf to store the address in.
+ *
+ * The higher-level routines sosend and soreceive (in socket.c)
+ * also add data to, and remove data from socket buffers repectively.
+ */
+
+soreserve(so, sndcc, rcvcc)
+ register struct socket *so;
+ int sndcc, rcvcc;
+{
+
+ if (sbreserve(&so->so_snd, sndcc) == 0)
+ goto bad;
+ if (sbreserve(&so->so_rcv, rcvcc) == 0)
+ goto bad2;
+ return (0);
+bad2:
+ sbrelease(&so->so_snd);
+bad:
+ return (ENOBUFS);
+}
+