1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * buffered file I/O
3cabdff1aSopenharmony_ci * Copyright (c) 2001 Fabrice Bellard
4cabdff1aSopenharmony_ci *
5cabdff1aSopenharmony_ci * This file is part of FFmpeg.
6cabdff1aSopenharmony_ci *
7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
11cabdff1aSopenharmony_ci *
12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15cabdff1aSopenharmony_ci * Lesser General Public License for more details.
16cabdff1aSopenharmony_ci *
17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20cabdff1aSopenharmony_ci */
21cabdff1aSopenharmony_ci
22cabdff1aSopenharmony_ci#include "config_components.h"
23cabdff1aSopenharmony_ci
24cabdff1aSopenharmony_ci#include "libavutil/avstring.h"
25cabdff1aSopenharmony_ci#include "libavutil/internal.h"
26cabdff1aSopenharmony_ci#include "libavutil/opt.h"
27cabdff1aSopenharmony_ci#include "avformat.h"
28cabdff1aSopenharmony_ci#if HAVE_DIRENT_H
29cabdff1aSopenharmony_ci#include <dirent.h>
30cabdff1aSopenharmony_ci#endif
31cabdff1aSopenharmony_ci#include <fcntl.h>
32cabdff1aSopenharmony_ci#if HAVE_IO_H
33cabdff1aSopenharmony_ci#include <io.h>
34cabdff1aSopenharmony_ci#endif
35cabdff1aSopenharmony_ci#if HAVE_UNISTD_H
36cabdff1aSopenharmony_ci#include <unistd.h>
37cabdff1aSopenharmony_ci#endif
38cabdff1aSopenharmony_ci#include <sys/stat.h>
39cabdff1aSopenharmony_ci#include <stdlib.h>
40cabdff1aSopenharmony_ci#include "os_support.h"
41cabdff1aSopenharmony_ci#include "url.h"
42cabdff1aSopenharmony_ci
43cabdff1aSopenharmony_ci/* Some systems may not have S_ISFIFO */
44cabdff1aSopenharmony_ci#ifndef S_ISFIFO
45cabdff1aSopenharmony_ci#  ifdef S_IFIFO
46cabdff1aSopenharmony_ci#    define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
47cabdff1aSopenharmony_ci#  else
48cabdff1aSopenharmony_ci#    define S_ISFIFO(m) 0
49cabdff1aSopenharmony_ci#  endif
50cabdff1aSopenharmony_ci#endif
51cabdff1aSopenharmony_ci
52cabdff1aSopenharmony_ci/* Not available in POSIX.1-1996 */
53cabdff1aSopenharmony_ci#ifndef S_ISLNK
54cabdff1aSopenharmony_ci#  ifdef S_IFLNK
55cabdff1aSopenharmony_ci#    define S_ISLNK(m) (((m) & S_IFLNK) == S_IFLNK)
56cabdff1aSopenharmony_ci#  else
57cabdff1aSopenharmony_ci#    define S_ISLNK(m) 0
58cabdff1aSopenharmony_ci#  endif
59cabdff1aSopenharmony_ci#endif
60cabdff1aSopenharmony_ci
61cabdff1aSopenharmony_ci/* Not available in POSIX.1-1996 */
62cabdff1aSopenharmony_ci#ifndef S_ISSOCK
63cabdff1aSopenharmony_ci#  ifdef S_IFSOCK
64cabdff1aSopenharmony_ci#    define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
65cabdff1aSopenharmony_ci#  else
66cabdff1aSopenharmony_ci#    define S_ISSOCK(m) 0
67cabdff1aSopenharmony_ci#  endif
68cabdff1aSopenharmony_ci#endif
69cabdff1aSopenharmony_ci
70cabdff1aSopenharmony_ci/* standard file protocol */
71cabdff1aSopenharmony_ci
72cabdff1aSopenharmony_citypedef struct FileContext {
73cabdff1aSopenharmony_ci    const AVClass *class;
74cabdff1aSopenharmony_ci    int fd;
75cabdff1aSopenharmony_ci    int trunc;
76cabdff1aSopenharmony_ci    int blocksize;
77cabdff1aSopenharmony_ci    int follow;
78cabdff1aSopenharmony_ci    int seekable;
79cabdff1aSopenharmony_ci#if HAVE_DIRENT_H
80cabdff1aSopenharmony_ci    DIR *dir;
81cabdff1aSopenharmony_ci#endif
82cabdff1aSopenharmony_ci} FileContext;
83cabdff1aSopenharmony_ci
84cabdff1aSopenharmony_cistatic const AVOption file_options[] = {
85cabdff1aSopenharmony_ci    { "truncate", "truncate existing files on write", offsetof(FileContext, trunc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
86cabdff1aSopenharmony_ci    { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
87cabdff1aSopenharmony_ci    { "follow", "Follow a file as it is being written", offsetof(FileContext, follow), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
88cabdff1aSopenharmony_ci    { "seekable", "Sets if the file is seekable", offsetof(FileContext, seekable), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 0, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
89cabdff1aSopenharmony_ci    { NULL }
90cabdff1aSopenharmony_ci};
91cabdff1aSopenharmony_ci
92cabdff1aSopenharmony_cistatic const AVOption pipe_options[] = {
93cabdff1aSopenharmony_ci    { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
94cabdff1aSopenharmony_ci    { NULL }
95cabdff1aSopenharmony_ci};
96cabdff1aSopenharmony_ci
97cabdff1aSopenharmony_cistatic const AVClass file_class = {
98cabdff1aSopenharmony_ci    .class_name = "file",
99cabdff1aSopenharmony_ci    .item_name  = av_default_item_name,
100cabdff1aSopenharmony_ci    .option     = file_options,
101cabdff1aSopenharmony_ci    .version    = LIBAVUTIL_VERSION_INT,
102cabdff1aSopenharmony_ci};
103cabdff1aSopenharmony_ci
104cabdff1aSopenharmony_cistatic const AVClass pipe_class = {
105cabdff1aSopenharmony_ci    .class_name = "pipe",
106cabdff1aSopenharmony_ci    .item_name  = av_default_item_name,
107cabdff1aSopenharmony_ci    .option     = pipe_options,
108cabdff1aSopenharmony_ci    .version    = LIBAVUTIL_VERSION_INT,
109cabdff1aSopenharmony_ci};
110cabdff1aSopenharmony_ci
111cabdff1aSopenharmony_cistatic int file_read(URLContext *h, unsigned char *buf, int size)
112cabdff1aSopenharmony_ci{
113cabdff1aSopenharmony_ci    FileContext *c = h->priv_data;
114cabdff1aSopenharmony_ci    int ret;
115cabdff1aSopenharmony_ci    size = FFMIN(size, c->blocksize);
116cabdff1aSopenharmony_ci    ret = read(c->fd, buf, size);
117cabdff1aSopenharmony_ci    if (ret == 0 && c->follow)
118cabdff1aSopenharmony_ci        return AVERROR(EAGAIN);
119cabdff1aSopenharmony_ci    if (ret == 0)
120cabdff1aSopenharmony_ci        return AVERROR_EOF;
121cabdff1aSopenharmony_ci    return (ret == -1) ? AVERROR(errno) : ret;
122cabdff1aSopenharmony_ci}
123cabdff1aSopenharmony_ci
124cabdff1aSopenharmony_cistatic int file_write(URLContext *h, const unsigned char *buf, int size)
125cabdff1aSopenharmony_ci{
126cabdff1aSopenharmony_ci    FileContext *c = h->priv_data;
127cabdff1aSopenharmony_ci    int ret;
128cabdff1aSopenharmony_ci    size = FFMIN(size, c->blocksize);
129cabdff1aSopenharmony_ci    ret = write(c->fd, buf, size);
130cabdff1aSopenharmony_ci    return (ret == -1) ? AVERROR(errno) : ret;
131cabdff1aSopenharmony_ci}
132cabdff1aSopenharmony_ci
133cabdff1aSopenharmony_cistatic int file_get_handle(URLContext *h)
134cabdff1aSopenharmony_ci{
135cabdff1aSopenharmony_ci    FileContext *c = h->priv_data;
136cabdff1aSopenharmony_ci    return c->fd;
137cabdff1aSopenharmony_ci}
138cabdff1aSopenharmony_ci
139cabdff1aSopenharmony_cistatic int file_check(URLContext *h, int mask)
140cabdff1aSopenharmony_ci{
141cabdff1aSopenharmony_ci    int ret = 0;
142cabdff1aSopenharmony_ci    const char *filename = h->filename;
143cabdff1aSopenharmony_ci    av_strstart(filename, "file:", &filename);
144cabdff1aSopenharmony_ci
145cabdff1aSopenharmony_ci    {
146cabdff1aSopenharmony_ci#if HAVE_ACCESS && defined(R_OK)
147cabdff1aSopenharmony_ci    if (access(filename, F_OK) < 0)
148cabdff1aSopenharmony_ci        return AVERROR(errno);
149cabdff1aSopenharmony_ci    if (mask&AVIO_FLAG_READ)
150cabdff1aSopenharmony_ci        if (access(filename, R_OK) >= 0)
151cabdff1aSopenharmony_ci            ret |= AVIO_FLAG_READ;
152cabdff1aSopenharmony_ci    if (mask&AVIO_FLAG_WRITE)
153cabdff1aSopenharmony_ci        if (access(filename, W_OK) >= 0)
154cabdff1aSopenharmony_ci            ret |= AVIO_FLAG_WRITE;
155cabdff1aSopenharmony_ci#else
156cabdff1aSopenharmony_ci    struct stat st;
157cabdff1aSopenharmony_ci    ret = stat(filename, &st);
158cabdff1aSopenharmony_ci    if (ret < 0)
159cabdff1aSopenharmony_ci        return AVERROR(errno);
160cabdff1aSopenharmony_ci
161cabdff1aSopenharmony_ci    ret |= st.st_mode&S_IRUSR ? mask&AVIO_FLAG_READ  : 0;
162cabdff1aSopenharmony_ci    ret |= st.st_mode&S_IWUSR ? mask&AVIO_FLAG_WRITE : 0;
163cabdff1aSopenharmony_ci#endif
164cabdff1aSopenharmony_ci    }
165cabdff1aSopenharmony_ci    return ret;
166cabdff1aSopenharmony_ci}
167cabdff1aSopenharmony_ci
168cabdff1aSopenharmony_ci#if CONFIG_FILE_PROTOCOL
169cabdff1aSopenharmony_ci
170cabdff1aSopenharmony_cistatic int file_delete(URLContext *h)
171cabdff1aSopenharmony_ci{
172cabdff1aSopenharmony_ci#if HAVE_UNISTD_H
173cabdff1aSopenharmony_ci    int ret;
174cabdff1aSopenharmony_ci    const char *filename = h->filename;
175cabdff1aSopenharmony_ci    av_strstart(filename, "file:", &filename);
176cabdff1aSopenharmony_ci
177cabdff1aSopenharmony_ci    ret = rmdir(filename);
178cabdff1aSopenharmony_ci    if (ret < 0 && (errno == ENOTDIR
179cabdff1aSopenharmony_ci#   ifdef _WIN32
180cabdff1aSopenharmony_ci        || errno == EINVAL
181cabdff1aSopenharmony_ci#   endif
182cabdff1aSopenharmony_ci        ))
183cabdff1aSopenharmony_ci        ret = unlink(filename);
184cabdff1aSopenharmony_ci    if (ret < 0)
185cabdff1aSopenharmony_ci        return AVERROR(errno);
186cabdff1aSopenharmony_ci
187cabdff1aSopenharmony_ci    return ret;
188cabdff1aSopenharmony_ci#else
189cabdff1aSopenharmony_ci    return AVERROR(ENOSYS);
190cabdff1aSopenharmony_ci#endif /* HAVE_UNISTD_H */
191cabdff1aSopenharmony_ci}
192cabdff1aSopenharmony_ci
193cabdff1aSopenharmony_cistatic int file_move(URLContext *h_src, URLContext *h_dst)
194cabdff1aSopenharmony_ci{
195cabdff1aSopenharmony_ci    const char *filename_src = h_src->filename;
196cabdff1aSopenharmony_ci    const char *filename_dst = h_dst->filename;
197cabdff1aSopenharmony_ci    av_strstart(filename_src, "file:", &filename_src);
198cabdff1aSopenharmony_ci    av_strstart(filename_dst, "file:", &filename_dst);
199cabdff1aSopenharmony_ci
200cabdff1aSopenharmony_ci    if (rename(filename_src, filename_dst) < 0)
201cabdff1aSopenharmony_ci        return AVERROR(errno);
202cabdff1aSopenharmony_ci
203cabdff1aSopenharmony_ci    return 0;
204cabdff1aSopenharmony_ci}
205cabdff1aSopenharmony_ci
206cabdff1aSopenharmony_cistatic int file_open(URLContext *h, const char *filename, int flags)
207cabdff1aSopenharmony_ci{
208cabdff1aSopenharmony_ci    FileContext *c = h->priv_data;
209cabdff1aSopenharmony_ci    int access;
210cabdff1aSopenharmony_ci    int fd;
211cabdff1aSopenharmony_ci    struct stat st;
212cabdff1aSopenharmony_ci
213cabdff1aSopenharmony_ci    av_strstart(filename, "file:", &filename);
214cabdff1aSopenharmony_ci
215cabdff1aSopenharmony_ci    if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ) {
216cabdff1aSopenharmony_ci        access = O_CREAT | O_RDWR;
217cabdff1aSopenharmony_ci        if (c->trunc)
218cabdff1aSopenharmony_ci            access |= O_TRUNC;
219cabdff1aSopenharmony_ci    } else if (flags & AVIO_FLAG_WRITE) {
220cabdff1aSopenharmony_ci        access = O_CREAT | O_WRONLY;
221cabdff1aSopenharmony_ci        if (c->trunc)
222cabdff1aSopenharmony_ci            access |= O_TRUNC;
223cabdff1aSopenharmony_ci    } else {
224cabdff1aSopenharmony_ci        access = O_RDONLY;
225cabdff1aSopenharmony_ci    }
226cabdff1aSopenharmony_ci#ifdef O_BINARY
227cabdff1aSopenharmony_ci    access |= O_BINARY;
228cabdff1aSopenharmony_ci#endif
229cabdff1aSopenharmony_ci    fd = avpriv_open(filename, access, 0666);
230cabdff1aSopenharmony_ci    if (fd == -1)
231cabdff1aSopenharmony_ci        return AVERROR(errno);
232cabdff1aSopenharmony_ci    c->fd = fd;
233cabdff1aSopenharmony_ci
234cabdff1aSopenharmony_ci    h->is_streamed = !fstat(fd, &st) && S_ISFIFO(st.st_mode);
235cabdff1aSopenharmony_ci
236cabdff1aSopenharmony_ci    /* Buffer writes more than the default 32k to improve throughput especially
237cabdff1aSopenharmony_ci     * with networked file systems */
238cabdff1aSopenharmony_ci    if (!h->is_streamed && flags & AVIO_FLAG_WRITE)
239cabdff1aSopenharmony_ci        h->min_packet_size = h->max_packet_size = 262144;
240cabdff1aSopenharmony_ci
241cabdff1aSopenharmony_ci    if (c->seekable >= 0)
242cabdff1aSopenharmony_ci        h->is_streamed = !c->seekable;
243cabdff1aSopenharmony_ci
244cabdff1aSopenharmony_ci    return 0;
245cabdff1aSopenharmony_ci}
246cabdff1aSopenharmony_ci
247cabdff1aSopenharmony_ci/* XXX: use llseek */
248cabdff1aSopenharmony_cistatic int64_t file_seek(URLContext *h, int64_t pos, int whence)
249cabdff1aSopenharmony_ci{
250cabdff1aSopenharmony_ci    FileContext *c = h->priv_data;
251cabdff1aSopenharmony_ci    int64_t ret;
252cabdff1aSopenharmony_ci
253cabdff1aSopenharmony_ci    if (whence == AVSEEK_SIZE) {
254cabdff1aSopenharmony_ci        struct stat st;
255cabdff1aSopenharmony_ci        ret = fstat(c->fd, &st);
256cabdff1aSopenharmony_ci        return ret < 0 ? AVERROR(errno) : (S_ISFIFO(st.st_mode) ? 0 : st.st_size);
257cabdff1aSopenharmony_ci    }
258cabdff1aSopenharmony_ci
259cabdff1aSopenharmony_ci    ret = lseek(c->fd, pos, whence);
260cabdff1aSopenharmony_ci
261cabdff1aSopenharmony_ci    return ret < 0 ? AVERROR(errno) : ret;
262cabdff1aSopenharmony_ci}
263cabdff1aSopenharmony_ci
264cabdff1aSopenharmony_cistatic int file_close(URLContext *h)
265cabdff1aSopenharmony_ci{
266cabdff1aSopenharmony_ci    FileContext *c = h->priv_data;
267cabdff1aSopenharmony_ci    int ret = close(c->fd);
268cabdff1aSopenharmony_ci    return (ret == -1) ? AVERROR(errno) : 0;
269cabdff1aSopenharmony_ci}
270cabdff1aSopenharmony_ci
271cabdff1aSopenharmony_cistatic int file_open_dir(URLContext *h)
272cabdff1aSopenharmony_ci{
273cabdff1aSopenharmony_ci#if HAVE_LSTAT
274cabdff1aSopenharmony_ci    FileContext *c = h->priv_data;
275cabdff1aSopenharmony_ci
276cabdff1aSopenharmony_ci    c->dir = opendir(h->filename);
277cabdff1aSopenharmony_ci    if (!c->dir)
278cabdff1aSopenharmony_ci        return AVERROR(errno);
279cabdff1aSopenharmony_ci
280cabdff1aSopenharmony_ci    return 0;
281cabdff1aSopenharmony_ci#else
282cabdff1aSopenharmony_ci    return AVERROR(ENOSYS);
283cabdff1aSopenharmony_ci#endif /* HAVE_LSTAT */
284cabdff1aSopenharmony_ci}
285cabdff1aSopenharmony_ci
286cabdff1aSopenharmony_cistatic int file_read_dir(URLContext *h, AVIODirEntry **next)
287cabdff1aSopenharmony_ci{
288cabdff1aSopenharmony_ci#if HAVE_LSTAT
289cabdff1aSopenharmony_ci    FileContext *c = h->priv_data;
290cabdff1aSopenharmony_ci    struct dirent *dir;
291cabdff1aSopenharmony_ci    char *fullpath = NULL;
292cabdff1aSopenharmony_ci
293cabdff1aSopenharmony_ci    *next = ff_alloc_dir_entry();
294cabdff1aSopenharmony_ci    if (!*next)
295cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
296cabdff1aSopenharmony_ci    do {
297cabdff1aSopenharmony_ci        errno = 0;
298cabdff1aSopenharmony_ci        dir = readdir(c->dir);
299cabdff1aSopenharmony_ci        if (!dir) {
300cabdff1aSopenharmony_ci            av_freep(next);
301cabdff1aSopenharmony_ci            return AVERROR(errno);
302cabdff1aSopenharmony_ci        }
303cabdff1aSopenharmony_ci    } while (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, ".."));
304cabdff1aSopenharmony_ci
305cabdff1aSopenharmony_ci    fullpath = av_append_path_component(h->filename, dir->d_name);
306cabdff1aSopenharmony_ci    if (fullpath) {
307cabdff1aSopenharmony_ci        struct stat st;
308cabdff1aSopenharmony_ci        if (!lstat(fullpath, &st)) {
309cabdff1aSopenharmony_ci            if (S_ISDIR(st.st_mode))
310cabdff1aSopenharmony_ci                (*next)->type = AVIO_ENTRY_DIRECTORY;
311cabdff1aSopenharmony_ci            else if (S_ISFIFO(st.st_mode))
312cabdff1aSopenharmony_ci                (*next)->type = AVIO_ENTRY_NAMED_PIPE;
313cabdff1aSopenharmony_ci            else if (S_ISCHR(st.st_mode))
314cabdff1aSopenharmony_ci                (*next)->type = AVIO_ENTRY_CHARACTER_DEVICE;
315cabdff1aSopenharmony_ci            else if (S_ISBLK(st.st_mode))
316cabdff1aSopenharmony_ci                (*next)->type = AVIO_ENTRY_BLOCK_DEVICE;
317cabdff1aSopenharmony_ci            else if (S_ISLNK(st.st_mode))
318cabdff1aSopenharmony_ci                (*next)->type = AVIO_ENTRY_SYMBOLIC_LINK;
319cabdff1aSopenharmony_ci            else if (S_ISSOCK(st.st_mode))
320cabdff1aSopenharmony_ci                (*next)->type = AVIO_ENTRY_SOCKET;
321cabdff1aSopenharmony_ci            else if (S_ISREG(st.st_mode))
322cabdff1aSopenharmony_ci                (*next)->type = AVIO_ENTRY_FILE;
323cabdff1aSopenharmony_ci            else
324cabdff1aSopenharmony_ci                (*next)->type = AVIO_ENTRY_UNKNOWN;
325cabdff1aSopenharmony_ci
326cabdff1aSopenharmony_ci            (*next)->group_id = st.st_gid;
327cabdff1aSopenharmony_ci            (*next)->user_id = st.st_uid;
328cabdff1aSopenharmony_ci            (*next)->size = st.st_size;
329cabdff1aSopenharmony_ci            (*next)->filemode = st.st_mode & 0777;
330cabdff1aSopenharmony_ci            (*next)->modification_timestamp = INT64_C(1000000) * st.st_mtime;
331cabdff1aSopenharmony_ci            (*next)->access_timestamp =  INT64_C(1000000) * st.st_atime;
332cabdff1aSopenharmony_ci            (*next)->status_change_timestamp = INT64_C(1000000) * st.st_ctime;
333cabdff1aSopenharmony_ci        }
334cabdff1aSopenharmony_ci        av_free(fullpath);
335cabdff1aSopenharmony_ci    }
336cabdff1aSopenharmony_ci
337cabdff1aSopenharmony_ci    (*next)->name = av_strdup(dir->d_name);
338cabdff1aSopenharmony_ci    return 0;
339cabdff1aSopenharmony_ci#else
340cabdff1aSopenharmony_ci    return AVERROR(ENOSYS);
341cabdff1aSopenharmony_ci#endif /* HAVE_LSTAT */
342cabdff1aSopenharmony_ci}
343cabdff1aSopenharmony_ci
344cabdff1aSopenharmony_cistatic int file_close_dir(URLContext *h)
345cabdff1aSopenharmony_ci{
346cabdff1aSopenharmony_ci#if HAVE_LSTAT
347cabdff1aSopenharmony_ci    FileContext *c = h->priv_data;
348cabdff1aSopenharmony_ci    closedir(c->dir);
349cabdff1aSopenharmony_ci    return 0;
350cabdff1aSopenharmony_ci#else
351cabdff1aSopenharmony_ci    return AVERROR(ENOSYS);
352cabdff1aSopenharmony_ci#endif /* HAVE_LSTAT */
353cabdff1aSopenharmony_ci}
354cabdff1aSopenharmony_ci
355cabdff1aSopenharmony_ciconst URLProtocol ff_file_protocol = {
356cabdff1aSopenharmony_ci    .name                = "file",
357cabdff1aSopenharmony_ci    .url_open            = file_open,
358cabdff1aSopenharmony_ci    .url_read            = file_read,
359cabdff1aSopenharmony_ci    .url_write           = file_write,
360cabdff1aSopenharmony_ci    .url_seek            = file_seek,
361cabdff1aSopenharmony_ci    .url_close           = file_close,
362cabdff1aSopenharmony_ci    .url_get_file_handle = file_get_handle,
363cabdff1aSopenharmony_ci    .url_check           = file_check,
364cabdff1aSopenharmony_ci    .url_delete          = file_delete,
365cabdff1aSopenharmony_ci    .url_move            = file_move,
366cabdff1aSopenharmony_ci    .priv_data_size      = sizeof(FileContext),
367cabdff1aSopenharmony_ci    .priv_data_class     = &file_class,
368cabdff1aSopenharmony_ci    .url_open_dir        = file_open_dir,
369cabdff1aSopenharmony_ci    .url_read_dir        = file_read_dir,
370cabdff1aSopenharmony_ci    .url_close_dir       = file_close_dir,
371cabdff1aSopenharmony_ci    .default_whitelist   = "file,crypto,data"
372cabdff1aSopenharmony_ci};
373cabdff1aSopenharmony_ci
374cabdff1aSopenharmony_ci#endif /* CONFIG_FILE_PROTOCOL */
375cabdff1aSopenharmony_ci
376cabdff1aSopenharmony_ci#if CONFIG_PIPE_PROTOCOL
377cabdff1aSopenharmony_ci
378cabdff1aSopenharmony_cistatic int pipe_open(URLContext *h, const char *filename, int flags)
379cabdff1aSopenharmony_ci{
380cabdff1aSopenharmony_ci    FileContext *c = h->priv_data;
381cabdff1aSopenharmony_ci    int fd;
382cabdff1aSopenharmony_ci    char *final;
383cabdff1aSopenharmony_ci    av_strstart(filename, "pipe:", &filename);
384cabdff1aSopenharmony_ci
385cabdff1aSopenharmony_ci    fd = strtol(filename, &final, 10);
386cabdff1aSopenharmony_ci    if((filename == final) || *final ) {/* No digits found, or something like 10ab */
387cabdff1aSopenharmony_ci        if (flags & AVIO_FLAG_WRITE) {
388cabdff1aSopenharmony_ci            fd = 1;
389cabdff1aSopenharmony_ci        } else {
390cabdff1aSopenharmony_ci            fd = 0;
391cabdff1aSopenharmony_ci        }
392cabdff1aSopenharmony_ci    }
393cabdff1aSopenharmony_ci#if HAVE_SETMODE
394cabdff1aSopenharmony_ci    setmode(fd, O_BINARY);
395cabdff1aSopenharmony_ci#endif
396cabdff1aSopenharmony_ci    c->fd = fd;
397cabdff1aSopenharmony_ci    h->is_streamed = 1;
398cabdff1aSopenharmony_ci    return 0;
399cabdff1aSopenharmony_ci}
400cabdff1aSopenharmony_ci
401cabdff1aSopenharmony_ciconst URLProtocol ff_pipe_protocol = {
402cabdff1aSopenharmony_ci    .name                = "pipe",
403cabdff1aSopenharmony_ci    .url_open            = pipe_open,
404cabdff1aSopenharmony_ci    .url_read            = file_read,
405cabdff1aSopenharmony_ci    .url_write           = file_write,
406cabdff1aSopenharmony_ci    .url_get_file_handle = file_get_handle,
407cabdff1aSopenharmony_ci    .url_check           = file_check,
408cabdff1aSopenharmony_ci    .priv_data_size      = sizeof(FileContext),
409cabdff1aSopenharmony_ci    .priv_data_class     = &pipe_class,
410cabdff1aSopenharmony_ci    .default_whitelist   = "crypto,data"
411cabdff1aSopenharmony_ci};
412cabdff1aSopenharmony_ci
413cabdff1aSopenharmony_ci#endif /* CONFIG_PIPE_PROTOCOL */
414