summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/input/input_file.c51
1 files changed, 42 insertions, 9 deletions
diff --git a/src/input/input_file.c b/src/input/input_file.c
index 28cbf5ed5..93d208c4e 100644
--- a/src/input/input_file.c
+++ b/src/input/input_file.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: input_file.c,v 1.116 2006/09/16 14:38:18 tmattern Exp $
+ * $Id: input_file.c,v 1.117 2006/10/01 20:14:43 dgp85 Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -114,12 +114,41 @@ static uint32_t file_plugin_get_capabilities (input_plugin_t *this_gen) {
#endif /* _MSC_VER */
}
+#ifdef HAVE_MMAP
+/**
+ * @brief Check if the file can be read through mmap().
+ * @param this The instance of the input plugin to check
+ * with
+ * @return 1 if the file can still be mmapped, 0 if the file
+ * changed size
+ */
+static int check_mmap_file(file_input_plugin_t *this) {
+ struct stat sbuf;
+
+ if ( ! this->mmap_on ) return 0;
+
+ if ( fstat (this->fh, &sbuf) != 0 ) {
+ return 0;
+ }
+
+ /* If the file grew, we're most likely dealing with a timeshifting recording
+ * so switch to normal access. */
+ if ( this->mmap_len != sbuf.st_size ) {
+ this->mmap_on = 0;
+
+ lseek(this->fh, this->mmap_curr - this->mmap_base, SEEK_SET);
+ return 0;
+ }
+
+ return 1;
+}
+#endif
static off_t file_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) {
file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
#ifdef HAVE_MMAP
- if ( this->mmap_on ) {
+ if ( check_mmap_file(this) ) {
off_t l = len;
if ( (this->mmap_curr + len) > (this->mmap_base + this->mmap_len) )
l = (this->mmap_base + this->mmap_len) - this->mmap_curr;
@@ -142,7 +171,7 @@ static buf_element_t *file_plugin_read_block (input_plugin_t *this_gen, fifo_buf
buf->type = BUF_DEMUX_BLOCK;
#ifdef HAVE_MMAP
- if ( this->mmap_on ) {
+ if ( check_mmap_file(this) ) {
off_t len = todo;
if ( (this->mmap_curr + len) > (this->mmap_base + this->mmap_len) )
@@ -193,7 +222,7 @@ static off_t file_plugin_seek (input_plugin_t *this_gen, off_t offset, int origi
file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
#ifdef HAVE_MMAP /* Simulate f*() library calls */
- if ( this->mmap_on ) {
+ if ( check_mmap_file(this) ) {
void *new_point = this->mmap_curr;
switch(origin) {
case SEEK_SET: new_point = this->mmap_base + offset; break;
@@ -223,7 +252,7 @@ static off_t file_plugin_get_current_pos (input_plugin_t *this_gen){
return 0;
#ifdef HAVE_MMAP
- if ( this->mmap_on )
+ if ( check_mmap_file(this) )
return (this->mmap_curr - this->mmap_base);
#endif
@@ -239,7 +268,7 @@ static off_t file_plugin_get_length (input_plugin_t *this_gen) {
return 0;
#ifdef HAVE_MMAP
- if ( this->mmap_on )
+ if ( check_mmap_file(this) )
return this->mmap_len;
#endif
@@ -253,7 +282,7 @@ static off_t file_plugin_get_length (input_plugin_t *this_gen) {
static uint32_t file_plugin_get_blocksize (input_plugin_t *this_gen) {
file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
#if 0 && defined(HAVE_MMAP)
- if ( this->mmap_on )
+ if ( check_mmap_file(this) )
return this->mmap_len;
#endif
return 0;
@@ -286,7 +315,11 @@ static void file_plugin_dispose (input_plugin_t *this_gen ) {
file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
#ifdef HAVE_MMAP
- if ( this->mmap_on )
+ /* Check for mmap_base rather than mmap_on because the file might have
+ * started as a mmap() and now might be changed to descriptor-based
+ * access
+ */
+ if ( this->mmap_base )
munmap(this->mmap_base, this->mmap_len);
#endif
@@ -395,7 +428,7 @@ static int file_plugin_open (input_plugin_t *this_gen ) {
}
#ifdef HAVE_MMAP
- if ( (this->mmap_base = mmap(NULL, sbuf.st_size, PROT_READ, MAP_SHARED, this->fh, 0)) != -1 ) {
+ if ( (this->mmap_base = mmap(NULL, sbuf.st_size, PROT_READ, MAP_SHARED, this->fh, 0)) != (void*)-1 ) {
this->mmap_on = 1;
this->mmap_curr = this->mmap_base;
this->mmap_len = sbuf.st_size;