Re: Socket header file

Andrew Pollard (andrew@odie.demon.co.uk)
Thu, 19 Dec 1996 17:15:29 GMT


Alan Modra writes:

> >Richard Gooch <rgooch@atnf.CSIRO.AU>
> >
> > Alan Modra writes:
> > >
> > > >root@analogic.com (Richard B. Johnson)
> > > > /usr/include/linux/socket.h: unsigned char cmsg_data[0];
> > > > This should probably be:
> > > > unsigned char *cmsg_data;
> > >
> > > No, definitely not. It's correct as it is. The structure is
> > > dynamically allocated with cmsg_data[] a variable length array.
> >
> > I have complained to Linus about this a few times before, with no
> > response. The problem with the above construct is that you cannot
> > compile with gcc -Wall -pedantic-errors
>
> Glad to see that you like to have your code portable. Linus may
> accept a fix rather than just a complaint. No, come to think of it,
> the person you should talk to is Alan Cox, since he's the network code
> maintainer.
>
> One fix would be to zap cmsg_data[0] from struct cmsghdr, change the
> CMSG_DATA define to
> #define CMSG_DATA(cmsg) ((unsigned char *)(cmsg) + sizeof(struct cmsghdr))
> and fix kernel code referencing cmsg_data. In fact, the CMSG_DATA
> macro should be used in the kernel anyway. Shouldn't take more than
> 10 minutes :-)

I've been having this problem as well. Here is implementation of
suggested fix for 2.0.27 (NB. there was a redundant '&' used in af_unix.c)

diff -r -u v2.0.27/include/linux/un.h linux/include/linux/un.h
--- v2.0.27/include/linux/un.h Thu Dec 19 16:30:07 1996
+++ linux/include/linux/un.h Thu Dec 19 16:55:19 1996
@@ -12,7 +12,9 @@
unsigned int cmsg_len;
int cmsg_level;
int cmsg_type;
- unsigned char cmsg_data[0];
+/* unsigned char cmsg_data[0]; */
};
+
+#define CMSG_DATA(cmsg) ((unsigned char *)(cmsg)+sizeof(struct cmsghdr))

#endif /* _LINUX_UN_H */
diff -r -u v2.0.27/net/unix/af_unix.c linux/net/unix/af_unix.c
--- v2.0.27/net/unix/af_unix.c Thu Dec 19 16:31:06 1996
+++ linux/net/unix/af_unix.c Thu Dec 19 16:43:20 1996
@@ -709,7 +709,7 @@
{
int num=cmsg->cmsg_len-sizeof(struct cmsghdr);
int i;
- int *fdp=(int *)cmsg->cmsg_data;
+ int *fdp=(int *)CMSG_DATA(cmsg);

num /= sizeof(int); /* Odd bytes are forgotten in BSD not errored */
if (num >= UNIX_MAX_FD)
@@ -775,7 +775,7 @@
if (cmsg)
{
cmnum = (cmsg->cmsg_len-sizeof(struct cmsghdr)) / sizeof(int);
- cmfptr = (int *)&cmsg->cmsg_data;
+ cmfptr = (int *)CMSG_DATA(cmsg);
}

fdnum = *(int *)skb->h.filp;

Andrew.
=============================================================================
| Andrew Pollard, Integral Solutions Ltd UK.| Work: andrewp@isl.co.uk |
| Tel:+44(0)1256 55899 Fax:+44(0)1256 63467 | Home: andrew@odie.demon.co.uk |
=============================================================================