00001 /* 00002 * Buffered file io for ffmpeg system 00003 * Copyright (c) 2001 Fabrice Bellard 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include "libavutil/avstring.h" 00023 #include "avformat.h" 00024 #include <fcntl.h> 00025 #if HAVE_SETMODE 00026 #include <io.h> 00027 #endif 00028 #include <unistd.h> 00029 #include <sys/time.h> 00030 #include <stdlib.h> 00031 #include "os_support.h" 00032 00033 00034 /* standard file protocol */ 00035 00036 static int file_open(URLContext *h, const char *filename, int flags) 00037 { 00038 int access; 00039 int fd; 00040 00041 av_strstart(filename, "file:", &filename); 00042 00043 if (flags & URL_RDWR) { 00044 access = O_CREAT | O_TRUNC | O_RDWR; 00045 } else if (flags & URL_WRONLY) { 00046 access = O_CREAT | O_TRUNC | O_WRONLY; 00047 } else { 00048 access = O_RDONLY; 00049 } 00050 #ifdef O_BINARY 00051 access |= O_BINARY; 00052 #endif 00053 fd = open(filename, access, 0666); 00054 if (fd < 0) 00055 return AVERROR(ENOENT); 00056 h->priv_data = (void *)(size_t)fd; 00057 return 0; 00058 } 00059 00060 static int file_read(URLContext *h, unsigned char *buf, int size) 00061 { 00062 int fd = (size_t)h->priv_data; 00063 return read(fd, buf, size); 00064 } 00065 00066 static int file_write(URLContext *h, unsigned char *buf, int size) 00067 { 00068 int fd = (size_t)h->priv_data; 00069 return write(fd, buf, size); 00070 } 00071 00072 /* XXX: use llseek */ 00073 static int64_t file_seek(URLContext *h, int64_t pos, int whence) 00074 { 00075 int fd = (size_t)h->priv_data; 00076 return lseek(fd, pos, whence); 00077 } 00078 00079 static int file_close(URLContext *h) 00080 { 00081 int fd = (size_t)h->priv_data; 00082 return close(fd); 00083 } 00084 00085 URLProtocol file_protocol = { 00086 "file", 00087 file_open, 00088 file_read, 00089 file_write, 00090 file_seek, 00091 file_close, 00092 }; 00093 00094 /* pipe protocol */ 00095 00096 static int pipe_open(URLContext *h, const char *filename, int flags) 00097 { 00098 int fd; 00099 char *final; 00100 av_strstart(filename, "pipe:", &filename); 00101 00102 fd = strtol(filename, &final, 10); 00103 if((filename == final) || *final ) {/* No digits found, or something like 10ab */ 00104 if (flags & URL_WRONLY) { 00105 fd = 1; 00106 } else { 00107 fd = 0; 00108 } 00109 } 00110 #if HAVE_SETMODE 00111 setmode(fd, O_BINARY); 00112 #endif 00113 h->priv_data = (void *)(size_t)fd; 00114 h->is_streamed = 1; 00115 return 0; 00116 } 00117 00118 URLProtocol pipe_protocol = { 00119 "pipe", 00120 pipe_open, 00121 file_read, 00122 file_write, 00123 };