How to shoot others in the foot

ethan on 2004-03-13T08:56:02

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.


Post

djberg96 on 2004-03-13T13:19:05

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. :)

Re:Post

jhorwitz on 2004-03-13T14:38:46

FWIW, it hasn't changed as of the latest "solaris express" release of 10.

i sent email

hfb on 2004-03-13T18:30:53

to Alan Burlison...he said he logged it as a bug.

Re:i sent email

ethan on 2004-03-13T19:22:24

Long live Alan!

I didn't know that it is so easy to get something filed as a bug for Solaris. It's good to know that the Perl community has a genuine SUN chap in Alan Burliston.

Re:i sent email

hfb on 2004-03-13T19:30:52

Well...he is one of the lead kernel engineers for Solaris 10 afterall :)

Re:i sent email

ethan on 2004-03-13T22:43:13

That I didn't know. So maybe and after all Solaris can be trusted more than I would want to acknowledge. :-)

You called?

Alan Burlison on 2004-03-13T20:03:41

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]);

Re:You called?

Alan Burlison on 2004-03-13T20:37:33

If it isn't obvious from the above, buffer is the SCSI reply buffer, and the code is common to both x86 & sparc.

Re:You called?

ethan on 2004-03-13T22:38:45

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!

Re:You called?

ethan on 2004-03-13T22:49:16

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).