Deleted Added
full compact
kern_sendfile.c (96972) kern_sendfile.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 ---