Unix Programming - Casting structure pointers

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > February 2004 > Casting structure pointers





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Casting structure pointers
Xavier Noria

2004-02-19, 1:34 am

I have read in books about networking in Unix that pointers to struct
sockaddr and struct sockaddr_in can be casted one to another. This
involves assumptions about alignment and basic type sizes that are not
guaranteed by the C standard.

Why those casts work in Unix?

-- fxn
Villy Kruse

2004-02-19, 2:34 am

On 19 Feb 2004 07:09:43 -0800,
Xavier Noria <fxn@hashref.com> wrote:


>I have read in books about networking in Unix that pointers to struct
>sockaddr and struct sockaddr_in can be casted one to another. This
>involves assumptions about alignment and basic type sizes that are not
>guaranteed by the C standard.
>
>Why those casts work in Unix?
>



That works because sockaddr and sockaddr_in structures are defined
that way. Remember you can pass other sockaddr types to the bind() call
such as sockaddr_un for defining local socket addresses (aka unix socket)
or sockaddr_ipx for defining IPX socket addresses.

Villy
Xavier Noria

2004-02-19, 11:33 pm

vek@station02.ohout.pharmapartners.nl (Villy Kruse) wrote in message news:<slrnc39lk3.abg.vek@station02.ohout.pharmapartners.nl>...
> On 19 Feb 2004 07:09:43 -0800,
> Xavier Noria <fxn@hashref.com> wrote:
>
> That works because sockaddr and sockaddr_in structures are defined
> that way.


Are defined which way?

The underlying problem is that given this code:

struct foo { char c[2]; };
struct bar { char c0; char c1; };

struct foo f;
struct bar b, *bp;

f.c[1] = 'a';
bp = (struct bar*) &f;

you just don't know whether bp->c1 holds 'a' in ANSI C. So we are
relying on something that happens "in Unix", whatever that means,
albeit it is not guaranteed by the standard.

I guess that might be some well-known assumption that holds "in Unix"
because even Steven's book does not mention that issue. My question
is: what are we relying on?

-- fxn
David Schwartz

2004-02-19, 11:33 pm


"Xavier Noria" <fxn@hashref.com> wrote in message
news:31a13074.0402200426.477e8797@posting.google.com...


> vek@station02.ohout.pharmapartners.nl (Villy Kruse) wrote in message
> news:<slrnc39lk3.abg.vek@station02.ohout.pharmapartners.nl>...




[color=blue]
>
> Are defined which way?



Are defined so that one is a more specific form of the other.


> The underlying problem is that given this code:
>
> struct foo { char c[2]; };
> struct bar { char c0; char c1; };
>
> struct foo f;
> struct bar b, *bp;
>
> f.c[1] = 'a';
> bp = (struct bar*) &f;
>
> you just don't know whether bp->c1 holds 'a' in ANSI C.


Right.

> So we are
> relying on something that happens "in Unix", whatever that means,
> albeit it is not guaranteed by the standard.



It is guaranteed by POSIX.


> I guess that might be some well-known assumption that holds "in Unix"
> because even Steven's book does not mention that issue. My question
> is: what are we relying on?



We are relying upon the guarantees provided by the POSIX 1003.1 and
SuSv3 standards. Here are some excerpts from SuSv3 (Single Unix
Specification, Version 3) that articulate parts of this requirement:

When a sockaddr_storage structure is cast as a sockaddr structure, the
ss_family field of the sockaddr_storage structure shall map onto the
sa_family field of the sockaddr structure. When a sockaddr_storage structure
is cast as a protocol-specific address structure, the ss_family field shall
map onto a field of that structure that is of type sa_family_t and that
identifies the protocol's address family.

The sockaddr_storage structure defined in <sys/socket.h> shall be large
enough to accommodate a sockaddr_in structure (see the <netinet/in.h> header
defined in the Base Definitions volume of IEEE Std 1003.1-2001, Chapter 13,
Headers) and shall be aligned at an appropriate boundary so that pointers to
it can be cast as pointers to sockaddr_in structures and used to access the
fields of those structures without alignment problems. When a
sockaddr_storage structure is cast as a sockaddr_in structure, the ss_family
field maps onto the sin_family field.

The sockaddr_in structure is used to store addresses for the Internet
address family. Values of this type shall be cast by applications to struct
sockaddr for use with socket functions.

DS



Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com