1 /****************************************************************************
2 * fs/vfs/fs_dup.c
3 *
4 * Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved.
5 * Based on NuttX originally from nuttx source (nuttx/fs/ and nuttx/drivers/)
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 ****************************************************************************/
20
21 /****************************************************************************
22 * Included Files
23 ****************************************************************************/
24
25 #include "vfs_config.h"
26
27 #include "errno.h"
28 #include "unistd.h"
29 #include "sched.h"
30
31 #include "vnode.h"
32 #if defined(LOSCFG_NET_LWIP_SACK)
33 #include "lwip/sockets.h"
34 #endif
35
36 /****************************************************************************
37 * Public Functions
38 ****************************************************************************/
39
40 /****************************************************************************
41 * Name: dup
42 *
43 * Description:
44 * Clone a file or socket descriptor to an arbitray descriptor number
45 *
46 ****************************************************************************/
47
dup(int fd)48 int dup(int fd)
49 {
50 int ret = OK;
51
52 /* Check the range of the descriptor to see if we got a file or a socket
53 * descriptor.
54 */
55
56 #if CONFIG_NFILE_DESCRIPTORS > 0
57 if ((unsigned int)fd < CONFIG_NFILE_DESCRIPTORS)
58 {
59 /* 0,1,2 fd is not opened in system, no need to dup them, return fd directly */
60
61 if ((fd >= STDIN_FILENO) && (fd <= STDERR_FILENO))
62 {
63 return fd;
64 }
65
66 /* Its a valid file descriptor.. dup the file descriptor using any
67 * other file descriptor. fd_dupfd() sets the errno value in the
68 * event of any failures.
69 */
70
71 ret = fs_dupfd(fd, 3); /* 3: file start fd */
72 }
73 else
74 #endif
75 {
76 /* Not a valid file descriptor. Did we get a valid socket descriptor? */
77 #if defined(LOSCFG_NET_LWIP_SACK)
78 if ((unsigned int)fd < (unsigned int)(CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS))
79 {
80 /* Yes.. dup the socket descriptor. The errno value is not set. */
81
82 set_errno(EBADF); /* When net_dupsd is still closed,errno should set */
83 ret = VFS_ERROR;
84
85 }
86 else
87 #endif
88 {
89 /* No.. then it is a bad descriptor number */
90
91 set_errno(EBADF);
92 ret = VFS_ERROR;
93 }
94 }
95
96 return ret;
97 }
98