#include #include #include #include #include #include extern const char *__progname; static int fd; static char sbuf[512]; static unsigned long long int min; static unsigned long long int max; static int readable(unsigned long long int o) { int rrv; #ifdef LB_SET static int lb_set_works = -1; if (o > 0x003fffff) { if (lb_set_works < 0) { lb_set_works = (lseek(fd,o,LB_SET) >= 0); } if (lb_set_works) { lseek(fd,o,LB_SET); } else { lseek(fd,o*(off_t)512,L_SET); } } else #endif { lseek(fd,o*(off_t)512,L_SET); } rrv = read(fd,sbuf,512); if (rrv < 0) { printf("%llu: %s\n",o,strerror(errno)); return(0); } else if (rrv == 0) { printf("%llu: EOF\n",o); return(0); } else if (rrv != 512) { printf("%llu: read %d\n",o,rrv); return(0); } else { printf("%llu: ok\n",o); return(1); } } int main(int, char **); int main(int ac, char **av) { if (ac < 2) { fprintf(stderr,"Usage: %s \n",__progname); exit(1); } fd = open(av[1],O_RDONLY|O_NDELAY,0); if (fd < 0) { perror(av[1]); exit(1); } min = 0; max = 1; while (readable(max)) { min = max; max *= 2; if (max == 0) { fprintf(stderr,"%s: no end found\n",__progname); exit(1); } } while (max-min > 1) { unsigned long long int m; m = min + ((max-min)/2); /* (min+max)/2 may overflow! */ if (readable(m)) { min = m; } else { max = m; } } printf("%llu\n",max); exit(0); }