]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blob - libavformat/file.c
Prepare for O_DIRECT
[frescor/ffmpeg.git] / libavformat / file.c
1 /*
2  * Buffered file io for ffmpeg system
3  * Copyright (c) 2001 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 #define _GNU_SOURCE
23 #include "libavutil/avstring.h"
24 #include "avformat.h"
25 #include <fcntl.h>
26 #if HAVE_SETMODE
27 #include <io.h>
28 #endif
29 #include <unistd.h>
30 #include <sys/time.h>
31 #include <stdlib.h>
32 #include "os_support.h"
33
34
35 /* standard file protocol */
36
37 struct FileContext {
38     int fd;
39 };
40
41 static int file_open(URLContext *h, const char *filename, int flags)
42 {
43     struct FileContext *s = h->priv_data;
44     int access;
45     int fd;
46
47     av_strstart(filename, "file:", &filename);
48
49     if (flags & URL_RDWR) {
50         access = O_CREAT | O_TRUNC | O_RDWR;
51     } else if (flags & URL_WRONLY) {
52         access = O_CREAT | O_TRUNC | O_WRONLY;
53     } else {
54         access = O_RDONLY;
55     }
56 #ifdef O_BINARY
57     access |= O_BINARY;
58 #endif
59     s = av_malloc(sizeof(struct FileContext));
60     if (!s)
61         return AVERROR(ENOMEM);
62     if (flags & URL_DIRECT)
63         access |= O_DIRECT;
64     fd = open(filename, access, 0666);
65     if (fd < 0)
66         return AVERROR(ENOENT);
67     s->fd = fd;
68     h->priv_data = (void *) s;
69     return 0;
70 }
71
72 static int file_read(URLContext *h, unsigned char *buf, int size)
73 {
74     struct FileContext *s = h->priv_data;
75     int fd = s->fd;
76     return read(fd, buf, size);
77 }
78
79 static int file_write(URLContext *h, unsigned char *buf, int size)
80 {
81     struct FileContext *s = h->priv_data;
82     int fd = s->fd;
83     return write(fd, buf, size);
84 }
85
86 /* XXX: use llseek */
87 static int64_t file_seek(URLContext *h, int64_t pos, int whence)
88 {
89     struct FileContext *s = h->priv_data;
90     int fd = s->fd;
91     return lseek(fd, pos, whence);
92 }
93
94 static int file_close(URLContext *h)
95 {
96     struct FileContext *s = h->priv_data;
97     int fd = s->fd;
98     return close(fd);
99 }
100
101 static int file_get_handle(URLContext *h)
102 {
103     return (intptr_t) h->priv_data;
104 }
105
106 URLProtocol file_protocol = {
107     "file",
108     file_open,
109     file_read,
110     file_write,
111     file_seek,
112     file_close,
113     .url_get_file_handle = file_get_handle,
114 };
115
116 /* pipe protocol */
117
118 static int pipe_open(URLContext *h, const char *filename, int flags)
119 {
120     int fd;
121     char *final;
122     av_strstart(filename, "pipe:", &filename);
123
124     fd = strtol(filename, &final, 10);
125     if((filename == final) || *final ) {/* No digits found, or something like 10ab */
126         if (flags & URL_WRONLY) {
127             fd = 1;
128         } else {
129             fd = 0;
130         }
131     }
132 #if HAVE_SETMODE
133     setmode(fd, O_BINARY);
134 #endif
135     h->priv_data = (void *) (intptr_t) fd;
136     h->is_streamed = 1;
137     return 0;
138 }
139
140 URLProtocol pipe_protocol = {
141     "pipe",
142     pipe_open,
143     file_read,
144     file_write,
145     .url_get_file_handle = file_get_handle,
146 };