1 /****************************************************************************
2 * fs/vfs/fs_dupfd.c
3 *
4 * Copyright (C) 2007-2009, 2011-2014, 2017 Gregory Nutt. All rights
5 * reserved.
6 * Author: Gregory Nutt <gnutt@nuttx.org>
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 * 3. Neither the name NuttX nor the names of its contributors may be
19 * used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
29 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 *
35 ****************************************************************************/
36
37 /****************************************************************************
38 * Included Files
39 ****************************************************************************/
40
41 #include "vfs_config.h"
42
43 #include "assert.h"
44 #include "errno.h"
45 #include "sched.h"
46
47 #include "fs/file.h"
48
49 #include "vnode.h"
50 #include "stdlib.h"
51 #include "string.h"
52 #if CONFIG_NFILE_DESCRIPTORS > 0
53
54 /****************************************************************************
55 * Pre-processor Definitions
56 ****************************************************************************/
57
58 /****************************************************************************
59 * Public Functions
60 ****************************************************************************/
61
62 /****************************************************************************
63 * Name: file_dup
64 *
65 * Description:
66 * Equivalent to the non-standard fs_dupfd() function except that it
67 * accepts a struct file instance instead of a file descriptor and does
68 * not set the errno variable.
69 *
70 * Returned Value:
71 * Zero (OK) is returned on success; a negated errno value is returned on
72 * any failure.
73 *
74 ****************************************************************************/
75
file_dup(struct file * filep,int minfd)76 int file_dup(struct file *filep, int minfd)
77 {
78 struct file *filep2 = NULL;
79
80 /* Verify that fd is a valid, open file descriptor */
81
82 if ((filep->f_vnode == NULL) || (filep->f_path == NULL))
83 {
84 set_errno(EBADF);
85 return VFS_ERROR;
86 }
87
88 /* Then allocate a new file descriptor for the vnode */
89
90 filep2 = files_allocate(filep->f_vnode, filep->f_oflags, filep->f_pos, filep->f_priv, minfd);
91 if (filep2 == NULL)
92 {
93 set_errno(EMFILE);
94 return VFS_ERROR;
95 }
96 filep2->f_refcount = filep->f_refcount;
97
98 return filep2->fd;
99 }
100
101 /****************************************************************************
102 * Name: fs_dupfd OR dup
103 *
104 * Description:
105 * Clone a file descriptor 'fd' to an arbitray descriptor number (any value
106 * greater than or equal to 'minfd'). If socket descriptors are
107 * implemented, then this is called by dup() for the case of file
108 * descriptors. If socket descriptors are not implemented, then this
109 * function IS dup().
110 *
111 * Returned Value:
112 * fs_dupfd is sometimes an OS internal function and sometimes is a direct
113 * substitute for dup(). So it must return an errno value as though it
114 * were dup().
115 *
116 ****************************************************************************/
117
fs_dupfd(int fd,int minfd)118 int fs_dupfd(int fd, int minfd)
119 {
120 struct file *filep;
121
122 /* Get the file structure corresponding to the file descriptor. */
123
124 int ret = fs_getfilep(fd, &filep);
125 if (ret < 0)
126 {
127 /* The errno value has already been set */
128 return VFS_ERROR;
129 }
130
131 /* Let file_dup() do the real work */
132
133 return file_dup(filep, minfd);
134 }
135
136 #endif /* CONFIG_NFILE_DESCRIPTORS > 0 */
137