On Thu, Jul 7, 2011 at 5:43 AM, Bastiaan Timmer
<address@hidden> wrote:
Hi! I've been writing a CD ripping utility under linux using libcdio. At first, I only allowed ripping whole discs, but I have just added functionality to rip separate tracks as well. When testing this new option I found that seeking to a frame (using 'cdio_paranoia_seek(cdrom_paranoia_t *, off_t, int)') would always fail, and fail silently. It took me quite a while to figure out what the problem was.
As it turns out, libcdio on my system (I just installed it from Fedora's software repository) is compiled with large file support, which sets the _FILE_OFFSET_BITS symbol to 64.
On a 32-bit notebook running Ubuntu, my _FILE_OFFSET_BITS are set to 64 as well.
This causes the off_t type in the library (which is used in cdio_paranoia_seek) to be 8 bytes. On 32-bit systems, like mine, an off_t is usually only 4 bytes.
There is something mysterious here because the typeset for off_t does not come from libcdio but rather from from the system. On Ubuntu it seems it comes from <sys/types.h>. So the fact that there is garbage in the upper 4 bytes on 32-bit systems feels to me like a design flaw.
When calling the function from my code, it was called with a 4 byte off_t and a 4 byte int as 2nd and 3rd arguments. The library however, would take both the off_t and the int as the 8 byte off_t it expects, and use some garbage value for the last int. Some very small example code showing this exact problem can be found here: http://forums.fedoraforum.org/showpost.php?s=405e58a90456014247766335d0d26a2a&p=1490685&postcount=1
Now, currently I am simply compiling my program with -D_FILE_OFFSET_BITS=64 to force a 64 bit off_t in my program as well, which fixes the problem. But if I were to distribute my program, how would users know how to compile? If I simply set _FILE_OFFSET_BITS=64 then they will get similar problems if their distributions package maintainers happen to have compiled libcdio without large file support. Does the library have any way of letting users know how large it thinks an off_t is?
There now is. When libcdio installs it installs ... include/cdio/cdio_config.h and that has values that were set from its config.h. Previously I had installed a truncated version of config.h. I just made a change in git to store the entire config.h.
But I have a little trepidation with this change, so it is an experiment and may change. The C preprocessor symbols are from a global namespace. That is the names there are not prefaced with say CDIO_. _FILE_OFFSET_BITS in particular is such a global namespace variable. So this means you may need to be careful with the order of includes because some other include may set _FILE_OFFSET_BITS and, at least on Ubuntu, <sys/types.h> uses the value of the #define.
That is why previously I tried to limit how much of config.h got copied.
Also, if a program would need to link to several different 3rd party libraries, some requiring _FILE_OFFSET_BITS to be set to 32 and others to 64, even letting users know how it was compiled will not help. Perhaps the best thing to do is to leave _FILE_OFFSET_BITS at the system default value (32 bit on x86, 64 on x86_64), and do what fseek/fseek64 and lseek/lseek64 do. That is, if the system has 32 bit architecture and large file support is enabled, then make a function 'cdio_paranoia_seek64(cdrom_paranoia_t *, off64_t, int)' available (see also the manpage of lseek64).
By the way, is the cdio_paranoia_seek function ever used for things other than audio CD's?
It should only be audio CDs.
Because if not, why would it ever need a 64 bit file offset type anyway, neither in frames nor even in bytes will a 32 bit value be to small to address a CD, right?
Right. I'll put on the list of things to do to change cdio_paranoia_seek to use an int32_t rather than an off_t.
Thanks,
Bas Timmer
_______________________________________________
Libcdio-help mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/libcdio-help