* @brief Duplicate a file descriptor from source table to current process * * @param[in] oldfd is the fd in the designate fd table. * @param[in,out] fdtab is the fd table for oldfd, if empty, use global (_fdtab). * * @return -1 on failed or the allocated file descriptor. */
| 758 | * @return -1 on failed or the allocated file descriptor. |
| 759 | */ |
| 760 | int dfs_dup_from(int oldfd, struct dfs_fdtable *fdtab) |
| 761 | { |
| 762 | int newfd = -1; |
| 763 | struct dfs_file *file; |
| 764 | |
| 765 | if (dfs_file_lock() != RT_EOK) |
| 766 | { |
| 767 | return -RT_ENOSYS; |
| 768 | } |
| 769 | |
| 770 | if (fdtab == NULL) |
| 771 | { |
| 772 | fdtab = &_fdtab; |
| 773 | } |
| 774 | |
| 775 | /* check old fd */ |
| 776 | if ((oldfd < 0) || (oldfd >= fdtab->maxfd)) |
| 777 | { |
| 778 | goto exit; |
| 779 | } |
| 780 | if (!fdtab->fds[oldfd]) |
| 781 | { |
| 782 | goto exit; |
| 783 | } |
| 784 | /* get a new fd*/ |
| 785 | newfd = fd_new(); |
| 786 | file = fd_get(newfd); |
| 787 | if (newfd >= 0 && file) |
| 788 | { |
| 789 | file->mode = fdtab->fds[oldfd]->mode; |
| 790 | file->flags = fdtab->fds[oldfd]->flags; |
| 791 | file->fops = fdtab->fds[oldfd]->fops; |
| 792 | file->dentry = dfs_dentry_ref(fdtab->fds[oldfd]->dentry); |
| 793 | file->vnode = fdtab->fds[oldfd]->vnode; |
| 794 | file->mmap_context = RT_NULL; |
| 795 | file->data = fdtab->fds[oldfd]->data; |
| 796 | } |
| 797 | |
| 798 | dfs_file_close(fdtab->fds[oldfd]); |
| 799 | |
| 800 | exit: |
| 801 | fdt_fd_release(fdtab, oldfd); |
| 802 | dfs_file_unlock(); |
| 803 | |
| 804 | return newfd; |
| 805 | } |
| 806 | |
| 807 | /** |
| 808 | * @brief System call to duplicate a file descriptor |
nothing calls this directly
no test coverage detected