} else if ( RANGE( sscanf( range, "%d:%n", &a, &c ), 1 )) {
p->from = ( a < 0 )? ( p->to + a ) : a;
} else if ( RANGE( sscanf( range, "%d%n", &a, &c ), 1 )) {
- if ( a < 0 ) {
- p->from = p->to + a;
+ if ( a >= 0 ) {
+ p->from = a;
} else {
- p->to = p->from + a;
+ p->from = p->to + a;
}
} else if ( RANGE( sscanf( range, ":%n", &c), 0 ) ) {
// to end from start
return 1;
}
}
- if ( p->from >= p->to ||
- p->from >= filestat.st_size || p->to > filestat.st_size ) {
+ if ( ( filestat.st_mode & S_IFMT ) == S_IFCHR ) {
+ filestat.st_size = p->to; // Pretend size of character device
+ }
+ if ( p->from < 0 ) {
+ p->from = 0;
+ }
+ if ( p->to > filestat.st_size ) {
+ p->to = filestat.st_size;
+ }
+ if ( p->from >= p->to || p->from >= filestat.st_size ) {
fprintf( stderr, "** BAD RANGE: %s [%ld:%ld]\n",
argv[i], p->from, p->to );
return 1;
if ( offset >= sources.size ) {
return -1;
}
+#if DEBUG
+ fprintf( stderr, "find_source( %ld )\n", offset );
+#endif
while ( lo + 1 < hi ) {
int m = ( lo + hi ) / 2;
if ( offset < sources.array[ m ].start ) {
+#if DEBUG
+ fprintf( stderr, " offset < [%d].start: %ld\n",
+ m, sources.array[ m ].start );
+#endif
hi = m;
} else {
+#if DEBUG
+ fprintf( stderr, " offset >= [%d].start: %ld\n",
+ m, sources.array[ m ].start );
+#endif
lo = m;
}
}
+#if DEBUG
+ fprintf( stderr, "found %d\n", lo );
+#endif
return lo;
}
#if DEBUG
fprintf( stderr, "read %ld %ld\n", off, size );
#endif
- size_t rr = 0;
+ size_t rr = 0; // total reading
while ( size > 0 ) {
#if DEBUG
- fprintf( stderr, "find_source %ld %ld\n", off, size );
+ fprintf( stderr, " find_source %ld %ld\n", off, size );
#endif
int i = find_source( off );
if ( i < 0 ) {
if ( n > size ) {
n = size;
}
+#if DEBUG
+ fprintf( stderr, " seek fd=%d to %ld\n", sources.array[i].fd, b );
+#endif
if ( lseek( sources.array[i].fd, b, SEEK_SET ) < 0 ) {
perror( sources.array[i].filename );
return -ENOENT;
}
#if DEBUG
- fprintf( stderr, "get %ld bytes at %ld\n", n, rr );
+ fprintf( stderr, " now read %ld from fd=%d\n",
+ n, sources.array[i].fd );
#endif
ssize_t r = read( sources.array[i].fd, buf + rr, n );
#if DEBUG
- fprintf( stderr, "got %ld bytes\n", r );
+ fprintf( stderr, " got %ld bytes\n", r );
#endif
if ( r < 0 ) {
perror( sources.array[i].filename );
off += r;
size -= r;
}
+#if DEBUG
+ fprintf( stderr, " total reading %ld bytes\n", rr );
+#endif
return rr;
}
static void usage() {
char *usage =
"Usage: fusefile [ <fuse options> ] <mount> <file/from-to> ... \n"
-"Mounts a virtual, read-only file that is a concatenation of file fragments\n"
+"Mounts a virtual, file that is a concatenation of file fragments\n"
;
fprintf( stderr, "%s", usage );
exit( 1 );
times.ctime = stbuf.st_ctime;
}
+ {
+ int fd = open( mnt, O_RDWR, S_IRUSR | S_IWUSR );
+ if ( fd < 0 ) {
+ perror( mnt );
+ return 1;
+ }
+ if ( lseek( fd, sources.size, SEEK_SET ) < 0 ) {
+ return -EIO;
+ }
+ }
fuseargc = setup_argv( fuseargc, &argv );
struct fuse_args args = FUSE_ARGS_INIT( fuseargc, argv );
if ( fuse_parse_cmdline( &args, &mnt, &mt, &fg ) ) {