diff options
author | Ron Economos <w6rz@comcast.net> | 2019-03-29 17:05:02 -0700 |
---|---|---|
committer | Andrej Rode <mail@andrejro.de> | 2019-03-31 23:32:05 +0200 |
commit | 980d0a881f9309ef43881634ef1b1a6143b03ed7 (patch) | |
tree | 6b9c3228307889059b38add6af758ff7cb6dc708 /gr-blocks/lib/file_source_impl.cc | |
parent | 24a40b03237530679bca7270efc4c064bb8f2577 (diff) |
blocks: Modify File Source block to work with named pipes and devices.
The block uses fseek and ftell, which don't apply to named pipes
and character/block devices.
Diffstat (limited to 'gr-blocks/lib/file_source_impl.cc')
-rw-r--r-- | gr-blocks/lib/file_source_impl.cc | 98 |
1 files changed, 65 insertions, 33 deletions
diff --git a/gr-blocks/lib/file_source_impl.cc b/gr-blocks/lib/file_source_impl.cc index 3f7b844e03..18bbc73be3 100644 --- a/gr-blocks/lib/file_source_impl.cc +++ b/gr-blocks/lib/file_source_impl.cc @@ -37,9 +37,13 @@ #ifdef _MSC_VER #define GR_FSEEK _fseeki64 #define GR_FTELL _ftelli64 +#define GR_FSTAT _fstat +#define GR_FILENO _fileno #else #define GR_FSEEK fseeko #define GR_FTELL ftello +#define GR_FSTAT fstat +#define GR_FILENO fileno #endif namespace gr { @@ -81,28 +85,34 @@ namespace gr { bool file_source_impl::seek(int64_t seek_point, int whence) { - seek_point += d_start_offset_items; - - switch(whence) { - case SEEK_SET: - break; - case SEEK_CUR: - seek_point += (d_length_items - d_items_remaining); - break; - case SEEK_END: - seek_point = d_length_items - seek_point; - break; - default: - GR_LOG_WARN(d_logger, "bad seek mode"); - return 0; - } + if (d_seekable) { + seek_point += d_start_offset_items; + + switch(whence) { + case SEEK_SET: + break; + case SEEK_CUR: + seek_point += (d_length_items - d_items_remaining); + break; + case SEEK_END: + seek_point = d_length_items - seek_point; + break; + default: + GR_LOG_WARN(d_logger, "bad seek mode"); + return 0; + } - if ((seek_point < (int64_t)d_start_offset_items) - || (seek_point > (int64_t)(d_start_offset_items+d_length_items-1))) { - GR_LOG_WARN(d_logger, "bad seek point"); + if ((seek_point < (int64_t)d_start_offset_items) + || (seek_point > (int64_t)(d_start_offset_items+d_length_items-1))) { + GR_LOG_WARN(d_logger, "bad seek point"); + return 0; + } + return GR_FSEEK((FILE*)d_fp, seek_point * d_itemsize, SEEK_SET) == 0; + } + else { + GR_LOG_WARN(d_logger, "file not seekable"); return 0; } - return GR_FSEEK((FILE*)d_fp, seek_point * d_itemsize, SEEK_SET) == 0; } @@ -123,20 +133,40 @@ namespace gr { throw std::runtime_error("can't open file"); } - //Check to ensure the file will be consumed according to item size - GR_FSEEK(d_new_fp, 0, SEEK_END); - uint64_t file_size = GR_FTELL(d_new_fp); + struct stat st; - // Make sure there will be at least one item available - if ((file_size / d_itemsize) < (start_offset_items+1)) { - if (start_offset_items) { - GR_LOG_WARN(d_logger, "file is too small for start offset"); - } - else { - GR_LOG_WARN(d_logger, "file is too small"); + if(GR_FSTAT(GR_FILENO(d_new_fp), &st)) { + GR_LOG_ERROR(d_logger, boost::format("%s: %s") % filename % strerror(errno)); + throw std::runtime_error("can't fstat file"); + } + if(S_ISREG(st.st_mode)) { + d_seekable = true; + } + else { + d_seekable = false; + } + + uint64_t file_size; + + if (d_seekable) { + //Check to ensure the file will be consumed according to item size + GR_FSEEK(d_new_fp, 0, SEEK_END); + file_size = GR_FTELL(d_new_fp); + + // Make sure there will be at least one item available + if ((file_size / d_itemsize) < (start_offset_items+1)) { + if (start_offset_items) { + GR_LOG_WARN(d_logger, "file is too small for start offset"); + } + else { + GR_LOG_WARN(d_logger, "file is too small"); + } + fclose(d_new_fp); + throw std::runtime_error("file is too small"); } - fclose(d_new_fp); - throw std::runtime_error("file is too small"); + } + else { + file_size = INT64_MAX; } uint64_t items_available = (file_size / d_itemsize - start_offset_items); @@ -156,7 +186,9 @@ namespace gr { } // Rewind to start offset - GR_FSEEK(d_new_fp, start_offset_items * d_itemsize, SEEK_SET); + if (d_seekable) { + GR_FSEEK(d_new_fp, start_offset_items * d_itemsize, SEEK_SET); + } d_updated = true; d_repeat = repeat; @@ -241,7 +273,7 @@ namespace gr { if (d_items_remaining == 0) { // Repeat: rewind and request tag - if (d_repeat) { + if (d_repeat && d_seekable) { GR_FSEEK(d_fp, d_start_offset_items * d_itemsize, SEEK_SET); d_items_remaining = d_length_items; if (d_add_begin_tag != pmt::PMT_NIL) { |