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