Mercurial > mplayer.hg
annotate stream/stream_file.c @ 35078:d698d80bb438
Pass input to "strings" via stdin.
That disables any "clever" parsing that will fail if strings
was not updated to support that particular binary format.
This can easily happen when cross-compiling, but obviously
strings on OSX 10.6 was never update to handle the latest
(64 bit) binary format either and would previously just fail
(the obvious way of falling back to the generic algorithm in
that case would have been too user-friendly I guess...)
author | reimar |
---|---|
date | Wed, 12 Sep 2012 22:01:36 +0000 |
parents | 5f3501f7f4d9 |
children | ceb148e1fe31 |
rev | line source |
---|---|
30426
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
1 /* |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
2 * This file is part of MPlayer. |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
3 * |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
4 * MPlayer is free software; you can redistribute it and/or modify |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
5 * it under the terms of the GNU General Public License as published by |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
6 * the Free Software Foundation; either version 2 of the License, or |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
7 * (at your option) any later version. |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
8 * |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
9 * MPlayer is distributed in the hope that it will be useful, |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
12 * GNU General Public License for more details. |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
13 * |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
14 * You should have received a copy of the GNU General Public License along |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
ce0122361a39
Add license header to all files missing it in the stream subdirectory.
diego
parents:
29920
diff
changeset
|
17 */ |
9794 | 18 |
19 #include "config.h" | |
20 | |
16748
ec02252fbaa6
we need stdio.h for SEEK_SET on mingw, patch by Zuxy <zuxy.meng at gmail.com>
faust3
parents:
15461
diff
changeset
|
21 #include <stdio.h> |
9794 | 22 #include <sys/types.h> |
23 #include <sys/stat.h> | |
24 #include <fcntl.h> | |
25 #include <unistd.h> | |
33759 | 26 #if HAVE_SETMODE |
27 #include <io.h> | |
28 #endif | |
9794 | 29 |
30 #include "mp_msg.h" | |
31 #include "stream.h" | |
32 #include "help_mp.h" | |
17012 | 33 #include "m_option.h" |
34 #include "m_struct.h" | |
9794 | 35 |
36 static struct stream_priv_s { | |
37 char* filename; | |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
38 char *filename2; |
9794 | 39 } stream_priv_dflts = { |
15452 | 40 NULL, NULL |
9794 | 41 }; |
42 | |
43 #define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f) | |
44 /// URL definition | |
25242 | 45 static const m_option_t stream_opts_fields[] = { |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
46 {"string", ST_OFF(filename), CONF_TYPE_STRING, 0, 0 ,0, NULL}, |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
47 {"filename", ST_OFF(filename2), CONF_TYPE_STRING, 0, 0 ,0, NULL}, |
9794 | 48 { NULL, NULL, 0, 0, 0, 0, NULL } |
49 }; | |
25691 | 50 static const struct m_struct_st stream_opts = { |
9794 | 51 "file", |
52 sizeof(struct stream_priv_s), | |
53 &stream_priv_dflts, | |
54 stream_opts_fields | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27727
diff
changeset
|
55 }; |
9794 | 56 |
57 static int fill_buffer(stream_t *s, char* buffer, int max_len){ | |
58 int r = read(s->fd,buffer,max_len); | |
35018
5f3501f7f4d9
Explicitly signal EOF when reaching the end of a file/pipe.
reimar
parents:
33759
diff
changeset
|
59 // We are certain this is EOF, do not retry |
5f3501f7f4d9
Explicitly signal EOF when reaching the end of a file/pipe.
reimar
parents:
33759
diff
changeset
|
60 if (max_len && r == 0) s->eof = 1; |
9794 | 61 return (r <= 0) ? -1 : r; |
62 } | |
63 | |
64 static int write_buffer(stream_t *s, char* buffer, int len) { | |
32794
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
65 int r; |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
66 int wr = 0; |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
67 while (wr < len) { |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
68 r = write(s->fd,buffer,len); |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
69 if (r <= 0) |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
70 return -1; |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
71 wr += r; |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
72 buffer += r; |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
73 } |
77d81e27a176
Fix stream_write_buffer to make sure all requested bytes are written
ranma
parents:
32529
diff
changeset
|
74 return len; |
9794 | 75 } |
76 | |
77 static int seek(stream_t *s,off_t newpos) { | |
78 s->pos = newpos; | |
79 if(lseek(s->fd,s->pos,SEEK_SET)<0) { | |
80 s->eof=1; | |
81 return 0; | |
82 } | |
83 return 1; | |
84 } | |
85 | |
86 static int seek_forward(stream_t *s,off_t newpos) { | |
87 if(newpos<s->pos){ | |
88 mp_msg(MSGT_STREAM,MSGL_INFO,"Cannot seek backward in linear streams!\n"); | |
89 return 0; | |
90 } | |
91 while(s->pos<newpos){ | |
12018 | 92 int len=s->fill_buffer(s,s->buffer,STREAM_BUFFER_SIZE); |
93 if(len<=0){ s->eof=1; s->buf_pos=s->buf_len=0; break; } // EOF | |
94 s->buf_pos=0; | |
95 s->buf_len=len; | |
96 s->pos+=len; | |
9794 | 97 } |
98 return 1; | |
99 } | |
100 | |
21658 | 101 static int control(stream_t *s, int cmd, void *arg) { |
102 switch(cmd) { | |
103 case STREAM_CTRL_GET_SIZE: { | |
104 off_t size; | |
105 | |
106 size = lseek(s->fd, 0, SEEK_END); | |
107 lseek(s->fd, s->pos, SEEK_SET); | |
108 if(size != (off_t)-1) { | |
109 *((off_t*)arg) = size; | |
110 return 1; | |
111 } | |
112 } | |
113 } | |
24257 | 114 return STREAM_UNSUPPORTED; |
21658 | 115 } |
116 | |
9794 | 117 static int open_f(stream_t *stream,int mode, void* opts, int* file_format) { |
118 int f; | |
119 mode_t m = 0; | |
120 off_t len; | |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
121 unsigned char *filename; |
9794 | 122 struct stream_priv_s* p = (struct stream_priv_s*)opts; |
123 | |
124 if(mode == STREAM_READ) | |
125 m = O_RDONLY; | |
126 else if(mode == STREAM_WRITE) | |
22451
86f7b9cab33b
truncate mencoder's output file if it exists, instead of overwriting just part of it.
lorenm
parents:
21705
diff
changeset
|
127 m = O_RDWR|O_CREAT|O_TRUNC; |
9794 | 128 else { |
10608 | 129 mp_msg(MSGT_OPEN,MSGL_ERR, "[file] Unknown open mode %d\n",mode); |
9794 | 130 m_struct_free(&stream_opts,opts); |
24257 | 131 return STREAM_UNSUPPORTED; |
9794 | 132 } |
133 | |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
134 if(p->filename) |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
135 filename = p->filename; |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
136 else if(p->filename2) |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
137 filename = p->filename2; |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
138 else |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
139 filename = NULL; |
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
140 if(!filename) { |
9849 | 141 mp_msg(MSGT_OPEN,MSGL_ERR, "[file] No filename\n"); |
142 m_struct_free(&stream_opts,opts); | |
143 return STREAM_ERROR; | |
144 } | |
145 | |
30608
c05fbacce55f
Replace platform preprocessor check by HAVE_DOS_PATHS.
komh
parents:
30426
diff
changeset
|
146 #if HAVE_DOS_PATHS |
26005 | 147 // extract '/' from '/x:/path' |
148 if( filename[ 0 ] == '/' && filename[ 1 ] && filename[ 2 ] == ':' ) | |
149 filename++; | |
150 #endif | |
151 | |
9794 | 152 m |= O_BINARY; |
153 | |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
154 if(!strcmp(filename,"-")){ |
9794 | 155 if(mode == STREAM_READ) { |
156 // read from stdin | |
157 mp_msg(MSGT_OPEN,MSGL_INFO,MSGTR_ReadSTDIN); | |
158 f=0; // 0=stdin | |
30787
e10ba171be06
Define HAVE_SETMODE conditionally, and use it in stream/stream_file.c instead
komh
parents:
30608
diff
changeset
|
159 #if HAVE_SETMODE |
e10ba171be06
Define HAVE_SETMODE conditionally, and use it in stream/stream_file.c instead
komh
parents:
30608
diff
changeset
|
160 setmode(fileno(stdin),O_BINARY); |
12921 | 161 #endif |
9794 | 162 } else { |
163 mp_msg(MSGT_OPEN,MSGL_INFO,"Writing to stdout\n"); | |
164 f=1; | |
30787
e10ba171be06
Define HAVE_SETMODE conditionally, and use it in stream/stream_file.c instead
komh
parents:
30608
diff
changeset
|
165 #if HAVE_SETMODE |
e10ba171be06
Define HAVE_SETMODE conditionally, and use it in stream/stream_file.c instead
komh
parents:
30608
diff
changeset
|
166 setmode(fileno(stdout),O_BINARY); |
12921 | 167 #endif |
9794 | 168 } |
169 } else { | |
21705
829b1f30a07f
fix compilation on the most delicious variant of unix (mingw) that lacks S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
nicodvb
parents:
21673
diff
changeset
|
170 mode_t openmode = S_IRUSR|S_IWUSR; |
829b1f30a07f
fix compilation on the most delicious variant of unix (mingw) that lacks S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
nicodvb
parents:
21673
diff
changeset
|
171 #ifndef __MINGW32__ |
829b1f30a07f
fix compilation on the most delicious variant of unix (mingw) that lacks S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
nicodvb
parents:
21673
diff
changeset
|
172 openmode |= S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; |
829b1f30a07f
fix compilation on the most delicious variant of unix (mingw) that lacks S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
nicodvb
parents:
21673
diff
changeset
|
173 #endif |
829b1f30a07f
fix compilation on the most delicious variant of unix (mingw) that lacks S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
nicodvb
parents:
21673
diff
changeset
|
174 f=open(filename,m, openmode); |
9794 | 175 if(f<0) { |
15461
7c272bfba96f
fixed file:// syntax using newly introduced -string- urlpart
nicodvb
parents:
15452
diff
changeset
|
176 mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_FileNotFound,filename); |
9794 | 177 m_struct_free(&stream_opts,opts); |
9827 | 178 return STREAM_ERROR; |
9794 | 179 } |
180 } | |
181 | |
182 len=lseek(f,0,SEEK_END); lseek(f,0,SEEK_SET); | |
12921 | 183 #ifdef __MINGW32__ |
31883 | 184 // seeks on stdin incorrectly succeed on MinGW |
185 if(f==0) | |
186 len = -1; | |
187 #endif | |
9794 | 188 if(len == -1) { |
21656
32c50eb3ff18
in STREAM_WRITE mode open the stream with O_RDWR|O_CREAT, S_IRUSR|S_IWUSR and disable seek_forward for pipes
nicodvb
parents:
19271
diff
changeset
|
189 if(mode == STREAM_READ) stream->seek = seek_forward; |
9794 | 190 stream->type = STREAMTYPE_STREAM; // Must be move to STREAMTYPE_FILE |
29920
4f740437ed2b
Finally rename the STREAM_SEEK define to MP_STREAM_SEEK, there are just too many
reimar
parents:
29304
diff
changeset
|
191 stream->flags |= MP_STREAM_SEEK_FW; |
9794 | 192 } else if(len >= 0) { |
193 stream->seek = seek; | |
194 stream->end_pos = len; | |
195 stream->type = STREAMTYPE_FILE; | |
196 } | |
197 | |
16750
0a31740dd5e6
Use PRI?64 defines as format strings for 64 bit variables.
reimar
parents:
16748
diff
changeset
|
198 mp_msg(MSGT_OPEN,MSGL_V,"[file] File size is %"PRId64" bytes\n", (int64_t)len); |
9794 | 199 |
200 stream->fd = f; | |
201 stream->fill_buffer = fill_buffer; | |
202 stream->write_buffer = write_buffer; | |
21658 | 203 stream->control = control; |
32529
0624fa95a2aa
Make the file protocol read up to 64 kB at once when the cache is used,
reimar
parents:
31883
diff
changeset
|
204 stream->read_chunk = 64*1024; |
9794 | 205 |
206 m_struct_free(&stream_opts,opts); | |
207 return STREAM_OK; | |
208 } | |
209 | |
25211 | 210 const stream_info_t stream_info_file = { |
9794 | 211 "File", |
212 "file", | |
213 "Albeu", | |
214 "based on the code from ??? (probably Arpi)", | |
215 open_f, | |
216 { "file", "", NULL }, | |
217 &stream_opts, | |
218 1 // Urls are an option string | |
219 }; |