1/* 2 * buffered file I/O 3 * Copyright (c) 2001 Fabrice Bellard 4 * 5 * This file is part of Libav. 6 * 7 * Libav 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 * Libav 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 Libav; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22#include "libavutil/avstring.h" 23#include "avformat.h" 24#include <fcntl.h> 25#if HAVE_SETMODE 26#include <io.h> 27#endif 28#include <unistd.h> 29#include <sys/stat.h> 30#include <stdlib.h> 31#include "os_support.h" 32#include "url.h" 33 34 35/* standard file protocol */ 36 37static int file_read(URLContext *h, unsigned char *buf, int size) 38{ 39 int fd = (intptr_t) h->priv_data; 40 return read(fd, buf, size); 41} 42 43static int file_write(URLContext *h, const unsigned char *buf, int size) 44{ 45 int fd = (intptr_t) h->priv_data; 46 return write(fd, buf, size); 47} 48 49static int file_get_handle(URLContext *h) 50{ 51 return (intptr_t) h->priv_data; 52} 53 54static int file_check(URLContext *h, int mask) 55{ 56 struct stat st; 57 int ret = stat(h->filename, &st); 58 if (ret < 0) 59 return AVERROR(errno); 60 61 ret |= st.st_mode&S_IRUSR ? mask&AVIO_FLAG_READ : 0; 62 ret |= st.st_mode&S_IWUSR ? mask&AVIO_FLAG_WRITE : 0; 63 64 return ret; 65} 66 67#if CONFIG_FILE_PROTOCOL 68 69static int file_open(URLContext *h, const char *filename, int flags) 70{ 71 int access; 72 int fd; 73 74 av_strstart(filename, "file:", &filename); 75 76 if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ) { 77 access = O_CREAT | O_TRUNC | O_RDWR; 78 } else if (flags & AVIO_FLAG_WRITE) { 79 access = O_CREAT | O_TRUNC | O_WRONLY; 80 } else { 81 access = O_RDONLY; 82 } 83#ifdef O_BINARY 84 access |= O_BINARY; 85#endif 86 fd = open(filename, access, 0666); 87 if (fd == -1) 88 return AVERROR(errno); 89 h->priv_data = (void *) (intptr_t) fd; 90 return 0; 91} 92 93/* XXX: use llseek */ 94static int64_t file_seek(URLContext *h, int64_t pos, int whence) 95{ 96 int fd = (intptr_t) h->priv_data; 97 if (whence == AVSEEK_SIZE) { 98 struct stat st; 99 int ret = fstat(fd, &st); 100 return ret < 0 ? AVERROR(errno) : st.st_size; 101 } 102 return lseek(fd, pos, whence); 103} 104 105static int file_close(URLContext *h) 106{ 107 int fd = (intptr_t) h->priv_data; 108 return close(fd); 109} 110 111URLProtocol ff_file_protocol = { 112 .name = "file", 113 .url_open = file_open, 114 .url_read = file_read, 115 .url_write = file_write, 116 .url_seek = file_seek, 117 .url_close = file_close, 118 .url_get_file_handle = file_get_handle, 119 .url_check = file_check, 120}; 121 122#endif /* CONFIG_FILE_PROTOCOL */ 123 124#if CONFIG_PIPE_PROTOCOL 125 126static int pipe_open(URLContext *h, const char *filename, int flags) 127{ 128 int fd; 129 char *final; 130 av_strstart(filename, "pipe:", &filename); 131 132 fd = strtol(filename, &final, 10); 133 if((filename == final) || *final ) {/* No digits found, or something like 10ab */ 134 if (flags & AVIO_FLAG_WRITE) { 135 fd = 1; 136 } else { 137 fd = 0; 138 } 139 } 140#if HAVE_SETMODE 141 setmode(fd, O_BINARY); 142#endif 143 h->priv_data = (void *) (intptr_t) fd; 144 h->is_streamed = 1; 145 return 0; 146} 147 148URLProtocol ff_pipe_protocol = { 149 .name = "pipe", 150 .url_open = pipe_open, 151 .url_read = file_read, 152 .url_write = file_write, 153 .url_get_file_handle = file_get_handle, 154 .url_check = file_check, 155}; 156 157#endif /* CONFIG_PIPE_PROTOCOL */ 158