Many moons ago, trying to determine the size of a CD in a cdrom drive was a pain, and the "binary search for last location we can actually read" was the only reliable way to determine the length of the image I could find.
But I'm not sure that's still relevant? That hardware's mostly gone away. DVD drives are still around, but require a ritual sacrifice in order to read the actual image data with that whole decss nonsense to <strike>remove the style sheet</strike> unscramble the contents, and while burning your own DVD for backup CLAIMS to have a half life of 5 years mine were more like 3, which ain't great for data retention, which was a widely known problem at least a decade ago ala https://www.rlvision.com/blog/how-long-do-writable-cddvd-last-400-discs-put-to-the-test/ so people just bought USB hard drives and stuck them in a safe deposit box if they cared... Ahem. Anyway: Doing stat() to find a length, the "get block device size" ioctl, and finally lseek(SEEK_END) is _probably good enough? I can still fall back to the binary search but I'm not sure how SEEK_END is going to return failure and yet SEEK_SET still work in that binary search case? (The CD didn't even spin up the drive for the checks that didn't actually try to read data, because spinning up the drive was expensive so they disabled it and stubbed out the return values. This was related to the scsi layer throwing all the devices into a big pile and giving it a stir so /dev/sd? devices never enumerated in a known order the way IDE had because if the IBM zseries was going to have a serious device enumeration problem then all those IBM Linux developers Sam Palmisano was spending $1 billion/year on from 2001-2005 were going to inflict that problem on the Linux on the Desktop crowd until there were no more people trying to use Linux on the Desktop. And thus was systemd forged in the fires of Mt Doom, and short of hiring Peter Dinklage to throw a recording of the song "bananaphone" into Kilauea nobody has a plan to make it go away again. Where was I?) The other thing is that fdlength() currently returns 0 when it can't find the length, and off_t is signed* and 0 is a valid length so it SHOULD return -1 (with an xfdlength exiting), but I need to audit the callers: load_policy: xmmap(0) will barf, eh, close enough? ftpget: storing the return value in unsigned long long. Can't check. hexedit: checking <1 for bad length, should be fine. mkswap: no check, int underflow for 0 length file (unsigned pages = 0-1) so it would write a corrupted header... to a zero length file you couldn't mount anyway? modinfo: storing into a signed 32 bit int. Not that people are going to load a single module larger than 2 gigabytes but still... Then feeds length to xmmap() which would die on <0. shred: stores in off_t (signed long), checks for <1 truncate: stores in a signed variable, no check, negative length in ftruncate() would be EINVAL. mkdev, mke2fs, modprobe, vi are all in pending. Rob * glibc defines off_t as __off_t which is __OFF_T_TYPE which is __SYSCALL_SLONG_TYPE which is __SLONGWORD_TYPE which is long int. The <strike>aristocrats</strike> FSF! _______________________________________________ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net