/src/ffmpeg/libavformat/os_support.h
Line | Count | Source |
1 | | /* |
2 | | * various OS-feature replacement utilities |
3 | | * copyright (c) 2000, 2001, 2002 Fabrice Bellard |
4 | | * |
5 | | * This file is part of FFmpeg. |
6 | | * |
7 | | * FFmpeg is free software; you can redistribute it and/or |
8 | | * modify it under the terms of the GNU Lesser General Public |
9 | | * License as published by the Free Software Foundation; either |
10 | | * version 2.1 of the License, or (at your option) any later version. |
11 | | * |
12 | | * FFmpeg is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | | * Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public |
18 | | * License along with FFmpeg; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | | */ |
21 | | |
22 | | #ifndef AVFORMAT_OS_SUPPORT_H |
23 | | #define AVFORMAT_OS_SUPPORT_H |
24 | | |
25 | | /** |
26 | | * @file |
27 | | * miscellaneous OS support macros and functions. |
28 | | */ |
29 | | |
30 | | #include "config.h" |
31 | | |
32 | | #include <sys/stat.h> |
33 | | |
34 | | #ifdef _WIN32 |
35 | | #if HAVE_DIRECT_H |
36 | | #include <direct.h> |
37 | | #endif |
38 | | #if HAVE_IO_H |
39 | | #include <io.h> |
40 | | #endif |
41 | | #endif |
42 | | |
43 | | #ifdef _WIN32 |
44 | | # include <fcntl.h> |
45 | | # include <stdint.h> |
46 | | # ifdef lseek |
47 | | # undef lseek |
48 | | # endif |
49 | | # define lseek(f,p,w) _lseeki64((f), (p), (w)) |
50 | | # ifdef stat |
51 | | # undef stat |
52 | | # endif |
53 | | |
54 | | # define stat win32_stat |
55 | | |
56 | | /* |
57 | | * The POSIX definition for the stat() function uses a struct of the |
58 | | * same name (struct stat), that why it takes this extra effort for |
59 | | * redirecting/replacing the stat() function with our own one which |
60 | | * is capable to handle long path names on Windows. |
61 | | * The struct below roughly follows the POSIX definition. Time values |
62 | | * are 64bit, but in cases when _USE_32BIT_TIME_T is defined, they |
63 | | * will be set to values no larger than INT32_MAX which corresponds |
64 | | * to file times up to the year 2038. |
65 | | */ |
66 | | struct win32_stat |
67 | | { |
68 | | _dev_t st_dev; /* ID of device containing file */ |
69 | | _ino_t st_ino; /* inode number */ |
70 | | unsigned short st_mode; /* protection */ |
71 | | short st_nlink; /* number of hard links */ |
72 | | short st_uid; /* user ID of owner */ |
73 | | short st_gid; /* group ID of owner */ |
74 | | _dev_t st_rdev; /* device ID (if special file) */ |
75 | | int64_t st_size; /* total size, in bytes */ |
76 | | int64_t st_atime; /* time of last access */ |
77 | | int64_t st_mtime; /* time of last modification */ |
78 | | int64_t st_ctime; /* time of last status change */ |
79 | | }; |
80 | | |
81 | | # ifdef fstat |
82 | | # undef fstat |
83 | | # endif |
84 | | # define fstat win32_fstat |
85 | | #endif /* defined(_WIN32) */ |
86 | | |
87 | | |
88 | | #ifdef __ANDROID__ |
89 | | # if HAVE_UNISTD_H |
90 | | # include <unistd.h> |
91 | | # endif |
92 | | # ifdef lseek |
93 | | # undef lseek |
94 | | # endif |
95 | | # define lseek(f,p,w) lseek64((f), (p), (w)) |
96 | | #endif |
97 | | |
98 | | static inline int is_dos_path(const char *path) |
99 | 0 | { |
100 | | #if HAVE_DOS_PATHS |
101 | | if (path[0] && path[1] == ':') |
102 | | return 1; |
103 | | #endif |
104 | 0 | return 0; |
105 | 0 | } Unexecuted instantiation: url.c:is_dos_path Unexecuted instantiation: utils.c:is_dos_path Unexecuted instantiation: avio.c:is_dos_path Unexecuted instantiation: network.c:is_dos_path Unexecuted instantiation: os_support.c:is_dos_path |
106 | | |
107 | | #if defined(_WIN32) |
108 | | #ifndef S_IRUSR |
109 | | #define S_IRUSR S_IREAD |
110 | | #endif |
111 | | #ifndef S_IWUSR |
112 | | #define S_IWUSR S_IWRITE |
113 | | #endif |
114 | | #endif |
115 | | |
116 | | #if CONFIG_NETWORK |
117 | | #if defined(_WIN32) |
118 | | #define SHUT_RD SD_RECEIVE |
119 | | #define SHUT_WR SD_SEND |
120 | | #define SHUT_RDWR SD_BOTH |
121 | | #else |
122 | | #include <sys/socket.h> |
123 | | #if !defined(SHUT_RD) /* OS/2, DJGPP */ |
124 | | #define SHUT_RD 0 |
125 | | #define SHUT_WR 1 |
126 | | #define SHUT_RDWR 2 |
127 | | #endif |
128 | | #endif |
129 | | |
130 | | #if !HAVE_SOCKLEN_T |
131 | | typedef int socklen_t; |
132 | | #endif |
133 | | |
134 | | /* most of the time closing a socket is just closing an fd */ |
135 | | #if !HAVE_CLOSESOCKET |
136 | 0 | #define closesocket close |
137 | | #endif |
138 | | |
139 | | #if !HAVE_POLL_H |
140 | | typedef unsigned long nfds_t; |
141 | | |
142 | | #if HAVE_WINSOCK2_H |
143 | | #include <winsock2.h> |
144 | | #endif |
145 | | #if !HAVE_STRUCT_POLLFD |
146 | | struct pollfd { |
147 | | int fd; |
148 | | short events; /* events to look for */ |
149 | | short revents; /* events that occurred */ |
150 | | }; |
151 | | |
152 | | /* events & revents */ |
153 | | #define POLLIN 0x0001 /* any readable data available */ |
154 | | #define POLLOUT 0x0002 /* file descriptor is writeable */ |
155 | | #define POLLRDNORM POLLIN |
156 | | #define POLLWRNORM POLLOUT |
157 | | #define POLLRDBAND 0x0008 /* priority readable data */ |
158 | | #define POLLWRBAND 0x0010 /* priority data can be written */ |
159 | | #define POLLPRI 0x0020 /* high priority readable data */ |
160 | | |
161 | | /* revents only */ |
162 | | #define POLLERR 0x0004 /* errors pending */ |
163 | | #define POLLHUP 0x0080 /* disconnected */ |
164 | | #define POLLNVAL 0x1000 /* invalid file descriptor */ |
165 | | #endif |
166 | | |
167 | | |
168 | | int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout); |
169 | | #define poll ff_poll |
170 | | #endif /* HAVE_POLL_H */ |
171 | | #endif /* CONFIG_NETWORK */ |
172 | | |
173 | | #ifdef _WIN32 |
174 | | #include <stdio.h> |
175 | | #include <windows.h> |
176 | | #include "libavutil/mem.h" |
177 | | #include "libavutil/wchar_filename.h" |
178 | | |
179 | | #define DEF_FS_FUNCTION(name, wfunc, afunc) \ |
180 | | static inline int win32_##name(const char *filename_utf8) \ |
181 | | { \ |
182 | | wchar_t *filename_w; \ |
183 | | int ret; \ |
184 | | \ |
185 | | if (get_extended_win32_path(filename_utf8, &filename_w)) \ |
186 | | return -1; \ |
187 | | if (!filename_w) \ |
188 | | goto fallback; \ |
189 | | \ |
190 | | ret = wfunc(filename_w); \ |
191 | | av_free(filename_w); \ |
192 | | return ret; \ |
193 | | \ |
194 | | fallback: \ |
195 | | /* filename may be be in CP_ACP */ \ |
196 | | return afunc(filename_utf8); \ |
197 | | } |
198 | | |
199 | | DEF_FS_FUNCTION(unlink, _wunlink, _unlink) |
200 | | DEF_FS_FUNCTION(mkdir, _wmkdir, _mkdir) |
201 | | DEF_FS_FUNCTION(rmdir, _wrmdir , _rmdir) |
202 | | |
203 | | static inline int win32_access(const char *filename_utf8, int mode) |
204 | | { |
205 | | wchar_t *filename_w; |
206 | | int ret; |
207 | | if (get_extended_win32_path(filename_utf8, &filename_w)) |
208 | | return -1; |
209 | | if (!filename_w) |
210 | | goto fallback; |
211 | | ret = _waccess(filename_w, mode); |
212 | | av_free(filename_w); |
213 | | return ret; |
214 | | fallback: |
215 | | return _access(filename_utf8, mode); |
216 | | } |
217 | | |
218 | | static inline void copy_stat(struct _stat64 *crtstat, struct win32_stat *buf) |
219 | | { |
220 | | buf->st_dev = crtstat->st_dev; |
221 | | buf->st_ino = crtstat->st_ino; |
222 | | buf->st_mode = crtstat->st_mode; |
223 | | buf->st_nlink = crtstat->st_nlink; |
224 | | buf->st_uid = crtstat->st_uid; |
225 | | buf->st_gid = crtstat->st_gid; |
226 | | buf->st_rdev = crtstat->st_rdev; |
227 | | buf->st_size = crtstat->st_size; |
228 | | buf->st_atime = crtstat->st_atime; |
229 | | buf->st_mtime = crtstat->st_mtime; |
230 | | buf->st_ctime = crtstat->st_ctime; |
231 | | } |
232 | | |
233 | | static inline int win32_stat(const char *filename_utf8, struct win32_stat *buf) |
234 | | { |
235 | | struct _stat64 crtstat = { 0 }; |
236 | | wchar_t *filename_w; |
237 | | int ret; |
238 | | |
239 | | if (get_extended_win32_path(filename_utf8, &filename_w)) |
240 | | return -1; |
241 | | |
242 | | if (filename_w) { |
243 | | ret = _wstat64(filename_w, &crtstat); |
244 | | av_free(filename_w); |
245 | | } else |
246 | | ret = _stat64(filename_utf8, &crtstat); |
247 | | |
248 | | copy_stat(&crtstat, buf); |
249 | | |
250 | | return ret; |
251 | | } |
252 | | |
253 | | static inline int win32_fstat(int fd, struct win32_stat *buf) |
254 | | { |
255 | | struct _stat64 crtstat = { 0 }; |
256 | | int ret; |
257 | | |
258 | | ret = _fstat64(fd, &crtstat); |
259 | | |
260 | | copy_stat(&crtstat, buf); |
261 | | |
262 | | return ret; |
263 | | } |
264 | | |
265 | | static inline int win32_rename(const char *src_utf8, const char *dest_utf8) |
266 | | { |
267 | | wchar_t *src_w, *dest_w; |
268 | | int ret; |
269 | | |
270 | | if (get_extended_win32_path(src_utf8, &src_w)) |
271 | | return -1; |
272 | | if (get_extended_win32_path(dest_utf8, &dest_w)) { |
273 | | av_free(src_w); |
274 | | return -1; |
275 | | } |
276 | | if (!src_w || !dest_w) { |
277 | | av_free(src_w); |
278 | | av_free(dest_w); |
279 | | goto fallback; |
280 | | } |
281 | | |
282 | | ret = MoveFileExW(src_w, dest_w, MOVEFILE_REPLACE_EXISTING); |
283 | | av_free(src_w); |
284 | | av_free(dest_w); |
285 | | // Lacking proper mapping from GetLastError() error codes to errno codes |
286 | | if (ret) |
287 | | errno = EPERM; |
288 | | return ret; |
289 | | |
290 | | fallback: |
291 | | /* filename may be be in CP_ACP */ |
292 | | #if !HAVE_UWP |
293 | | ret = MoveFileExA(src_utf8, dest_utf8, MOVEFILE_REPLACE_EXISTING); |
294 | | if (ret) |
295 | | errno = EPERM; |
296 | | #else |
297 | | /* Windows Phone doesn't have MoveFileExA, and for Windows Store apps, |
298 | | * it is available but not allowed by the app certification kit. However, |
299 | | * it's unlikely that anybody would input filenames in CP_ACP there, so this |
300 | | * fallback is kept mostly for completeness. Alternatively we could |
301 | | * do MultiByteToWideChar(CP_ACP) and use MoveFileExW, but doing |
302 | | * explicit conversions with CP_ACP is allegedly forbidden in windows |
303 | | * store apps (or windows phone), and the notion of a native code page |
304 | | * doesn't make much sense there. */ |
305 | | ret = rename(src_utf8, dest_utf8); |
306 | | #endif |
307 | | return ret; |
308 | | } |
309 | | |
310 | | #define mkdir(a, b) win32_mkdir(a) |
311 | | #define rename win32_rename |
312 | | #define rmdir win32_rmdir |
313 | | #define unlink win32_unlink |
314 | | #define access win32_access |
315 | | |
316 | | #endif |
317 | | |
318 | | #endif /* AVFORMAT_OS_SUPPORT_H */ |