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 --- |