Coverage Report

Created: 2026-01-25 07:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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 */