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