• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  * fs/vfs/fs_truncate64.c
3  *
4  *   Copyright (C) 2018 Gregory Nutt. All rights reserved.
5  *   Author: Gregory Nutt <gnutt@nuttx.org>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name NuttX nor the names of its contributors may be
18  *    used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  ****************************************************************************/
35 
36 /****************************************************************************
37  * Included Files
38  ****************************************************************************/
39 
40 #include "vfs_config.h"
41 #include "sys/types.h"
42 #include "unistd.h"
43 #include "fcntl.h"
44 #include "sched.h"
45 #include "assert.h"
46 #include "errno.h"
47 
48 #include "vnode.h"
49 
50 /****************************************************************************
51  * Name: file_truncate
52  *
53  * Description:
54  *   Equivalent to the standard ftruncate() function except that is accepts
55  *   a struct file instance instead of a file descriptor and it does not set
56  *   the errno variable.
57  *
58  ****************************************************************************/
59 
file_truncate64(struct file * filep,off64_t length)60 static int file_truncate64(struct file *filep, off64_t length)
61 {
62   struct Vnode *vnode = NULL;
63   int err;
64 
65   /* Was this file opened for write access? */
66 
67   if (((unsigned int)(filep->f_oflags) & O_ACCMODE) == O_RDONLY)
68     {
69       err = -EACCES;
70       goto errout;
71     }
72 
73   /* Is this vnode a registered mountpoint? Does it support the
74    * truncate operations may be relevant to device drivers but only
75    * the mountpoint operations vtable contains a truncate method.
76    */
77 
78   vnode = filep->f_vnode;
79   if (!vnode || !vnode->vop || !vnode->vop->Truncate64)
80     {
81       err = -ENOSYS;
82       goto errout;
83     }
84 
85   /* Does the file system support the truncate method?  It should if it is
86    * a write-able file system.
87    */
88 
89   err = vnode->vop->Truncate64(vnode, length);
90   if (err < 0)
91     {
92       goto errout;
93     }
94 
95   return OK;
96 
97 errout:
98   set_errno(-err);
99   return VFS_ERROR;
100 }
101 
102 /****************************************************************************
103  * Name: ftruncate
104  *
105  * Description:
106  *   The ftruncate() function causes the regular file referenced by fd to
107  *   have a size of length bytes.
108  *
109  *   If the file previously was larger than length, the extra data is
110  *   discarded.  If it was previously shorter than length, it is unspecified
111  *   whether the file is changed or its size increased.  If the file is
112  *   extended, the extended area appears as if it were zero-filled.  If fd
113  *   references a shared memory object, ftruncate() sets the size of the
114  *   shared memory object to length. If the file is not a regular file or
115  *   a shared memory object, the result is unspecified.
116 
117  *   With ftruncate(), the file must be open for writing; for truncate(),
118  *   the process must have write permission for the file.
119  *
120  *   ftruncate() does not modify the file offset for any open file
121  *   descriptions associated with the file.
122  *
123  * Input Parameters:
124  *   fd     - A reference to an open, regular file or shared memory object
125  *            to be truncated.
126  *   length - The new length of the file or shared memory object.
127  *
128  * Returned Value:
129  * On success, 0.
130  * On error, -1 is returned, and errno is set appro-priately:
131  *
132  *
133  ****************************************************************************/
134 
ftruncate64(int fd,off64_t length)135 int ftruncate64(int fd, off64_t length)
136 {
137 #if CONFIG_NFILE_DESCRIPTORS > 0
138   struct file *filep = NULL;
139 #endif
140 
141   /* Did we get a valid file descriptor? */
142 
143 #if CONFIG_NFILE_DESCRIPTORS > 0
144   if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
145 #endif
146     {
147       set_errno(EBADF);
148       return VFS_ERROR;
149     }
150 
151 #if CONFIG_NFILE_DESCRIPTORS > 0
152   /* The descriptor is in the right range to be a file descriptor... write
153    * to the file.
154    */
155 
156   int ret = fs_getfilep(fd, &filep);
157   if (ret < 0)
158     {
159       /* The errno value has already been set */
160       return VFS_ERROR;
161     }
162 
163   if (filep->f_oflags & O_DIRECTORY)
164     {
165       set_errno(EBADF);
166       return VFS_ERROR;
167     }
168 
169   /* Perform the truncate operation using the file descriptor as an index */
170 
171   return file_truncate64(filep, length);
172 #endif
173 }
174