+#ifdef __APPLE__
+/*
+ * The following are macros on BSD and functions on Darwin
+ */
+
+/*
+ * Do we need to notify the other side when I/O is possible?
+ */
+
+int
+sb_notify(struct sockbuf *sb)
+{
+ return ((sb->sb_flags & (SB_WAIT|SB_SEL|SB_ASYNC|SB_UPCALL)) != 0);
+}
+
+/*
+ * How much space is there in a socket buffer (so->so_snd or so->so_rcv)?
+ * This is problematical if the fields are unsigned, as the space might
+ * still be negative (cc > hiwat or mbcnt > mbmax). Should detect
+ * overflow and return 0. Should use "lmin" but it doesn't exist now.
+ */
+long
+sbspace(struct sockbuf *sb)
+{
+ return ((long) imin((int)(sb->sb_hiwat - sb->sb_cc),
+ (int)(sb->sb_mbmax - sb->sb_mbcnt)));
+}
+
+/* do we have to send all at once on a socket? */
+int
+sosendallatonce(struct socket *so)
+{
+ return (so->so_proto->pr_flags & PR_ATOMIC);
+}
+
+/* can we read something from so? */
+int
+soreadable(struct socket *so)
+{
+ return (so->so_rcv.sb_cc >= so->so_rcv.sb_lowat ||
+ (so->so_state & SS_CANTRCVMORE) ||
+ so->so_comp.tqh_first || so->so_error);
+}
+
+/* can we write something to so? */
+
+int
+sowriteable(struct socket *so)
+{
+ return ((sbspace(&(so)->so_snd) >= (so)->so_snd.sb_lowat &&
+ ((so->so_state&SS_ISCONNECTED) ||
+ (so->so_proto->pr_flags&PR_CONNREQUIRED)==0)) ||
+ (so->so_state & SS_CANTSENDMORE) ||
+ so->so_error);
+}
+
+/* adjust counters in sb reflecting allocation of m */
+
+void
+sballoc(struct sockbuf *sb, struct mbuf *m)
+{
+ sb->sb_cc += m->m_len;
+ sb->sb_mbcnt += MSIZE;
+ if (m->m_flags & M_EXT)
+ sb->sb_mbcnt += m->m_ext.ext_size;
+}
+
+/* adjust counters in sb reflecting freeing of m */
+void
+sbfree(struct sockbuf *sb, struct mbuf *m)
+{
+ sb->sb_cc -= m->m_len;
+ sb->sb_mbcnt -= MSIZE;
+ if (m->m_flags & M_EXT)
+ sb->sb_mbcnt -= m->m_ext.ext_size;
+}
+
+/*
+ * Set lock on sockbuf sb; sleep if lock is already held.
+ * Unless SB_NOINTR is set on sockbuf, sleep is interruptible.
+ * Returns error without lock if sleep is interrupted.
+ */
+int
+sblock(struct sockbuf *sb, int wf)
+{
+ return(sb->sb_flags & SB_LOCK ?
+ ((wf == M_WAIT) ? sb_lock(sb) : EWOULDBLOCK) :
+ (sb->sb_flags |= SB_LOCK), 0);
+}
+
+/* release lock on sockbuf sb */
+void
+sbunlock(struct sockbuf *sb)
+{
+ sb->sb_flags &= ~SB_LOCK;
+ if (sb->sb_flags & SB_WANT) {
+ sb->sb_flags &= ~SB_WANT;
+ wakeup((caddr_t)&(sb)->sb_flags);
+ }
+}
+
+void
+sorwakeup(struct socket * so)
+{
+ if (sb_notify(&so->so_rcv))
+ sowakeup(so, &so->so_rcv);
+}
+
+void
+sowwakeup(struct socket * so)
+{
+ if (sb_notify(&so->so_snd))
+ sowakeup(so, &so->so_snd);
+}
+#endif __APPLE__