1 /****************************************************************************
2 * fs/vfs/fs_dupfd2.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 "errno.h"
47 #include "unistd.h"
48 #include "sched.h"
49
50 #include "vnode.h"
51
52 #if CONFIG_NFILE_DESCRIPTORS > 0
53
54 /****************************************************************************
55 * Pre-processor Definitions
56 ****************************************************************************/
57
58 /****************************************************************************
59 * Private Functions
60 ****************************************************************************/
61
62 /****************************************************************************
63 * Public Functions
64 ****************************************************************************/
65
66 /****************************************************************************
67 * Name: fs_dupfd2 OR dup2
68 *
69 * Description:
70 * Clone a file descriptor to a specific descriptor number. If socket
71 * descriptors are implemented, then this is called by dup2() for the
72 * case of file descriptors. If socket descriptors are not implemented,
73 * then this function IS dup2().
74 *
75 * Returned Value:
76 * fs_dupfd is sometimes an OS internal function and sometimes is a direct
77 * substitute for dup2(). So it must return an errno value as though it
78 * were dup2().
79 *
80 ****************************************************************************/
81
82 #if defined(LOSCFG_NET_LWIP_SACK)
fs_dupfd2(int fd1,int fd2)83 int fs_dupfd2(int fd1, int fd2)
84 #else
85 int dup2(int fd1, int fd2)
86 #endif
87 {
88 struct file *filep1;
89 struct file *filep2;
90 int ret;
91
92 /* Get the file structures corresponding to the file descriptors. */
93
94 ret = fs_getfilep(fd1, &filep1);
95 if (ret >= 0)
96 {
97 ret = fs_getfilep(fd2, &filep2);
98 }
99
100
101 if (ret < 0)
102 {
103 /* The errno value has already been set */
104 return VFS_ERROR;
105 }
106
107 /* Verify that fd1 is a valid, open file descriptor */
108
109 if (filep1->f_vnode == NULL)
110 {
111 set_errno(EBADF);
112 return VFS_ERROR;
113 }
114
115 /* Handle a special case */
116
117 if (fd1 == fd2)
118 {
119 return fd1;
120 }
121
122 /* Perform the dup2 operation */
123
124 if (!file_dup2(filep1, filep2))
125 {
126 return fd2;
127 }
128 else
129 {
130 clear_fd(fd2);
131 return VFS_ERROR;
132 }
133 }
134
135 #endif /* CONFIG_NFILE_DESCRIPTORS > 0 */
136