diff --git a/libisofs/fsource.c b/libisofs/fsource.c index 5d95ee0..da3f5da 100644 --- a/libisofs/fsource.c +++ b/libisofs/fsource.c @@ -135,11 +135,12 @@ int iso_file_source_get_aa_string(IsoFileSource *src, } -/* Determine whether src is random-access readable and return its capacity. - @flag bit0= Open and close src +/* @flag bit0= Open and close src + bit1= Try iso_file_source_lseek(, 0) (=SEEK_SET) with wanted_size @return <0 iso_file_source_lseek failed , >= 0 readable capacity */ -off_t iso_file_source_lseek_capacity(IsoFileSource *src, int flag) +off_t iso_file_source_lseek_capacity(IsoFileSource *src, off_t wanted_size, + int flag) { int ret, opened = 0; off_t end, old, reset; @@ -173,7 +174,11 @@ off_t iso_file_source_lseek_capacity(IsoFileSource *src, int flag) end = -1; goto ex; } - end = iso_file_source_lseek(src, 0, 2); + if(flag & 2) { + end = iso_file_source_lseek(src, wanted_size, 0); + } else { + end = iso_file_source_lseek(src, 0, 2); + } if (end < 0) { end = -1; goto ex; @@ -190,3 +195,43 @@ ex:; return end; } + +/* Determine whether src is random-access readable and return its capacity. + @flag bit0= For iso_file_source_lseek_capacity(): Open and close src + bit1= wanted_size is valid +*/ +off_t iso_file_source_determine_capacity(IsoFileSource *src, off_t wanted_size, + int flag) +{ + int ret; + off_t src_size, src_seek_size= -1; + struct stat info; + + ret = iso_file_source_stat(src, &info); + if (ret < 0) { + return (off_t) -1; + } + if (S_ISREG(info.st_mode)) { + return info.st_size; + } + src_size = iso_file_source_lseek_capacity(src, wanted_size, (flag & 1)); + if (src_size > 0) { + return src_size; + } + if (!(flag & 2)) { + if (src_size == 0) { + return 0; + } + return -1; + } + src_seek_size= src_size; + + src_size = iso_file_source_lseek_capacity(src, wanted_size, + 2 | (flag & 1)); + if (src_size >= 0) { + return src_size; + } else if (src_seek_size >= 0) { + return src_seek_size; + } + return -1; +} diff --git a/libisofs/fsource.h b/libisofs/fsource.h index 56781f5..ece7ae7 100644 --- a/libisofs/fsource.h +++ b/libisofs/fsource.h @@ -49,10 +49,14 @@ int iso_ifs_source_clone(IsoFileSource *old_source, IsoFileSource **new_source, int flag); +off_t iso_file_source_lseek_capacity(IsoFileSource *src, off_t wanted_size, + int flag); + /* Determine whether src is random-access readable and return its capacity. - @return -1 iso_file_source_lseek failed , >= 0 readable capacity */ -off_t iso_file_source_lseek_capacity(IsoFileSource *src, int flag); +off_t iso_file_source_determine_capacity(IsoFileSource *src, off_t wanted_size, + int flag); + #endif /*LIBISO_FSOURCE_H_*/ diff --git a/libisofs/stream.c b/libisofs/stream.c index ae3a9a2..9f56b3c 100644 --- a/libisofs/stream.c +++ b/libisofs/stream.c @@ -353,7 +353,8 @@ int cut_out_open(IsoStream *stream) src_size= info.st_size; } else { /* Determine src_size and lseekability of device */ - src_size = iso_file_source_lseek_capacity(src, 0); + src_size = iso_file_source_determine_capacity(src, + data->offset + data->size, 2); if (src_size <= 0) return ISO_WRONG_ARG_VALUE; } @@ -535,7 +536,7 @@ int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size, src_size = info.st_size; } else { /* Open src, do iso_source_lseek(SEEK_END), close src */ - src_size = iso_file_source_lseek_capacity(src, 1); + src_size = iso_file_source_determine_capacity(src, offset + size, 3); if (src_size <= 0) return ISO_WRONG_ARG_VALUE; } diff --git a/libisofs/tree.c b/libisofs/tree.c index 91953b2..fe8434a 100644 --- a/libisofs/tree.c +++ b/libisofs/tree.c @@ -720,8 +720,7 @@ int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent, if (S_ISREG(info.st_mode)) { src_size = info.st_size; } else { - /* Open src, do iso_source_lseek(SEEK_END), close src */ - src_size = iso_file_source_lseek_capacity(src, 1); + src_size = iso_file_source_determine_capacity(src, offset + size, 3); if (src_size <= 0) return ISO_WRONG_ARG_VALUE; }