os_support.h 6.38 KB
Newer Older
1
/*
2
 * various OS-feature replacement utilities
3 4
 * copyright (c) 2000, 2001, 2002 Fabrice Bellard
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
8 9
 * modify it under the terms of the GNU Lesser General Public
 * 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 14 15 16 17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * 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 20 21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

22 23
#ifndef AVFORMAT_OS_SUPPORT_H
#define AVFORMAT_OS_SUPPORT_H
24 25

/**
26
 * @file
27 28 29
 * miscellaneous OS support macros and functions.
 */

30 31
#include "config.h"

32 33
#include <sys/stat.h>

34 35 36 37 38 39 40 41 42
#ifdef _WIN32
#if HAVE_DIRECT_H
#include <direct.h>
#endif
#if HAVE_IO_H
#include <io.h>
#endif
#endif

43
#if defined(_WIN32) && !defined(__MINGW32CE__)
44
#  include <fcntl.h>
45 46 47
#  ifdef lseek
#   undef lseek
#  endif
48
#  define lseek(f,p,w) _lseeki64((f), (p), (w))
49 50 51
#  ifdef stat
#   undef stat
#  endif
52
#  define stat _stati64
53 54 55
#  ifdef fstat
#   undef fstat
#  endif
56
#  define fstat(f,s) _fstati64((f), (s))
57
#endif /* defined(_WIN32) && !defined(__MINGW32CE__) */
58

59

60
#ifdef __ANDROID__
61 62 63
#  if HAVE_UNISTD_H
#    include <unistd.h>
#  endif
64 65 66 67 68 69
#  ifdef lseek
#   undef lseek
#  endif
#  define lseek(f,p,w) lseek64((f), (p), (w))
#endif

70 71
static inline int is_dos_path(const char *path)
{
72
#if HAVE_DOS_PATHS
73 74 75 76 77 78
    if (path[0] && path[1] == ':')
        return 1;
#endif
    return 0;
}

Mans Rullgard's avatar
Mans Rullgard committed
79
#if defined(__OS2__) || defined(__Plan9__)
80 81 82 83 84
#define SHUT_RD 0
#define SHUT_WR 1
#define SHUT_RDWR 2
#endif

85 86 87 88
#if defined(_WIN32)
#define SHUT_RD SD_RECEIVE
#define SHUT_WR SD_SEND
#define SHUT_RDWR SD_BOTH
89 90 91 92 93 94 95

#ifndef S_IRUSR
#define S_IRUSR S_IREAD
#endif
#ifndef S_IWUSR
#define S_IWUSR S_IWRITE
#endif
96 97
#endif

98 99
#if CONFIG_NETWORK
#if !HAVE_SOCKLEN_T
100 101
typedef int socklen_t;
#endif
102

103
/* most of the time closing a socket is just closing an fd */
104
#if !HAVE_CLOSESOCKET
105 106 107
#define closesocket close
#endif

108
#if !HAVE_POLL_H
109 110
typedef unsigned long nfds_t;

111 112 113 114
#if HAVE_WINSOCK2_H
#include <winsock2.h>
#endif
#if !HAVE_STRUCT_POLLFD
115 116 117
struct pollfd {
    int fd;
    short events;  /* events to look for */
118
    short revents; /* events that occurred */
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
};

/* events & revents */
#define POLLIN     0x0001  /* any readable data available */
#define POLLOUT    0x0002  /* file descriptor is writeable */
#define POLLRDNORM POLLIN
#define POLLWRNORM POLLOUT
#define POLLRDBAND 0x0008  /* priority readable data */
#define POLLWRBAND 0x0010  /* priority data can be written */
#define POLLPRI    0x0020  /* high priority readable data */

/* revents only */
#define POLLERR    0x0004  /* errors pending */
#define POLLHUP    0x0080  /* disconnected */
#define POLLNVAL   0x1000  /* invalid file descriptor */
134
#endif
135 136


137 138
int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout);
#define poll ff_poll
139
#endif /* HAVE_POLL_H */
140
#endif /* CONFIG_NETWORK */
141

142 143 144 145 146
#if defined(__MINGW32CE__)
#define mkdir(a, b) _mkdir(a)
#elif defined(_WIN32)
#include <stdio.h>
#include <windows.h>
147
#include "libavutil/wchar_filename.h"
148

149 150 151 152 153 154 155 156 157 158 159 160
#ifdef WINAPI_FAMILY
#include <winapifamily.h>
// If a WINAPI_FAMILY is defined, check that the desktop API subset
// is enabled
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#define USE_MOVEFILEEXA
#endif
#else
// If no WINAPI_FAMILY is defined, assume the full API subset
#define USE_MOVEFILEEXA
#endif

161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
#define DEF_FS_FUNCTION(name, wfunc, afunc)               \
static inline int win32_##name(const char *filename_utf8) \
{                                                         \
    wchar_t *filename_w;                                  \
    int ret;                                              \
                                                          \
    if (utf8towchar(filename_utf8, &filename_w))          \
        return -1;                                        \
    if (!filename_w)                                      \
        goto fallback;                                    \
                                                          \
    ret = wfunc(filename_w);                              \
    av_free(filename_w);                                  \
    return ret;                                           \
                                                          \
fallback:                                                 \
    /* filename may be be in CP_ACP */                    \
    return afunc(filename_utf8);                          \
}

DEF_FS_FUNCTION(unlink, _wunlink, _unlink)
DEF_FS_FUNCTION(mkdir,  _wmkdir,  _mkdir)
DEF_FS_FUNCTION(rmdir,  _wrmdir , _rmdir)

static inline int win32_rename(const char *src_utf8, const char *dest_utf8)
{
    wchar_t *src_w, *dest_w;
    int ret;

    if (utf8towchar(src_utf8, &src_w))
        return -1;
    if (utf8towchar(dest_utf8, &dest_w)) {
        av_free(src_w);
        return -1;
    }
    if (!src_w || !dest_w) {
        av_free(src_w);
        av_free(dest_w);
        goto fallback;
    }

202
    ret = MoveFileExW(src_w, dest_w, MOVEFILE_REPLACE_EXISTING);
203 204
    av_free(src_w);
    av_free(dest_w);
205 206 207
    // Lacking proper mapping from GetLastError() error codes to errno codes
    if (ret)
        errno = EPERM;
208 209 210 211
    return ret;

fallback:
    /* filename may be be in CP_ACP */
212
#ifdef USE_MOVEFILEEXA
213 214 215 216
    ret = MoveFileExA(src_utf8, dest_utf8, MOVEFILE_REPLACE_EXISTING);
    if (ret)
        errno = EPERM;
#else
217 218 219
    /* Windows Phone doesn't have MoveFileExA, and for Windows Store apps,
     * it is available but not allowed by the app certification kit. However,
     * it's unlikely that anybody would input filenames in CP_ACP there, so this
220 221 222 223 224 225 226 227
     * fallback is kept mostly for completeness. Alternatively we could
     * do MultiByteToWideChar(CP_ACP) and use MoveFileExW, but doing
     * explicit conversions with CP_ACP is allegedly forbidden in windows
     * store apps (or windows phone), and the notion of a native code page
     * doesn't make much sense there. */
    ret = rename(src_utf8, dest_utf8);
#endif
    return ret;
228 229 230 231 232 233 234 235 236
}

#define mkdir(a, b) win32_mkdir(a)
#define rename      win32_rename
#define rmdir       win32_rmdir
#define unlink      win32_unlink

#endif

237
#endif /* AVFORMAT_OS_SUPPORT_H */