1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2016-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25
26 // These functions may be provided by gnulib. We don't include gnulib
27 // headers directly in Octave's C++ source files to avoid problems that
28 // may be caused by the way that gnulib overrides standard library
29 // functions.
30
31 #if defined (HAVE_CONFIG_H)
32 # include "config.h"
33 #endif
34
35 #include <time.h>
36
37 #include <sys/types.h>
38 #include <sys/stat.h>
39
40 #include "stat-wrappers.h"
41 #include "uniconv-wrappers.h"
42
43 #if defined (OCTAVE_USE_WINDOWS_API)
44 # include <windows.h>
45 # include <wchar.h>
46 #endif
47
48 int
octave_mkdir_wrapper(const char * name,mode_t mode)49 octave_mkdir_wrapper (const char *name, mode_t mode)
50 {
51 #if defined (OCTAVE_USE_WINDOWS_API)
52 wchar_t *wname = u8_to_wchar (name);
53 int status = _wmkdir (wname);
54 free ((void *) wname);
55 octave_unused_parameter (mode);
56 return status;
57 #else
58 return mkdir (name, mode);
59 #endif
60 }
61
62 int
octave_mkfifo_wrapper(const char * name,mode_t mode)63 octave_mkfifo_wrapper (const char *name, mode_t mode)
64 {
65 return mkfifo (name, mode);
66 }
67
68 int
octave_umask_wrapper(mode_t mode)69 octave_umask_wrapper (mode_t mode)
70 {
71 return umask (mode);
72 }
73
74 static inline void
assign_stat_fields(struct stat * buf,mode_t * mode,ino_t * ino,dev_t * dev,nlink_t * nlink,uid_t * uid,gid_t * gid,off_t * size,time_t * atime,time_t * mtime,time_t * ctime,dev_t * rdev,long * blksize,long * blocks)75 assign_stat_fields (struct stat *buf, mode_t *mode, ino_t *ino,
76 dev_t *dev, nlink_t *nlink, uid_t *uid,
77 gid_t *gid, off_t *size, time_t *atime,
78 time_t *mtime, time_t *ctime, dev_t *rdev,
79 long *blksize, long *blocks)
80 {
81 *mode = buf->st_mode;
82 *ino = buf->st_ino;
83 *dev = buf->st_dev;
84 *nlink = buf->st_nlink;
85 *uid = buf->st_uid;
86 *gid = buf->st_gid;
87 *size = buf->st_size;
88 *atime = buf->st_atime;
89 *mtime = buf->st_mtime;
90 *ctime = buf->st_ctime;
91
92 #if defined (HAVE_STRUCT_STAT_ST_RDEV)
93 *rdev = buf->st_rdev;
94 #else
95 *rdev = 0;
96 #endif
97
98 #if defined (HAVE_STRUCT_STAT_ST_BLKSIZE)
99 *blksize = buf->st_blksize;
100 #else
101 *blksize = 0;
102 #endif
103
104 #if defined (HAVE_STRUCT_STAT_ST_BLOCKS)
105 *blocks = buf->st_blocks;
106 #else
107 *blocks = 0;
108 #endif
109 }
110
111 int
octave_stat_wrapper(const char * fname,mode_t * mode,ino_t * ino,dev_t * dev,nlink_t * nlink,uid_t * uid,gid_t * gid,off_t * size,time_t * atime,time_t * mtime,time_t * ctime,dev_t * rdev,long * blksize,long * blocks)112 octave_stat_wrapper (const char *fname, mode_t *mode, ino_t *ino,
113 dev_t *dev, nlink_t *nlink, uid_t *uid,
114 gid_t *gid, off_t *size, time_t *atime,
115 time_t *mtime, time_t *ctime, dev_t *rdev,
116 long *blksize, long *blocks)
117 {
118 struct stat buf;
119
120 #if defined (OCTAVE_USE_WINDOWS_API)
121 wchar_t *wfname = u8_to_wchar (fname);
122 int status = _wstati64 (wfname, &buf);
123 free ((void *) wfname);
124 #else
125 int status = stat (fname, &buf);
126 #endif
127
128 assign_stat_fields (&buf, mode, ino, dev, nlink, uid, gid, size,
129 atime, mtime, ctime, rdev, blksize, blocks);
130
131 return status;
132 }
133
134 int
octave_lstat_wrapper(const char * lname,mode_t * mode,ino_t * ino,dev_t * dev,nlink_t * nlink,uid_t * uid,gid_t * gid,off_t * size,time_t * atime,time_t * mtime,time_t * ctime,dev_t * rdev,long * blksize,long * blocks)135 octave_lstat_wrapper (const char *lname, mode_t *mode, ino_t *ino,
136 dev_t *dev, nlink_t *nlink, uid_t *uid,
137 gid_t *gid, off_t *size, time_t *atime,
138 time_t *mtime, time_t *ctime, dev_t *rdev,
139 long *blksize, long *blocks)
140 {
141 struct stat buf;
142
143 #if defined (OCTAVE_USE_WINDOWS_API)
144 // Windows doesn't have an lstat. Use stat instead
145 wchar_t *wlname = u8_to_wchar (lname);
146 int status = _wstati64 (wlname, &buf);
147 free ((void *) wlname);
148 #else
149 int status = lstat (lname, &buf);
150 #endif
151
152 assign_stat_fields (&buf, mode, ino, dev, nlink, uid, gid, size,
153 atime, mtime, ctime, rdev, blksize, blocks);
154
155 return status;
156 }
157
158 int
octave_fstat_wrapper(int fid,mode_t * mode,ino_t * ino,dev_t * dev,nlink_t * nlink,uid_t * uid,gid_t * gid,off_t * size,time_t * atime,time_t * mtime,time_t * ctime,dev_t * rdev,long * blksize,long * blocks)159 octave_fstat_wrapper (int fid, mode_t *mode, ino_t *ino,
160 dev_t *dev, nlink_t *nlink, uid_t *uid,
161 gid_t *gid, off_t *size, time_t *atime,
162 time_t *mtime, time_t *ctime, dev_t *rdev,
163 long *blksize, long *blocks)
164 {
165 struct stat buf;
166
167 int status = fstat (fid, &buf);
168
169 assign_stat_fields (&buf, mode, ino, dev, nlink, uid, gid, size,
170 atime, mtime, ctime, rdev, blksize, blocks);
171
172 return status;
173 }
174
175 #if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC)
176 // Disable the unused parameter warning for the following wrapper functions.
177 // The <sys/stat.h> header provided by gnulib may define some of the S_IS*
178 // macros to expand to a constant and ignore the parameter.
179 #pragma GCC diagnostic push
180 #pragma GCC diagnostic ignored "-Wunused-parameter"
181 #endif
182
183 bool
octave_is_blk_wrapper(mode_t mode)184 octave_is_blk_wrapper (mode_t mode)
185 {
186 #if defined (S_ISBLK)
187 return S_ISBLK (mode);
188 #else
189 return false;
190 #endif
191 }
192
193 bool
octave_is_chr_wrapper(mode_t mode)194 octave_is_chr_wrapper (mode_t mode)
195 {
196 #if defined (S_ISCHR)
197 return S_ISCHR (mode);
198 #else
199 return false;
200 #endif
201 }
202
203 bool
octave_is_dir_wrapper(mode_t mode)204 octave_is_dir_wrapper (mode_t mode)
205 {
206 #if defined (S_ISDIR)
207 return S_ISDIR (mode);
208 #else
209 return false;
210 #endif
211 }
212
213 bool
octave_is_fifo_wrapper(mode_t mode)214 octave_is_fifo_wrapper (mode_t mode)
215 {
216 #if defined (S_ISFIFO)
217 return S_ISFIFO (mode);
218 #else
219 return false;
220 #endif
221 }
222
223 bool
octave_is_lnk_wrapper(mode_t mode)224 octave_is_lnk_wrapper (mode_t mode)
225 {
226 #if defined (S_ISLNK)
227 return S_ISLNK (mode);
228 #else
229 return false;
230 #endif
231 }
232
233 bool
octave_is_reg_wrapper(mode_t mode)234 octave_is_reg_wrapper (mode_t mode)
235 {
236 #if defined (S_ISREG)
237 return S_ISREG (mode);
238 #else
239 return false;
240 #endif
241 }
242
243 bool
octave_is_sock_wrapper(mode_t mode)244 octave_is_sock_wrapper (mode_t mode)
245 {
246 #if defined (S_ISSOCK)
247 return S_ISSOCK (mode);
248 #else
249 return false;
250 #endif
251 }
252
253 #if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC)
254 // Restore prevailing warning state for remainder of the file.
255 #pragma GCC diagnostic pop
256 #endif
257
258 bool
octave_have_struct_stat_st_rdev(void)259 octave_have_struct_stat_st_rdev (void)
260 {
261 #if defined (HAVE_STRUCT_STAT_ST_RDEV)
262 return true;
263 #else
264 return false;
265 #endif
266 }
267
268 bool
octave_have_struct_stat_st_blksize(void)269 octave_have_struct_stat_st_blksize (void)
270 {
271 #if defined (HAVE_STRUCT_STAT_ST_BLKSIZE)
272 return true;
273 #else
274 return false;
275 #endif
276 }
277
278 bool
octave_have_struct_stat_st_blocks(void)279 octave_have_struct_stat_st_blocks (void)
280 {
281 #if defined (HAVE_STRUCT_STAT_ST_BLOCKS)
282 return true;
283 #else
284 return false;
285 #endif
286 }
287