TIP: Click on subject to list as thread! ANSI
echo: c_echo
to: Jasen Betts
from: Bo Simonsen
date: 2004-01-22 15:50:10
subject: Re: Big endian machines

Hi Jasen,

-=> Jasen Betts wrote to Bo Simonsen <=-

 BS>> I'm looking into this issue because it looks like
 BS>> that SquishMail has
 BS>> problems my reading a packed (__attribute__(packed)) structure from
 BS>> diskfile written on a little endian machine.

 PS>> No guesses please, show us the structure definition. :)

 BS> It would be no-sence to show you the whole structure, so here's just a
 BS> bit
 BS> of it:

 BS> struct _pkthdr
 BS> {
 BS>   sword orig_node;        /* originating node */
 BS>   sword dest_node;        /* destination node */
 BS> }  __attribute__((packed, aligned(2)));

 JB> OK, a fidonet .PKT file, there are little endian (opposite of network
 JB> byte order)

Yes it _should_ be. :)

 JB> the easiest fix it to use do byte-swap operation on the words
 JB> after/before reading/writing them.

Yes, but I guess there is still no problem in reading a aligned 
structure (see the post from Pascal regarding this subject).

 JB>  &define  fido_swab(x)   (x=x<<8 & 0xff00 |
x>>8 & 0xff )

I'm not supposed to understand this right? ;-)

 BS> read(fp, &pkthdr, sizeof(struct _pkthdr));

 JB>  fido_swab(pkthdr.orig_node)
 JB>  fido_swab(pkthdr.dest_node)

 JB> and before you write them do fido_swab on them again....

Yes I see.

 JB> The trick for portable code is to get fido_swab to do nothing when
 JB> htons does something and vice versa. on little-endian hardware
 JB> fido_swab should be defined blank.

Yes I see.

 JB>  #define fido_swab

 JB> probably it's a good idea to test it at runtime, or as part of the make
 JB> process.

 JB>   {
 JB>   short int x=0
 JB>   ((char*)x)[0]=1;
 JB>   fido_swab[x]

       fido_swab(x) ?

 JB>   if(x != 1) { fpriintf(stderr "fido_swab mis-defined in source";
 JB>                exit(1);
 JB>              }
 JB>   }

 JB> This isn't a truly general solution as it won;'t work on macines that
 JB> don't use two's complement numbers but those are practiacally unheard
 JB> of these days,

It might be more portable to use the swap thing, because htonl (and 
brothers) might not exist in some OS'es like Solaris(?).

 JB> the other fix is to re-write it to use all bytes.

 BS> struct _pkthdr
 BS> {
 BS>   uchar orig_node_minor,orig_node_major;     /* originating node */
 BS>   uchar dest_node_minor,dest_node_major;     /* destination node */
 BS> }  __attribute__((packed, aligned(1)));

 JB> byt then you may need to do more edits to your code so that it can get
 JB> the node number

 JB> eg:

 JB>  unsigned short orig_node = (pkt.orig_node_major << 8 & 0xff00)
 JB>                            +(pkt.orig_node_minor      & 0x00FF)

Seems like a complicated one, I mean I shouldn't do swapping on a single 
byte?

 BS> Should I read every single variable in the structure to get it working?

 JB> no, you either need to address each byte separately or convert the
 JB> multi-byte values from file-format to host-format, and back to file
 JB> format before writing

Yes I understand now.

Bo


... 2 + 2 = 5 for extremely large values of 2.
___ MultiMail/Linux v0.46

--- Maximus/UNIX 3.03b
* Origin: The Night Express - Roennede, Dk (2:236/100)
SEEN-BY: 633/267 270
@PATH: 236/100 237/9 20/11 106/1 2000 633/267

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.