Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

ethan (3163)

ethan
  reversethis-{ed. ... rap.nov.olissat}

Being a 25-year old chap living in the western-most town of Germany. Stuying communication and information science and being a huge fan of XS-related things.

Journal of ethan (3163)

Saturday March 13, 2004
03:56 AM

How to shoot others in the foot

[ #17894 ]

Let's regard this little piece of imbecility as found in Solaris' sys/cdio.h:


struct cdrom_tocentry {
        unsigned char cdte_track;
        unsigned cdte_adr :4;
        unsigned cdte_ctrl :4;
        unsigned char cdte_format;
        union {
                struct {
                        unsigned char minute;
                        unsigned char second;
                        unsigned char frame;
                } msf;
                int lba;
        } cdte_addr;
        unsigned char cdte_datamode;
};

It can be seen that they inlined the cdte_addr slot. In Linux for instance there is a distinct type union cdrom_addr. Now suppose we have defined a type like this that works for Linux:


typedef struct CDROM_ADDR {
        union cdrom_addr addr;
        int type;
} CDROM_ADDR;

Naturally, for Solaris this has to become:


typedef struct CDROM_ADDR {
        union {
        struct {
                unsigned char minute;
                unsigned char second;
                unsigned char frame;
        } msf;
        int lba;
        } addr;
        int type;
} CDROM_ADDR;

What makes the Solaris approach so stupid is that I can no longer write:

        struct cdrom_tocentry entry;
        CDROM_ADDR addr; ...
        addr.addr = entry.cdte_addr;

Any compiler will complain that there are incompatible types in the assignment although the two types match perfectly.

So why weren't the Solaris people able to define a distinct type for the address union? Instead they used the inlined type three times in their header which makes assigning the address impossible. For me as a programmer this means that I either need yet another #if SOLARIS branch or I always write:


        addr.addr.lba = entry.cdte_addr.lba;

Working with Solaris will at some point put tear in your eyes.

As a related note - and because I have no physical access to a Solaris machine - I yet need to find out whether Solaris stores LBA addresses in their native big-endian format or whether they rather use host-byteorder. BSDs use big-endian for some reason, Linux uses little-endian (regardless of the processor's native byteorder). I predict that there nowhere any information about that can be found.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • Post this to comp.unix.solaris or send an email directly to Sun. Solaris 10 final isn't out yet - maybe it can be fixed by then. :)
  • to Alan Burlison...he said he logged it as a bug.
  • FYI, I've logged a bug - although no promises as to when it might be fixed.

    As far as LBA byte ordering goes, this from the CDROM driver:

    entry->cdte_addr.lba = ((uchar_t)buffer[8] << 24) + ((uchar_t)buffer[9] << 16) + ((uchar_t)buffer[10] << 8) + ((uchar_t)buffer[11]);
    • If it isn't obvious from the above, buffer is the SCSI reply buffer, and the code is common to both x86 & sparc.
      • If it isn't obvious from the above, buffer is the SCSI reply buffer, and the code is common to both x86 & sparc.

        That means I don't have to worry about byteorder. I just use the machine's native format which is good.

        I became suspicious when I learnt that the BSDs deliberately use network byteorder so on x86 I need to swap the bytes when reading the address or passing it as an ioctl parameter. It's a pleasant surprise that this time Solaris does not require any special treatment. :-) Thanks, Alan!
    • FYI, I've logged a bug - although no promises as to when it might be fixed.

      Almost forget to mention: I'm happy this has been put on the (undoubtedly voluminous) to-do list. Naturally, this wont immediately solve all my problems. It's the same with Solaris as it is with Perl: after a bug has been fixed in a new release, you have to wait a few years until you can start relying on the fixed behaviour. Propagation happens slowly (consider how many perl5.005_03s or even older are still used in production).