Deleted Added
sdiff udiff text old ( 98499 ) new ( 98849 )
full compact
1/*
2 * Copyright (c) 1982, 1986, 1988, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 17 unchanged lines hidden (view full) ---

26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
34 * $FreeBSD: head/sys/kern/uipc_socket.c 98499 2002-06-20 18:52:54Z alfred $
35 */
36
37#include "opt_inet.h"
38
39#include <sys/param.h>
40#include <sys/systm.h>
41#include <sys/fcntl.h>
42#include <sys/lock.h>
43#include <sys/malloc.h>
44#include <sys/mbuf.h>
45#include <sys/mutex.h>

--- 43 unchanged lines hidden (view full) ---

89SYSCTL_DECL(_kern_ipc);
90
91static int somaxconn = SOMAXCONN;
92SYSCTL_INT(_kern_ipc, KIPC_SOMAXCONN, somaxconn, CTLFLAG_RW,
93 &somaxconn, 0, "Maximum pending socket connection queue size");
94static int numopensockets;
95SYSCTL_INT(_kern_ipc, OID_AUTO, numopensockets, CTLFLAG_RD,
96 &numopensockets, 0, "Number of open sockets");
97
98
99/*
100 * Socket operation routines.
101 * These routines are called by the routines in
102 * sys_socket.c or from a system process, and
103 * implement the semantics of socket operations by
104 * switching out to the protocol specific routines.

--- 361 unchanged lines hidden (view full) ---

466 * otherwise by the mbuf chain "top" (which must be null
467 * if uio is not). Data provided in mbuf chain must be small
468 * enough to send all at once.
469 *
470 * Returns nonzero on error, timeout or signal; callers
471 * must check for short counts if EINTR/ERESTART are returned.
472 * Data and control buffers are freed on return.
473 */
474int
475sosend(so, addr, uio, top, control, flags, td)
476 register struct socket *so;
477 struct sockaddr *addr;
478 struct uio *uio;
479 struct mbuf *top;
480 struct mbuf *control;
481 int flags;
482 struct thread *td;
483{
484 struct mbuf **mp;
485 register struct mbuf *m;
486 register long space, len, resid;
487 int clen = 0, error, s, dontroute, mlen;
488 int atomic = sosendallatonce(so) || top;
489
490 if (uio)
491 resid = uio->uio_resid;
492 else
493 resid = top->m_pkthdr.len;
494 /*
495 * In theory resid should be unsigned.
496 * However, space must be signed, as it might be less than 0

--- 72 unchanged lines hidden (view full) ---

569 if (uio == NULL) {
570 /*
571 * Data is prepackaged in "top".
572 */
573 resid = 0;
574 if (flags & MSG_EOR)
575 top->m_flags |= M_EOR;
576 } else do {
577 if (top == 0) {
578 MGETHDR(m, M_TRYWAIT, MT_DATA);
579 if (m == NULL) {
580 error = ENOBUFS;
581 goto release;
582 }
583 mlen = MHLEN;
584 m->m_pkthdr.len = 0;
585 m->m_pkthdr.rcvif = (struct ifnet *)0;
586 } else {
587 MGET(m, M_TRYWAIT, MT_DATA);
588 if (m == NULL) {
589 error = ENOBUFS;
590 goto release;
591 }
592 mlen = MLEN;
593 }
594 if (resid >= MINCLSIZE) {
595 MCLGET(m, M_TRYWAIT);
596 if ((m->m_flags & M_EXT) == 0)
597 goto nopages;
598 mlen = MCLBYTES;
599 len = min(min(mlen, resid), space);
600 } else {
601nopages:
602 len = min(min(mlen, resid), space);
603 /*
604 * For datagram protocols, leave room
605 * for protocol headers in first mbuf.
606 */
607 if (atomic && top == 0 && len < mlen)
608 MH_ALIGN(m, len);
609 }
610 space -= len;
611 error = uiomove(mtod(m, caddr_t), (int)len, uio);
612 resid = uio->uio_resid;
613 m->m_len = len;
614 *mp = m;
615 top->m_pkthdr.len += len;
616 if (error)
617 goto release;
618 mp = &m->m_next;

--- 95 unchanged lines hidden (view full) ---

714 if (flags & MSG_OOB) {
715 m = m_get(M_TRYWAIT, MT_DATA);
716 if (m == NULL)
717 return (ENOBUFS);
718 error = (*pr->pr_usrreqs->pru_rcvoob)(so, m, flags & MSG_PEEK);
719 if (error)
720 goto bad;
721 do {
722 error = uiomove(mtod(m, caddr_t),
723 (int) min(uio->uio_resid, m->m_len), uio);
724 m = m_free(m);
725 } while (uio->uio_resid && error == 0 && m);
726bad:
727 if (m)
728 m_freem(m);
729 return (error);

--- 139 unchanged lines hidden (view full) ---

869 * Otherwise copy them out via the uio, then free.
870 * Sockbuf must be consistent here (points to current mbuf,
871 * it points to next record) when we drop priority;
872 * we must note any additions to the sockbuf when we
873 * block interrupts again.
874 */
875 if (mp == 0) {
876 splx(s);
877 error = uiomove(mtod(m, caddr_t) + moff, (int)len, uio);
878 s = splnet();
879 if (error)
880 goto release;
881 } else
882 uio->uio_resid -= len;
883 if (len == m->m_len - moff) {
884 if (m->m_flags & M_EOR)

--- 806 unchanged lines hidden ---