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