Deleted Added
full compact
kern_descrip.c (89310) kern_descrip.c (89319)
1/*
2 * Copyright (c) 1982, 1986, 1989, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

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

31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)kern_descrip.c 8.6 (Berkeley) 4/19/94
1/*
2 * Copyright (c) 1982, 1986, 1989, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

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

31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)kern_descrip.c 8.6 (Berkeley) 4/19/94
39 * $FreeBSD: head/sys/kern/kern_descrip.c 89310 2002-01-13 12:58:14Z alfred $
39 * $FreeBSD: head/sys/kern/kern_descrip.c 89319 2002-01-14 00:13:45Z alfred $
40 */
41
42#include "opt_compat.h"
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/lock.h>
47#include <sys/malloc.h>

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

838fpathconf(td, uap)
839 struct thread *td;
840 register struct fpathconf_args *uap;
841{
842 struct file *fp;
843 struct vnode *vp;
844 int error;
845
40 */
41
42#include "opt_compat.h"
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/lock.h>
47#include <sys/malloc.h>

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

838fpathconf(td, uap)
839 struct thread *td;
840 register struct fpathconf_args *uap;
841{
842 struct file *fp;
843 struct vnode *vp;
844 int error;
845
846 fp = ffind_hold(td, uap->fd);
847 if (fp == NULL)
848 return (EBADF);
849 mtx_lock(&Giant);
850 if ((error = fget(td, uap->fd, &fp)) != 0)
846 if ((error = fget(td, uap->fd, &fp)) != 0)
851 goto done2;
847 return (error);
852
853 switch (fp->f_type) {
854 case DTYPE_PIPE:
855 case DTYPE_SOCKET:
856 if (uap->name != _PC_PIPE_BUF) {
848
849 switch (fp->f_type) {
850 case DTYPE_PIPE:
851 case DTYPE_SOCKET:
852 if (uap->name != _PC_PIPE_BUF) {
857 fdrop(fp, td);
858 error = EINVAL;
853 error = EINVAL;
859 goto done2;
854 } else {
855 td->td_retval[0] = PIPE_BUF;
856 error = 0;
860 }
857 }
861 td->td_retval[0] = PIPE_BUF;
862 error = 0;
863 break;
864 case DTYPE_FIFO:
865 case DTYPE_VNODE:
866 vp = (struct vnode *)fp->f_data;
858 break;
859 case DTYPE_FIFO:
860 case DTYPE_VNODE:
861 vp = (struct vnode *)fp->f_data;
862 mtx_lock(&Giant);
867 error = VOP_PATHCONF(vp, uap->name, td->td_retval);
863 error = VOP_PATHCONF(vp, uap->name, td->td_retval);
864 mtx_unlock(&Giant);
868 break;
869 default:
870 error = EOPNOTSUPP;
871 break;
872 }
873 fdrop(fp, td);
865 break;
866 default:
867 error = EOPNOTSUPP;
868 break;
869 }
870 fdrop(fp, td);
874done2:
875 mtx_unlock(&Giant);
876 return(error);
877}
878
879/*
880 * Allocate a file descriptor for the process.
881 */
882static int fdexpand;
883SYSCTL_INT(_debug, OID_AUTO, fdexpand, CTLFLAG_RD, &fdexpand, 0, "");

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

1451 vp = (struct vnode *)fp->f_data;
1452 (void) VOP_ADVLOCK(vp, (caddr_t)td->td_proc->p_leader,
1453 F_UNLCK, &lf, F_POSIX);
1454 }
1455 return (fdrop(fp, td));
1456}
1457
1458/*
871 return(error);
872}
873
874/*
875 * Allocate a file descriptor for the process.
876 */
877static int fdexpand;
878SYSCTL_INT(_debug, OID_AUTO, fdexpand, CTLFLAG_RD, &fdexpand, 0, "");

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

1446 vp = (struct vnode *)fp->f_data;
1447 (void) VOP_ADVLOCK(vp, (caddr_t)td->td_proc->p_leader,
1448 F_UNLCK, &lf, F_POSIX);
1449 }
1450 return (fdrop(fp, td));
1451}
1452
1453/*
1459 * Find the struct file 'fd' in process 'p' and bump it's refcount
1460 * struct file is not locked on return.
1461 */
1462struct file *
1463ffind_hold(td, fd)
1464 struct thread *td;
1465 int fd;
1466{
1467 struct file *fp;
1468
1469 fp = ffind_lock(td, fd);
1470 if (fp != NULL)
1471 FILE_UNLOCK(fp);
1472 return (fp);
1473}
1474
1475/*
1476 * Find the struct file 'fd' in process 'p' and bump it's refcount,
1477 * struct file is locked on return.
1478 */
1479struct file *
1480ffind_lock(td, fd)
1481 struct thread *td;
1482 int fd;
1483{
1484 struct filedesc *fdp;
1485 struct file *fp;
1486
1487 if (td == NULL || (fdp = td->td_proc->p_fd) == NULL)
1488 return (NULL);
1489 FILEDESC_LOCK(fdp);
1490 if (fd < 0 || fd >= fdp->fd_nfiles ||
1491 (fp = fdp->fd_ofiles[fd]) == NULL ||
1492 fp->f_ops == &badfileops) {
1493 fp = NULL;
1494 } else {
1495 FILE_LOCK(fp);
1496 fhold_locked(fp);
1497 }
1498 FILEDESC_UNLOCK(fdp);
1499 return (fp);
1500}
1501
1502/*
1503 * Drop reference on struct file passed in, may call closef if the
1504 * reference hits zero.
1505 */
1506int
1507fdrop(fp, td)
1508 struct file *fp;
1509 struct thread *td;
1510{
1511
1512 FILE_LOCK(fp);
1513 return (fdrop_locked(fp, td));
1514}
1515
1516/*
1517 * Extract the file pointer associated with the specified descriptor for
1454 * Drop reference on struct file passed in, may call closef if the
1455 * reference hits zero.
1456 */
1457int
1458fdrop(fp, td)
1459 struct file *fp;
1460 struct thread *td;
1461{
1462
1463 FILE_LOCK(fp);
1464 return (fdrop_locked(fp, td));
1465}
1466
1467/*
1468 * Extract the file pointer associated with the specified descriptor for
1518 * the current user process. If no error occured 0 is returned, *fpp
1519 * will be set to the file pointer, and the file pointer's ref count
1520 * will be bumped. Use fdrop() to drop it. If an error occured the
1521 * non-zero error is returned and *fpp is set to NULL.
1469 * the current user process.
1522 *
1470 *
1523 * This routine requires Giant for the moment. Once enough of the
1524 * system is converted over to this and other encapsulated APIs we
1525 * will be able to mutex it and call it without Giant.
1471 * If the descriptor doesn't exist, EBADF is returned.
1472 *
1473 * If the descriptor exists but doesn't match 'flags' then
1474 * return EBADF for read attempts and EINVAL for write attempts.
1475 *
1476 * If 'hold' is set (non-zero) the file's refcount will be bumped on return.
1477 * It should be droped with fdrop().
1478 * If it is not set, then the refcount will not be bumped however the
1479 * thread's filedesc struct will be returned locked (for fgetsock).
1480 *
1481 * If an error occured the non-zero error is returned and *fpp is set to NULL.
1482 * Otherwise *fpp is set and zero is returned.
1526 */
1527static __inline
1528int
1483 */
1484static __inline
1485int
1529_fget(struct thread *td, int fd, struct file **fpp, int flags)
1486_fget(struct thread *td, int fd, struct file **fpp, int flags, int hold)
1530{
1531 struct filedesc *fdp;
1532 struct file *fp;
1533
1487{
1488 struct filedesc *fdp;
1489 struct file *fp;
1490
1534 GIANT_REQUIRED;
1535 fdp = td->td_proc->p_fd;
1536 *fpp = NULL;
1491 *fpp = NULL;
1537 if ((u_int)fd >= fdp->fd_nfiles)
1492 if (td == NULL || (fdp = td->td_proc->p_fd) == NULL)
1538 return(EBADF);
1493 return(EBADF);
1539 if ((fp = fdp->fd_ofiles[fd]) == NULL)
1494 FILEDESC_LOCK(fdp);
1495 if (fd < 0 || (u_int)fd >= fdp->fd_nfiles ||
1496 (fp = fdp->fd_ofiles[fd]) == NULL ||
1497 fp->f_ops == &badfileops) {
1498 FILEDESC_UNLOCK(fdp);
1540 return(EBADF);
1499 return(EBADF);
1500 }
1541
1542 /*
1543 * Note: FREAD failures returns EBADF to maintain backwards
1544 * compatibility with what routines returned before.
1545 *
1546 * Only one flag, or 0, may be specified.
1547 */
1501
1502 /*
1503 * Note: FREAD failures returns EBADF to maintain backwards
1504 * compatibility with what routines returned before.
1505 *
1506 * Only one flag, or 0, may be specified.
1507 */
1548 if (flags == FREAD && (fp->f_flag & FREAD) == 0)
1508 if (flags == FREAD && (fp->f_flag & FREAD) == 0) {
1509 FILEDESC_UNLOCK(fdp);
1549 return(EBADF);
1510 return(EBADF);
1550 if (flags == FWRITE && (fp->f_flag & FWRITE) == 0)
1511 }
1512 if (flags == FWRITE && (fp->f_flag & FWRITE) == 0) {
1513 FILEDESC_UNLOCK(fdp);
1551 return(EINVAL);
1514 return(EINVAL);
1552 ++fp->f_count;
1515 }
1516 if (hold) {
1517 fhold(fp);
1518 FILEDESC_UNLOCK(fdp);
1519 }
1553 *fpp = fp;
1554 return(0);
1555}
1556
1557int
1558fget(struct thread *td, int fd, struct file **fpp)
1559{
1520 *fpp = fp;
1521 return(0);
1522}
1523
1524int
1525fget(struct thread *td, int fd, struct file **fpp)
1526{
1560 return(_fget(td, fd, fpp, 0));
1527 return(_fget(td, fd, fpp, 0, 1));
1561}
1562
1563int
1564fget_read(struct thread *td, int fd, struct file **fpp)
1565{
1528}
1529
1530int
1531fget_read(struct thread *td, int fd, struct file **fpp)
1532{
1566 return(_fget(td, fd, fpp, FREAD));
1533 return(_fget(td, fd, fpp, FREAD, 1));
1567}
1568
1569int
1570fget_write(struct thread *td, int fd, struct file **fpp)
1571{
1534}
1535
1536int
1537fget_write(struct thread *td, int fd, struct file **fpp)
1538{
1572 return(_fget(td, fd, fpp, FWRITE));
1539 return(_fget(td, fd, fpp, FWRITE, 1));
1573}
1574
1575/*
1576 * Like fget() but loads the underlying vnode, or returns an error if
1577 * the descriptor does not represent a vnode. Note that pipes use vnodes
1578 * but never have VM objects (so VOP_GETVOBJECT() calls will return an
1579 * error). The returned vnode will be vref()d.
1580 */
1581
1582static __inline
1583int
1584_fgetvp(struct thread *td, int fd, struct vnode **vpp, int flags)
1585{
1540}
1541
1542/*
1543 * Like fget() but loads the underlying vnode, or returns an error if
1544 * the descriptor does not represent a vnode. Note that pipes use vnodes
1545 * but never have VM objects (so VOP_GETVOBJECT() calls will return an
1546 * error). The returned vnode will be vref()d.
1547 */
1548
1549static __inline
1550int
1551_fgetvp(struct thread *td, int fd, struct vnode **vpp, int flags)
1552{
1586 struct filedesc *fdp;
1587 struct file *fp;
1553 struct file *fp;
1554 int error;
1588
1555
1589 GIANT_REQUIRED;
1590 fdp = td->td_proc->p_fd;
1591 *vpp = NULL;
1556 *vpp = NULL;
1592 if ((u_int)fd >= fdp->fd_nfiles)
1593 return(EBADF);
1594 if ((fp = fdp->fd_ofiles[fd]) == NULL)
1595 return(EBADF);
1596 if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO)
1597 return(EINVAL);
1598 if (fp->f_data == NULL)
1599 return(EINVAL);
1600
1601 /*
1602 * Note: FREAD failures returns EBADF to maintain backwards
1603 * compatibility with what routines returned before.
1604 *
1605 * Only one flag, or 0, may be specified.
1606 */
1607 if (flags == FREAD && (fp->f_flag & FREAD) == 0)
1608 return(EBADF);
1609 if (flags == FWRITE && (fp->f_flag & FWRITE) == 0)
1610 return(EINVAL);
1611 *vpp = (struct vnode *)fp->f_data;
1612 vref(*vpp);
1613 return(0);
1557 if ((error = _fget(td, fd, &fp, 0, 0)) != 0)
1558 return (error);
1559 if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO) {
1560 error = EINVAL;
1561 } else {
1562 *vpp = (struct vnode *)fp->f_data;
1563 vref(*vpp);
1564 }
1565 FILEDESC_UNLOCK(td->td_proc->p_fd);
1566 return (error);
1614}
1615
1616int
1617fgetvp(struct thread *td, int fd, struct vnode **vpp)
1618{
1619 return(_fgetvp(td, fd, vpp, 0));
1620}
1621

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

1636 * the descriptor does not represent a socket.
1637 *
1638 * We bump the ref count on the returned socket. XXX Also obtain the SX lock in
1639 * the future.
1640 */
1641int
1642fgetsock(struct thread *td, int fd, struct socket **spp, u_int *fflagp)
1643{
1567}
1568
1569int
1570fgetvp(struct thread *td, int fd, struct vnode **vpp)
1571{
1572 return(_fgetvp(td, fd, vpp, 0));
1573}
1574

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

1589 * the descriptor does not represent a socket.
1590 *
1591 * We bump the ref count on the returned socket. XXX Also obtain the SX lock in
1592 * the future.
1593 */
1594int
1595fgetsock(struct thread *td, int fd, struct socket **spp, u_int *fflagp)
1596{
1644 struct filedesc *fdp;
1645 struct file *fp;
1597 struct file *fp;
1646 struct socket *so;
1598 int error;
1647
1599
1648 GIANT_REQUIRED;
1649 fdp = td->td_proc->p_fd;
1650 *spp = NULL;
1651 if (fflagp)
1652 *fflagp = 0;
1600 *spp = NULL;
1601 if (fflagp)
1602 *fflagp = 0;
1653 if ((u_int)fd >= fdp->fd_nfiles)
1654 return(EBADF);
1655 if ((fp = fdp->fd_ofiles[fd]) == NULL)
1656 return(EBADF);
1657 if (fp->f_type != DTYPE_SOCKET)
1658 return(ENOTSOCK);
1659 if (fp->f_data == NULL)
1660 return(EINVAL);
1661 so = (struct socket *)fp->f_data;
1662 if (fflagp)
1663 *fflagp = fp->f_flag;
1664 soref(so);
1665 *spp = so;
1666 return(0);
1603 if ((error = _fget(td, fd, &fp, 0, 0)) != 0)
1604 return (error);
1605 if (fp->f_type != DTYPE_SOCKET) {
1606 error = ENOTSOCK;
1607 } else {
1608 *spp = (struct socket *)fp->f_data;
1609 if (fflagp)
1610 *fflagp = fp->f_flag;
1611 soref(*spp);
1612 }
1613 FILEDESC_UNLOCK(td->td_proc->p_fd);
1614 return(error);
1667}
1668
1669/*
1670 * Drop the reference count on the the socket and XXX release the SX lock in
1671 * the future. The last reference closes the socket.
1672 */
1673void
1674fputsock(struct socket *so)

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

1732 * MPSAFE
1733 */
1734/* ARGSUSED */
1735int
1736flock(td, uap)
1737 struct thread *td;
1738 register struct flock_args *uap;
1739{
1615}
1616
1617/*
1618 * Drop the reference count on the the socket and XXX release the SX lock in
1619 * the future. The last reference closes the socket.
1620 */
1621void
1622fputsock(struct socket *so)

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

1680 * MPSAFE
1681 */
1682/* ARGSUSED */
1683int
1684flock(td, uap)
1685 struct thread *td;
1686 register struct flock_args *uap;
1687{
1740 register struct file *fp;
1688 struct file *fp;
1741 struct vnode *vp;
1742 struct flock lf;
1743 int error;
1744
1689 struct vnode *vp;
1690 struct flock lf;
1691 int error;
1692
1745 fp = ffind_hold(td, uap->fd);
1746 if (fp == NULL)
1747 return (EBADF);
1693 if ((error = fget(td, uap->fd, &fp)) != 0)
1694 return (error);
1748 if (fp->f_type != DTYPE_VNODE) {
1749 fdrop(fp, td);
1750 return (EOPNOTSUPP);
1751 }
1752
1753 mtx_lock(&Giant);
1754 vp = (struct vnode *)fp->f_data;
1755 lf.l_whence = SEEK_SET;

--- 333 unchanged lines hidden ---
1695 if (fp->f_type != DTYPE_VNODE) {
1696 fdrop(fp, td);
1697 return (EOPNOTSUPP);
1698 }
1699
1700 mtx_lock(&Giant);
1701 vp = (struct vnode *)fp->f_data;
1702 lf.l_whence = SEEK_SET;

--- 333 unchanged lines hidden ---