sctp_syscalls.c (96972) | sctp_syscalls.c (97658) |
---|---|
1/* 2 * Copyright (c) 1982, 1986, 1989, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * sendfile(2) and related extensions: 6 * Copyright (c) 1998, David Greenman. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 20 unchanged lines hidden (view full) --- 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94 | 1/* 2 * Copyright (c) 1982, 1986, 1989, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * sendfile(2) and related extensions: 6 * Copyright (c) 1998, David Greenman. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 20 unchanged lines hidden (view full) --- 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94 |
37 * $FreeBSD: head/sys/kern/uipc_syscalls.c 96972 2002-05-20 05:41:09Z tanimura $ | 37 * $FreeBSD: head/sys/kern/uipc_syscalls.c 97658 2002-05-31 11:52:35Z tanimura $ |
38 */ 39 40#include "opt_compat.h" 41#include "opt_ktrace.h" 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/kernel.h> --- 194 unchanged lines hidden (view full) --- 240 sizeof (namelen)); 241 if(error) 242 goto done2; 243 } 244 error = fgetsock(td, uap->s, &head, &fflag); 245 if (error) 246 goto done2; 247 s = splnet(); | 38 */ 39 40#include "opt_compat.h" 41#include "opt_ktrace.h" 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/kernel.h> --- 194 unchanged lines hidden (view full) --- 240 sizeof (namelen)); 241 if(error) 242 goto done2; 243 } 244 error = fgetsock(td, uap->s, &head, &fflag); 245 if (error) 246 goto done2; 247 s = splnet(); |
248 SOCK_LOCK(head); | |
249 if ((head->so_options & SO_ACCEPTCONN) == 0) { | 248 if ((head->so_options & SO_ACCEPTCONN) == 0) { |
250 SOCK_UNLOCK(head); | |
251 splx(s); 252 error = EINVAL; 253 goto done; 254 } 255 if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->so_comp)) { | 249 splx(s); 250 error = EINVAL; 251 goto done; 252 } 253 if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->so_comp)) { |
256 SOCK_UNLOCK(head); | |
257 splx(s); 258 error = EWOULDBLOCK; 259 goto done; 260 } 261 while (TAILQ_EMPTY(&head->so_comp) && head->so_error == 0) { 262 if (head->so_state & SS_CANTRCVMORE) { 263 head->so_error = ECONNABORTED; 264 break; 265 } | 254 splx(s); 255 error = EWOULDBLOCK; 256 goto done; 257 } 258 while (TAILQ_EMPTY(&head->so_comp) && head->so_error == 0) { 259 if (head->so_state & SS_CANTRCVMORE) { 260 head->so_error = ECONNABORTED; 261 break; 262 } |
266 error = msleep((caddr_t)&head->so_timeo, 267 SOCK_MTX(head), PSOCK | PCATCH, | 263 error = tsleep((caddr_t)&head->so_timeo, PSOCK | PCATCH, |
268 "accept", 0); 269 if (error) { | 264 "accept", 0); 265 if (error) { |
270 SOCK_UNLOCK(head); | |
271 splx(s); 272 goto done; 273 } 274 } | 266 splx(s); 267 goto done; 268 } 269 } |
275 SOCK_UNLOCK(head); | |
276 if (head->so_error) { 277 error = head->so_error; 278 head->so_error = 0; 279 splx(s); 280 goto done; 281 } 282 283 /* --- 22 unchanged lines hidden (view full) --- 306 goto done; 307 } 308 fhold(nfp); 309 td->td_retval[0] = fd; 310 311 /* connection has been removed from the listen queue */ 312 KNOTE(&head->so_rcv.sb_sel.si_note, 0); 313 | 270 if (head->so_error) { 271 error = head->so_error; 272 head->so_error = 0; 273 splx(s); 274 goto done; 275 } 276 277 /* --- 22 unchanged lines hidden (view full) --- 300 goto done; 301 } 302 fhold(nfp); 303 td->td_retval[0] = fd; 304 305 /* connection has been removed from the listen queue */ 306 KNOTE(&head->so_rcv.sb_sel.si_note, 0); 307 |
314 SOCK_LOCK(so); | |
315 so->so_state &= ~SS_COMP; | 308 so->so_state &= ~SS_COMP; |
316 SOCK_UNLOCK(so); | |
317 so->so_head = NULL; 318 if (head->so_sigio != NULL) 319 fsetown(fgetown(head->so_sigio), &so->so_sigio); 320 321 FILE_LOCK(nfp); | 309 so->so_head = NULL; 310 if (head->so_sigio != NULL) 311 fsetown(fgetown(head->so_sigio), &so->so_sigio); 312 313 FILE_LOCK(nfp); |
322 SOCK_LOCK(so); | |
323 soref(so); /* file descriptor reference */ | 314 soref(so); /* file descriptor reference */ |
324 SOCK_UNLOCK(so); | |
325 nfp->f_data = (caddr_t)so; /* nfp has ref count from falloc */ 326 nfp->f_flag = fflag; 327 nfp->f_ops = &socketops; 328 nfp->f_type = DTYPE_SOCKET; 329 FILE_UNLOCK(nfp); 330 sa = 0; 331 error = soaccept(so, &sa); 332 if (error) { --- 104 unchanged lines hidden (view full) --- 437{ 438 struct socket *so; 439 struct sockaddr *sa; 440 int error, s; 441 442 mtx_lock(&Giant); 443 if ((error = fgetsock(td, uap->s, &so, NULL)) != 0) 444 goto done2; | 315 nfp->f_data = (caddr_t)so; /* nfp has ref count from falloc */ 316 nfp->f_flag = fflag; 317 nfp->f_ops = &socketops; 318 nfp->f_type = DTYPE_SOCKET; 319 FILE_UNLOCK(nfp); 320 sa = 0; 321 error = soaccept(so, &sa); 322 if (error) { --- 104 unchanged lines hidden (view full) --- 427{ 428 struct socket *so; 429 struct sockaddr *sa; 430 int error, s; 431 432 mtx_lock(&Giant); 433 if ((error = fgetsock(td, uap->s, &so, NULL)) != 0) 434 goto done2; |
445 SOCK_LOCK(so); | |
446 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { | 435 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { |
447 SOCK_UNLOCK(so); | |
448 error = EALREADY; 449 goto done1; 450 } | 436 error = EALREADY; 437 goto done1; 438 } |
451 SOCK_UNLOCK(so); | |
452 error = getsockaddr(&sa, uap->name, uap->namelen); 453 if (error) 454 goto done1; 455 error = soconnect(so, sa, td); 456 if (error) 457 goto bad; | 439 error = getsockaddr(&sa, uap->name, uap->namelen); 440 if (error) 441 goto done1; 442 error = soconnect(so, sa, td); 443 if (error) 444 goto bad; |
458 SOCK_LOCK(so); | |
459 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { | 445 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { |
460 SOCK_UNLOCK(so); | |
461 FREE(sa, M_SONAME); 462 error = EINPROGRESS; 463 goto done1; 464 } 465 s = splnet(); 466 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { | 446 FREE(sa, M_SONAME); 447 error = EINPROGRESS; 448 goto done1; 449 } 450 s = splnet(); 451 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { |
467 error = msleep((caddr_t)&so->so_timeo, 468 SOCK_MTX(so), PSOCK | PCATCH, "connec", 0); | 452 error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH, "connec", 0); |
469 if (error) 470 break; 471 } 472 if (error == 0) { 473 error = so->so_error; 474 so->so_error = 0; 475 } | 453 if (error) 454 break; 455 } 456 if (error == 0) { 457 error = so->so_error; 458 so->so_error = 0; 459 } |
476 SOCK_UNLOCK(so); | |
477 splx(s); 478bad: | 460 splx(s); 461bad: |
479 SOCK_LOCK(so); | |
480 so->so_state &= ~SS_ISCONNECTING; | 462 so->so_state &= ~SS_ISCONNECTING; |
481 SOCK_UNLOCK(so); | |
482 FREE(sa, M_SONAME); 483 if (error == ERESTART) 484 error = EINTR; 485done1: 486 fputsock(so); 487done2: 488 mtx_unlock(&Giant); 489 return (error); --- 936 unchanged lines hidden (view full) --- 1426{ 1427 struct socket *so; 1428 struct sockaddr *sa; 1429 int len, error; 1430 1431 mtx_lock(&Giant); 1432 if ((error = fgetsock(td, uap->fdes, &so, NULL)) != 0) 1433 goto done2; | 463 FREE(sa, M_SONAME); 464 if (error == ERESTART) 465 error = EINTR; 466done1: 467 fputsock(so); 468done2: 469 mtx_unlock(&Giant); 470 return (error); --- 936 unchanged lines hidden (view full) --- 1407{ 1408 struct socket *so; 1409 struct sockaddr *sa; 1410 int len, error; 1411 1412 mtx_lock(&Giant); 1413 if ((error = fgetsock(td, uap->fdes, &so, NULL)) != 0) 1414 goto done2; |
1434 SOCK_LOCK(so); | |
1435 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) { | 1415 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) { |
1436 SOCK_UNLOCK(so); | |
1437 error = ENOTCONN; 1438 goto done1; 1439 } | 1416 error = ENOTCONN; 1417 goto done1; 1418 } |
1440 SOCK_UNLOCK(so); | |
1441 error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)); 1442 if (error) 1443 goto done1; 1444 sa = 0; 1445 error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, &sa); 1446 if (error) 1447 goto bad; 1448 if (sa == 0) { --- 241 unchanged lines hidden (view full) --- 1690 goto done; 1691 } 1692 if ((error = fgetsock(td, uap->s, &so, NULL)) != 0) 1693 goto done; 1694 if (so->so_type != SOCK_STREAM) { 1695 error = EINVAL; 1696 goto done; 1697 } | 1419 error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)); 1420 if (error) 1421 goto done1; 1422 sa = 0; 1423 error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, &sa); 1424 if (error) 1425 goto bad; 1426 if (sa == 0) { --- 241 unchanged lines hidden (view full) --- 1668 goto done; 1669 } 1670 if ((error = fgetsock(td, uap->s, &so, NULL)) != 0) 1671 goto done; 1672 if (so->so_type != SOCK_STREAM) { 1673 error = EINVAL; 1674 goto done; 1675 } |
1698 SOCK_LOCK(so); | |
1699 if ((so->so_state & SS_ISCONNECTED) == 0) { | 1676 if ((so->so_state & SS_ISCONNECTED) == 0) { |
1700 SOCK_UNLOCK(so); | |
1701 error = ENOTCONN; 1702 goto done; 1703 } | 1677 error = ENOTCONN; 1678 goto done; 1679 } |
1704 SOCK_UNLOCK(so); | |
1705 if (uap->offset < 0) { 1706 error = EINVAL; 1707 goto done; 1708 } 1709 1710 /* 1711 * If specified, get the pointer to the sf_hdtr struct for 1712 * any headers/trailers. --- 46 unchanged lines hidden (view full) --- 1759 if (uap->nbytes && xfsize > (uap->nbytes - sbytes)) 1760 xfsize = uap->nbytes - sbytes; 1761 if (xfsize <= 0) 1762 break; 1763 /* 1764 * Optimize the non-blocking case by looking at the socket space 1765 * before going to the extra work of constituting the sf_buf. 1766 */ | 1680 if (uap->offset < 0) { 1681 error = EINVAL; 1682 goto done; 1683 } 1684 1685 /* 1686 * If specified, get the pointer to the sf_hdtr struct for 1687 * any headers/trailers. --- 46 unchanged lines hidden (view full) --- 1734 if (uap->nbytes && xfsize > (uap->nbytes - sbytes)) 1735 xfsize = uap->nbytes - sbytes; 1736 if (xfsize <= 0) 1737 break; 1738 /* 1739 * Optimize the non-blocking case by looking at the socket space 1740 * before going to the extra work of constituting the sf_buf. 1741 */ |
1767 SOCK_LOCK(so); | |
1768 if ((so->so_state & SS_NBIO) && sbspace(&so->so_snd) <= 0) { 1769 if (so->so_state & SS_CANTSENDMORE) 1770 error = EPIPE; 1771 else 1772 error = EAGAIN; | 1742 if ((so->so_state & SS_NBIO) && sbspace(&so->so_snd) <= 0) { 1743 if (so->so_state & SS_CANTSENDMORE) 1744 error = EPIPE; 1745 else 1746 error = EAGAIN; |
1773 SOCK_UNLOCK(so); | |
1774 sbunlock(&so->so_snd); 1775 goto done; 1776 } | 1747 sbunlock(&so->so_snd); 1748 goto done; 1749 } |
1777 SOCK_UNLOCK(so); | |
1778 /* 1779 * Attempt to look up the page. 1780 * 1781 * Allocate if not found 1782 * 1783 * Wait and loop if busy. 1784 */ 1785 pg = vm_page_lookup(obj, pindex); --- 106 unchanged lines hidden (view full) --- 1892 * was closed. so_error is true when an error was sensed after 1893 * a previous send. 1894 * The state is checked after the page mapping and buffer 1895 * allocation above since those operations may block and make 1896 * any socket checks stale. From this point forward, nothing 1897 * blocks before the pru_send (or more accurately, any blocking 1898 * results in a loop back to here to re-check). 1899 */ | 1750 /* 1751 * Attempt to look up the page. 1752 * 1753 * Allocate if not found 1754 * 1755 * Wait and loop if busy. 1756 */ 1757 pg = vm_page_lookup(obj, pindex); --- 106 unchanged lines hidden (view full) --- 1864 * was closed. so_error is true when an error was sensed after 1865 * a previous send. 1866 * The state is checked after the page mapping and buffer 1867 * allocation above since those operations may block and make 1868 * any socket checks stale. From this point forward, nothing 1869 * blocks before the pru_send (or more accurately, any blocking 1870 * results in a loop back to here to re-check). 1871 */ |
1900 SOCK_LOCK(so); | |
1901 if ((so->so_state & SS_CANTSENDMORE) || so->so_error) { 1902 if (so->so_state & SS_CANTSENDMORE) { 1903 error = EPIPE; 1904 } else { 1905 error = so->so_error; 1906 so->so_error = 0; 1907 } | 1872 if ((so->so_state & SS_CANTSENDMORE) || so->so_error) { 1873 if (so->so_state & SS_CANTSENDMORE) { 1874 error = EPIPE; 1875 } else { 1876 error = so->so_error; 1877 so->so_error = 0; 1878 } |
1908 SOCK_UNLOCK(so); | |
1909 m_freem(m); 1910 sbunlock(&so->so_snd); 1911 splx(s); 1912 goto done; 1913 } 1914 /* 1915 * Wait for socket space to become available. We do this just 1916 * after checking the connection state above in order to avoid 1917 * a race condition with sbwait(). 1918 */ 1919 if (sbspace(&so->so_snd) < so->so_snd.sb_lowat) { 1920 if (so->so_state & SS_NBIO) { | 1879 m_freem(m); 1880 sbunlock(&so->so_snd); 1881 splx(s); 1882 goto done; 1883 } 1884 /* 1885 * Wait for socket space to become available. We do this just 1886 * after checking the connection state above in order to avoid 1887 * a race condition with sbwait(). 1888 */ 1889 if (sbspace(&so->so_snd) < so->so_snd.sb_lowat) { 1890 if (so->so_state & SS_NBIO) { |
1921 SOCK_UNLOCK(so); | |
1922 m_freem(m); 1923 sbunlock(&so->so_snd); 1924 splx(s); 1925 error = EAGAIN; 1926 goto done; 1927 } | 1891 m_freem(m); 1892 sbunlock(&so->so_snd); 1893 splx(s); 1894 error = EAGAIN; 1895 goto done; 1896 } |
1928 SOCK_UNLOCK(so); | |
1929 error = sbwait(&so->so_snd); 1930 /* 1931 * An error from sbwait usually indicates that we've 1932 * been interrupted by a signal. If we've sent anything 1933 * then return bytes sent, otherwise return the error. 1934 */ 1935 if (error) { 1936 m_freem(m); 1937 sbunlock(&so->so_snd); 1938 splx(s); 1939 goto done; 1940 } 1941 goto retry_space; 1942 } | 1897 error = sbwait(&so->so_snd); 1898 /* 1899 * An error from sbwait usually indicates that we've 1900 * been interrupted by a signal. If we've sent anything 1901 * then return bytes sent, otherwise return the error. 1902 */ 1903 if (error) { 1904 m_freem(m); 1905 sbunlock(&so->so_snd); 1906 splx(s); 1907 goto done; 1908 } 1909 goto retry_space; 1910 } |
1943 SOCK_UNLOCK(so); | |
1944 error = (*so->so_proto->pr_usrreqs->pru_send)(so, 0, m, 0, 0, td); 1945 splx(s); 1946 if (error) { 1947 sbunlock(&so->so_snd); 1948 goto done; 1949 } 1950 } 1951 sbunlock(&so->so_snd); --- 33 unchanged lines hidden --- | 1911 error = (*so->so_proto->pr_usrreqs->pru_send)(so, 0, m, 0, 0, td); 1912 splx(s); 1913 if (error) { 1914 sbunlock(&so->so_snd); 1915 goto done; 1916 } 1917 } 1918 sbunlock(&so->so_snd); --- 33 unchanged lines hidden --- |