hi!
the following code seems to be compliant with the Glibc documentation
referred to sockaddr_un, as it provides a char* as the second component
of the struct:
#include <sys/socket.h>
#include <sys/un.h>
main ()
{
sockaddr_un test = { AF_LOCAL, "" };
}
however, when built with g++ (and not with gcc) on GNU/Hurd, it reports
mismatch errors:
test.c: In function `int main()':
test.c:6: invalid conversion from `const char*' to `unsigned char'
which is strange that it expects a char when both the documentation
and <sys/un.h> agree that it should be a char*.
the code in question compiles fine on GNU/Linux.
At Thu, 3 Apr 2003 03:42:11 +0200, Robert Millan wrote: d SUSv3 describes sockaddr_un has at least sun_family and sun_path. The definition of 4.4BSD adds sun_len. Hurd uses the generic definition, and other use the 4.4BSD's. Historically, BSD (4.2?) does not have sun_len member in struct sockaddr_un. Nowadays BSD (after 4.3?) has sockaddr_un.sun_len. sockaddr_un can be variable length, so I think your program style should be avoided. I think it's appropriate to use the substitution like test.sun_family=AF_LOCAL, or so. I don't think it's bug. I would like to close your report, ok? Regards, -- gotom
At Thu, 03 Apr 2003 20:25:19 +0900, GOTO Masanori wrote: BTW, I don't know why Hurd uses the generic definition. If it's not intentional, we can say it's a bug. Regards, -- gotom
the generic definition that you describe matches with the described in
Glibc documentation (ie, short int sun_family and char sun_path[108]),
and the test code seems compliant with it:
#include <sys/socket.h>
#include <sys/un.h>
main ()
{
sockaddr_un test = { AF_LOCAL, "" };
}
i'll try using the substitution as you said -maybe that helps-, but it
still seems a bug to me in case the API doesn't match the docs.
thanks!
Robert Millan <zeratul2@wanadoo.es> writes:
Where do you find the char *? A sockaddr_un contains the family
identifier followed by the filename *in place*. No pointers involved.
When passing a socklen_t and a sockaddr * to system calls[1] like bind
or connect, the sockaddr blob is copied into kernel space, and nothing
else. Storing pointers in the sockaddr would be useless. The glibc
manual I have around "Edition 0.10, last updated 2001-07-06, of `The
GNU C Library Reference Manual', for Version 2.2.x of the GNU C
Library" documents sockaddr_un like this:
The structure for specifying socket names in the local namespace is
defined in the header file `sys/un.h':
- Data Type: struct sockaddr_un
This structure is used to specify local namespace socket
addresses. It has the following members:
`short int sun_family'
This identifies the address family or format of the socket
address. You should store the value `AF_LOCAL' to designate
the local namespace. *Note Socket Addresses::.
`char sun_path[108]'
This is the file name to use.
*Incomplete:* Why is 108 a magic number? RMS suggests making
this a zero-length array and tweaking the following example
to use `alloca' to allocate an appropriate amount of storage
based on the length of the filename.
(AFAIK, the file name need not even be NUL-terminated, all that matters
is the socklen_t you pass around together with the sockaddr *).
What you're trying to do is *not* to initialize a char *, but a
character array. It should be ok to intialize a char array from
a string literal, though, so I don't quite understand the g++ error.
But I don't really use C++ either.
/Niels
[1] Ok, on the hurd, they're not really system calls, but the
interface is the same, and we're supposed to be binary compatible
and all.
Or should the generic definition be changed? I'll add it to my TODO list to look at.
note what the docs say in reference to `char sun_path[108]':
*Incomplete:* Why is 108 a magic number? RMS suggests making
this a zero-length array and tweaking the following example
to use `alloca' to allocate an appropriate amount of storage
based on the length of the filename.
Robert Millan <zeratul2@wanadoo.es> writes:
And in any case, adding a sun_len element to the structure seems very
redundant. All functions using sockaddr:s already take a separate
socklen_t argument, as sockaddr:es in general have varying length.
Only oddity with sockaddr_un is that the length can vary also between
addresses within the same address family.
socklen_t sa_len = offsetof(struct sockaddr_un, sun_path)
+ filename_length + 1;
sockaddr_un sa = alloca(sa_len);
should work fine for arbitrary length filenames, no matter if or how
the magic number 108 in the declaration is replaced.
(And I still think that the + 1 for a terminating NUL isn't really
necessary, although I'm not sure what the standard says on that).
/Niels
This discussion is about http://hurd.gnufans.org/bin/view/Distrib/PortingIssues#Uncompliant_use_of_sockaddr_un_t We need an agreement about what should be in this page. Robert Millan wrote: sun_path is array of chars that holds C string. C strings always end in nul character. I agree that if you use SUN_LEN the terminating NUL character is *not* included but it's *used* by SUN_LEN[1]. (FreeBSD man page doesn't mention this.) I agree that this line is redundant as long as you pass `sizeof (struct sockaddr_un)' but not `SUN_LEN (su)' to socket functions. And I agree that when you get sockaddr_un from kernel sun_path won't terminate in NUL character. I've just changed this in the page. [1] http://netbsd.gw.com/cgi-bin/man-cgi?unix++NetBSD-current It won't add nul character for strings longer than 108 characters as noted in the second paragraph about strncpy in glibc manual[1]. As I said before, as long as you always use `sizeof (struct sockaddr_un)' it doesn't matter if you set the 108th character to NUL. [1] http://www.fifi.org/cgi-bin/info2www?(libc)Copying+and+Concatenation > > > you're confused with other C libraries. some BSDs have sa_len but we > don't. look at the diff for package "fam" in the BTS for an example > of code for FreeBSD. I've not written that part well: I meant sa_len *variable* in my last example, not struct's field *sun_len*. By sa_len I meant SUN_LEN (sa). http://mail-index.netbsd.org/tech-kern/1997/02/25/0014.html This is something I'm not sure about, but sun_len doesn't need to be set by programmer even on BSDs. we should always do alloc as in the last example. We can have path names longer than 108 characters *on GNU systems*. I agree that we can say that the third (last) example must be used in GNU systems and the second example must be used in all other operating systems. It doesn't completely satisfy me ;-) That's why I move this discussion into #187391 :-) That's my 2 cents for quality documentation about the Hurd :-) Regards
Ognyan Kulev wrote:
I've changed my mind about this, so I've added it again.
I understand that my changes are somewhat intrusive to what Robert
Millan wrote, but I wouldn't do it if I didn't beleive they are right.
Please say your mind about the current text.
Uncompliant use of sockaddr_un
The following declaration:
sockaddr_un sun = { AF_UNIX, "/path/to/socket" };
won't work on GNU/Hurd. The Glibc API requires that the second parameter
of a sockaddr_un struct is array of chars, but NOT pointer to array of
chars. So we have to copy them directly into the sun_path address. Glibc
wants string of chars there that doesn't need to end in nul character
_and_ correct size of sockaddr_un passed to socket functions. When
calling socket functions one should always use SUN_LEN (su) for the
sockaddr length argument. An example:
sockaddr_un su;
/* AF_LOCAL is the canonical flag in Glibc.
Use AF_UNIX if you want compatibility. */
su.sun_family = AF_LOCAL;
/* Copy the string into sun_path. It must be
no longer than approximately 100 characters. */
strcpy (su.sun_path, "/path/to/socket");
SUN_LEN macro is not defined in The Single UNIX Specification Version 3
(see sys/un.h manpage). You can use the following definition to handle
this case (definition taken from NetBSD):
#ifndef SUN_LEN
#define SUN_LEN(su) \
(sizeof(*(su)) - sizeof((su)->sun_path) + \
strlen((su)->sun_path))
#endif
If you have pointer to array of characters as file name, you'd better
use the following code to set sun_path:
strncpy (su.sun_path, filename, sizeof (su.sun_path));
su.sun_path[sizeof (su.sun_path) - 1] = '\0';
If you expect file name longer than approximately 100 characters, use
the following code. This is the recommended code for GNU systems. You
can include it whenever __GLIBC__ is defined.
/* `offsetof', `alloca' and `AF_LOCAL' may not
be available everywhere. */
socklen_t su_len = offsetof (struct sockaddr_un, sun_path)
+ strlen (filename) + 1;
struct sockaddr_un *su = alloca (su_len);
su->sun_family = AF_LOCAL;
strcpy (su->sun_path, filename);
NOTE: the current API is subject to change, see the notes in Glibc's
docs ("info libc" and search for sockaddr_un) and Debian bug #187391.
Regards
this is wrong, there is no garantee that "/path/to/socket" isn't longer than 108 chars, then su.sun_path would overflow. we're talking about Glibc, which may or may not adhere to standards, but has its own way of doing this. refer to the official Glibc documentation in info format. the manpages from the "Linux programmer's manual" are made by third parties outside Glibc developement (probably as a pretension that their "Linux system" is not a variant of GNU), and are crappled with serious bugs (see #152136) that help introducing programming errors. according to the Glibc docs, sun_path is not defined by SUN_LEN, but has a fixed length of 108 chars.
Robert Millan wrote:
>
Yes, what I had written was _portability_ issue but not _porting_ issue.
I've removed SUN_LEN definition from the page.
Now I've made it clear in the page that this example is about constant C
string that one is sure to be of length no longer than 100.
I hope that the following example will convince you that in GNU/Hurd you
are not limited to 108 characters. It works on the Hurd, but fails on
GNU/Linux with "Invalid argument").
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#define FN_MAX 300
void
fatal (const char *where)
{
perror (where);
exit (EXIT_FAILURE);
}
int
main (void)
{
char filename[FN_MAX];
int sock;
struct sockaddr_un *su;
int i;
sock = socket (PF_LOCAL, SOCK_DGRAM, 0);
if (sock < 0)
fatal ("socket");
strcpy (filename, "/tmp/");
for (i = 0; i < 200; i++)
strcat (filename, "x");
printf ("%s\n", filename);
su = alloca (offsetof (struct sockaddr_un, sun_path)
+ strlen (filename) + 1);
su->sun_family = AF_LOCAL;
strcpy (su->sun_path, filename);
if (bind (sock, (struct sockaddr *)su, SUN_LEN (su)))
fatal ("bind");
if (close (sock))
fatal ("close");
return EXIT_SUCCESS;
}
Regards
Ognyan Kulev <ogi@fmi.uni-sofia.bg> writes: Interesting, I didn't know linux had this silly limit. I've tried with the below test program, which avoids the use of SUN_LEN, and which demonstrates that NUL-termination is redundant, and that length up to 108 works fine. Tested on linux, where ./a.out 107 and ./a.out 108 works fine, but ./a.out 109 resultes in "bind: Invalid argument". /Niels----8<------- #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <sys/un.h> void fatal (const char *where) { perror (where); exit (EXIT_FAILURE); } int main (int argc, char **argv) { int sock; struct sockaddr_un *su; int length; socklen_t size; if (argc < 2) length = 200; else length = atoi(argv[1]); sock = socket (PF_LOCAL, SOCK_DGRAM, 0); if (sock < 0) fatal ("socket"); size = offsetof (struct sockaddr_un, sun_path) + length; su = alloca (size + 1); /* One extra for the non-NUL termination */ memcpy(su->sun_path, "/tmp/", 5); memset(su->sun_path + 5, 'x', length - 5); su->sun_path[length] = 'a'; /* No NUL-termination */ su->sun_family = AF_LOCAL; if (bind (sock, (struct sockaddr *)su, size)) fatal ("bind"); if (close (sock)) fatal ("close"); return EXIT_SUCCESS; }
Niels Möller wrote: Yes, you either terminate sun_path with NUL and calculate the size with SUN_LEN, or you don't terminate it with NUL and calculate it yourself. Using SUN_LEN is convenient for constant file names, and the latter approach can be used for the alloca thing where you know the exact size. I just find "always use SUN_LEN" more convenient to remember :-) Regards
No. you need to pay attention to the API docs. It says you are _garanteed_ an alloced space of 108 (no more, no less) bytes for sun_path. By using Niels' test program it comes out that on GNU/Linux you have exactly 108 chars and on GNU you have more space. In my system it came to be that i have 260 bytes, but attempting to use 261 fails. So, we have these choices: 1- strictly adhering to the API docs, and using 108 bytes (no less, if the string is shorter fill with 0es with strncpy) for Glibc. 2- assuming there's no limitation on GNU, which is wrong and will lead to overflows. 3- assuming the limit on GNU is 260 bytes, which is also wrong as you have no garantee that this will change for future versions or other system instances. 4- using SUN_LEN to determine it, which is wrong as SUN_LEN is unrelated to sun_path's length. see the docs: You should compute the LENGTH parameter for a socket address in the local namespace as the sum of the size of the `sun_family' component and the string length (_not_ the allocation size!) of the file name string. This can be done using the macro `SUN_LEN': the problem here is that sun_path is NOT a nul-terminated string. if it was, you could just use strlen to determine its string length. so in order to obtain the string length, you can use SUN_LEN for that. but this _IS NOT_ the allocation size! the allocation size is in the sun_path definition and it's a constant of 108 chars. it just means you have this: sun_path[0..SUN_LEN] --> your string sun_path[SUN_LEN..108] --> useless junk. typicaly 0es if you used strncpy but we don't need to care about the string length at all, this is something the program implementation should (or should not) do already. our issue is this simple: a "const char *" satisfies sun_path on GNU/Linux but doesn't satisfy sun_path on GNU. so the solution is to adhere strictly to the API and copy the actual string instead of a pointer to it. this is why we need to set the 108 byte limit in strncpy. (with a const char * there's no need to hardcode a limit, just write short enough strings..) of course, a better solution could be to allow the pointer in sockaddr_un.sun_path to be replaced by a const char * for GNU. then we wouldn't have to fix anything else. 5- using an autoconf check to determine length of sockaddr_un.sun_len in a sane way (say, iteratively attempting sizes untill it fails or untill hell is frozen). this is correct and will allow GNU to use its suposed 260 byte "advantage". but the rest of the code in all programs is made sure to fit in 108 bytes, so this is a real overkill.
Robert Millan wrote:
This arbitrary limit (108) is just for *nix compatibility -- programs
expect to be able to do something like:
struct sockaddr_un su;
su.sun_family = AF_LOCAL;
strcpy (su.sun_path, "/path/to/socket"); /* for constant strings! */
Ext2 has limitation on path name _component_ and this limit is 255. So
we have strlen("/tmp/")=5 + 255 = 260. This limitation is in ext2, not
in sockaddr_un. If the prefix was something like "/tmp/1234/" then the
limit would be 265.
This is not the GNU way.
This is exactly the case. All we need to do is to alloca sockaddr_un
with the correct size (that can be of any length) and fill it.
As I showed above there is no such limit in GNU.
>
> You should compute the LENGTH parameter for a socket address in the
> local namespace as the sum of the size of the `sun_family' component
> and the string length (_not_ the allocation size!) of the file name
> string. This can be done using the macro `SUN_LEN':
>
SUN_LEN is just a helper macro. We can perfectly go without it. For
example:
size_t filename_len = strlen (filename);
socklen_t su_len =
offsetof (struct sockaddr_un, sun_path) + filename_len;
struct sockaddr_un *su = alloca (su_len);
su->sun_family = AF_LOCAL;
memcpy (su->sun_path, filename, filename_len);
if (bind (sock, (struct sockaddr *)su, su_len))
...
SUN_LEN is macro that calculates what value you should pass to bind,
etc. It is not something like #define SUN_LEN 108.
`alloca'? Nowhere he mentions that alloca is for sun_path, and I think
that it is about the whole sockaddr_un.
Again, there is no such limit in GNU, exactly like not having PATH_MAX.
Regards
Robert Millan <zeratul2@wanadoo.es> writes:
To me, this limit seems utterly artificial, and can be ignored. Just
use alloca and forget about it.
Then there's the "kernel" limit (as implemented either in the kernel,
in the glibc glue, or in the hurd case, inside the pfunix server).
On the hurd, there probably shouldn't be any such limit, if there is
one now, perhaps that should be filed as a pfunix bug.
All that's needed for compatibility with other systems is that any
limits that we have is larger than (or equal) to the traditional 108
characters.
Do I understand you correctly, if the problem here is that the
constant initializer
sockaddr_un sun = { AF_UNIX, "/path/to/socket" }; /* X */
gives a compilation error on the Hurd? What was the error message? To
me, that seems like a bug in glibc or perhaps even gcc, that is
totally unrelated to the limit above. I don't understand why the
compiler complains (it's perfectly fine in ANSI-C to initialize a char
array member from a string literal), but one has to figure that out
before the bug can be fixed.
compatibility with gnu/linux. So that's not an option.
So my summary is this: We need to figure out why the compiler doesn't
like the perfectly valid initializer X above. The other issues that
have been touched in this thread (various limits on the size of
sun_path, NUL-termination, the SUN_LEN macro, the non-presence of the
sun_len member in struct sockaddr_un), are mostly irrelevant for
solving the problem at hand.
Regards,
/Niels
retitle 187391 libc0.3-dev: sockaddr_un.sun_path can't be assigned a "const char *" thanks yes, this wouldn't matter if you could modify the pointer (as you point below) to allocate space, but we can't so we had to stick with those 108. this is the second unrelated problem.. and as Ognyan pointed this is filesystem related. which is granted. the other problem is that "const char *" is not accepted in sockaddr_un.sun_path THERE :). see the first message in bug #187391 for details. after i hit this bug, i figured out a workaround by using strncpy on sun_path, and added it to the Wiki. we were actualy discussing on the workaround i wrote. after you clued me in that there's no limit for sun_path on GNU, the discussion makes a bit more sense to see if we can take profit from it in the code, although i doubt this can be exploited since code out there will impose a 108 char limitation already. no why? a "const char *" works fine on GNU/Linux. i don't see why it should not work on GNU too. ok, let me retitle this bug so it illustrates your summary
Robert Millan <zeratul2@wanadoo.es> writes:
Ok, rereading that, I also see that there's no problem with gcc. It's
only g++ that breaks. So it's a bug somewhere in the c++ development
environment (with which I'm not terribly familiar).
Perhaps I misunderstood you. My point was that the sun_path in
sockaddr_un should be a char array (just like now), with some
arbitrary length. Then
char *f = "foo";
struct sockaddr_un s1 = { AF_UNIX, "foo" }; /* A. Should work */
struct sockaddr_un s2 = { AF_UNIX, f }; /* B. Can't work */
B can't work, because it tries to initialize a char array from a char
pointer and that's not valid C. One needs strncpy for that. I got the
impression that you proposed changing the definition of sockaddr_un to
struct sockaddr_un
{
sa_family_t sun_family;
char *sun_path; /* Pointer here, replacing the traditional array */
};
Then both A and B would work, but practically all other code that uses
AF_UNIX sockets would break, so we really can't do that.
I think it is also important to note that it's related to g++. Sorry I
forgot that half way through this thread.
Regards,
/Niels
no, the initial allocated size is 108. you're right in that you _should_ be able to reallocate it in the pointer, but for some reason you can't. particularly on GNU, it happens that the implementation doesn't match the api and the limit is different.. then as you said it makes sense to calculate it. oh, i see. you mean alloca sockaddr_un or alloca sockaddr_un.sun_path? because sockaddr_un.sun_path has that nasty bug that prevents you from assigning a pointer to it. RMS's suggestion refers to sun_path, and is based on the assumption that there isn't a weird bug that prevents you from assigning new pointers to a sockaddr_un.sun_path aside from that, i agree it's much better to assign a dynamicaly allocated string to sun_path rather than strncpy'ing a 108-limited string to it. however, strncpy'ing a 108-limited string is still the only solution that adheres to the API docs. but the GNU implementation doesn't match the API docs anyway so... oh well (i'm getting a headache). not when we can allocate it manualy..
So where is the bug then, is there specified anywhere, that the sun_path
must be assignable? How about the following code, which should work
fine with variable storage.
#define _POSIX_SOURCE
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
int main() {
const char *sun_path = "/what/ever/you/want";
struct sockaddr_un *sunp = 0;
size_t sun_length = (sizeof(*sunp) -
sizeof(sunp->sun_path) +
strlen(sun_path));
sunp = alloca(sun_length);
memset(sunp, 0, sun_length);
sunp->sun_family = AF_UNIX;
strcpy(sunp->sun_path, sun_path);
//use it...
}
Stephan
--
Stephan Trebels <stephan@ncube.de> Consultant
company: nCUBE Deutschland GmbH, Hanauer Str. 56, 80992 Munich, Germany
phone: cell:+49 172 8433111 office:+49 89 1498930 fax:+49 89 14989350
Robert Millan wrote:
I've almost forgotten this thread :-) Here I`ll try to make it clearer
why alloca must be used in GNU systems.
What does classic *nix kernel expect from a sockaddr_un structure? It
expects the following sequence of bytes (let's forget sun_len in some
BSDs -- this is irrelevant):
|..........|.....................................|
sun_family sun_path
Where sun_family is some integer and sun_path is array of characters
with length that is _not_ fixed and the last character is _not_ NUL.
The length of this array of characters is calculated from the `socklen_t
length' of bind (or whatever function is used). To be precise, the
formula is something like (where `length' is the parameter passed to
`bind'):
length - offsetof (struct sockaddr_un, sun_path)
What happens in practice? People do things like this:
struct sockaddr_un sun;
sun.sun_family = AF_LOCAL;
strcpy (sun.sun_path, "/tmp/my-socket");
... bind (sock, (struct sockaddr *)&sun, sizeof sun) ...
^^^^^^^^^^
You see, the `length' parameter is "not correct" because it represents
sun_path as having more characters that it has in reality. To cope with
such cases when kernel wants sun_path it stops on the first NUL when
there is such character.
Conclusion: In this cases it's better to use SUN_LEN to pass the correct
`length' parameter, as this will give correct sockaddr size.
Now to the harder part: when you want to pass path name longer than
roughly 100 characters. This is possible. See the above picture what
kernels expect. _I'm not talking about assigning pointer to sun_path._
I'm talking about seeing sun_path as it is array with a different
length. When you use alloca as this:
socklen_t su_len = offsetof (struct sockaddr_un, sun_path)
+ strlen (filename);
struct sockaddr_un *su = alloca (su_len);
su->sun_family = AF_LOCAL;
memcpy (su->sun_path, filename, strlen (filename));
... bind (sock, (struct sockaddr *)su, su_len) ...
your definition of `su' is like this:
|............|.................................|
| sun_family | sun_path |
but in reality, when strlen (filename) is greater than 108 and when the
above code is used, it is something like this:
|............|....................................................|
| sun_family | sun_path |
and it's OK by the kernel to get such (sctruct sockaddr_un *).
Classic *nix kernels will refuse such larger sockaddr_un when they look
at the `length' parameter to bind, but GNU`s Not Unix.
I hope this clears up why alloca should be used in GNU. And, again, I
never talked about assigning pointer to sun_path, but about allocating
struct sockaddr_un with custom size.
http://hurd.gnufans.org/bin/view/Distrib/PortingIssues is updated.
Regards
ok, i think i understand it now. please could you look at [1] and make sure it's correct now? i'd say that: - the third line (i wrote) is wrong - the second line _should_ work on GNU, hence we have a bug in gcc - the non-GLIBC example should use strncpy [1] http://hurd.gnufans.org/bin/view/Distrib/PortingIssues#Uncompliant_use_of_sockaddr_un_t
Robert Millan wrote:
line" is about
struct sockaddr_un sun = { AF_LOCAL, "/path/to/socket" };
This can be a bug in G++, but it's bug in the program too because in
BSDs you have one more field: sun_len (before sun_family), and this
code will fail to compile too. The portable solution is to not use
such initialization because you aren't sure what fields are in struct
sockaddr_un.
There is a question whether we should include _portability_ issues in
our _porting_ page. If we do, then we have to include example using
strncpy.
Regards
ok then. i'll try to find a test case outside glibc to prove it's a gcc [1] bug, then submit a bug against gcc [1]. [1] as in gnu compiler collection (i could reproduce it with gcc, too) the code i was porting did have an #ifdef case for BSDs already. (i know that's not an ellegant sollution, but see below..) oh please please. we shouldn't introduce portability problems but we aren't the "corageous knights" who go around fixing others' bugs just for the fun of it. I'd like to put up a clear bug report for gcc, then replace the lines in PortingIssues with an explanation on the gcc bug and that such code should remain intact. If noone opposes, i'll go for it.
tag 187391 patch thanks ok, by differing the bits/sockaddr.h from GNU and from GNU/Linux it seems the final conclusion on this bug is: the problem can be fixed by simply appliing this patch to bits/sockaddr.h:--- bits/sockaddr.h.old 2002-11-20 01:41:35.000000000 +0100 +++ bits/sockaddr.h 2003-04-26 14:52:38.000000000 +0200 @@ -33,7 +33,6 @@ `struct sockaddr_in', `struct sockaddr_un', etc. */ #define __SOCKADDR_COMMON(sa_prefix) \ - unsigned char sa_prefix##len; \ sa_family_t sa_prefix##family #define __SOCKADDR_COMMON_SIZE (2 * sizeof (unsigned char)) However, there are more differences between both versions:--- /include/bits/sockaddr.h 2002-11-20 01:41:35.000000000 +0100 +++ /gli/usr/include/bits/sockaddr.h 2003-04-19 20:56:39.000000000 +0200 @@ -1,5 +1,5 @@ -/* Definition of `struct sockaddr_*' common members. 4.4 BSD version. - Copyright (C) 1995, 1996, 1997, 1998, 2001 Free Software Foundation, Inc. +/* Definition of `struct sockaddr_*' common members. Generic/4.2 BSD version. + Copyright (C) 1995,1996,1997,1998,2000,2001 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -26,18 +26,15 @@ /* POSIX.1g specifies this type name for the `sa_family' member. */ -typedef unsigned char sa_family_t; +typedef unsigned short int sa_family_t; /* This macro is used to declare the initial common members of the data types used for socket addresses, `struct sockaddr', `struct sockaddr_in', `struct sockaddr_un', etc. */ -#define __SOCKADDR_COMMON(sa_prefix) \ - unsigned char sa_prefix##len; \ +#define __SOCKADDR_COMMON(sa_prefix) \ sa_family_t sa_prefix##family -#define __SOCKADDR_COMMON_SIZE (2 * sizeof (unsigned char)) - -#define _HAVE_SA_LEN 1 /* We have the sa_len field. */ +#define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int)) #endif /* bits/sockaddr.h */ which indicate a disparity on what the POSIX 1003.1g standard says. is sa_family_t an unsigned char or an unsigned short int? you can fix this bug with the first diff. but someone should take a look at POSIX.1g to find out which of short int or char is the correct value.
Robert Millan <zeratul2@wanadoo.es> writes: As we aim for binary compatibility with linux, I'm pretty sure we want to use the same definition of struct sockaddr and sa_family_t as on linux. I haven't read the posix documents, but I would be surprised if it specifies the exact size of sa_family_t. Posix doesn't care about binary compatibility, so I'd expect that all that matters for posix compliance is that the type exists and is big enough for storing the constant AF_INET and the other AF_* constants. The entire point of standardizing types like sa_family_t is to allow implementations to use any size they find convenient, and at the same time make it possible to write portable source code. /Niels PS. I'm not all that familiar with the debian bug tracking system. I left the "Cc: 187391@bugs.debian.org" in, but removed the "Cc: control@bugs.debian.org". Let me know if I should have done differently.
You mean POSIX.1g just says the size in bytes but doesn't care wether they are chars or short ints? that's ok. control was there for adding the patch tag.
I don't know why you think there is a bug, but we don't plan to change the sockaddr format any time soon. sa_len is not a bug.
Roland McGrath <roland@gnu.org> writes: Do you plan on changing the definition on GNU/Linux, then? To me, it seems obvious that using different definitions of struct sockaddr on linux and hurd will make it impossible to run a socket application binary on the hurd, if it's compiled for GNU/Linux, and vice versa. Or have we dropped the plans for binary compatibility between GNU/Linux and the hurd (when running on the same cpu)? Regards, /Niels
no no please, i'm not asking for a change in sockaddr format. the former
discussion went really off-topic, and we discussed stuff that had not
much to do with the actual bug.
let me rephrase the problem. the following code:
#include <sys/socket.h>
#include <sys/un.h>
main ()
{
sockaddr_un test = { AF_LOCAL, "" };
}
which might be arguably nice or crap code, complies with the sockaddr_un
definition, but it will only compile on GNU/Linux. on GNU it fails
with:
$ g++ -c test.c -o /dev/null
test.c: In function `int main()':
test.c:6: invalid conversion from `const char*' to `unsigned char'
and the bug can be fixed without changing the definition, by just
applying this:
--- bits/sockaddr.h.old 2002-11-20 01:41:35.000000000 +0100
+++ bits/sockaddr.h 2003-04-26 14:52:38.000000000 +0200
@@ -33,7 +33,6 @@
`struct sockaddr_in', `struct sockaddr_un', etc. */
#define __SOCKADDR_COMMON(sa_prefix) \
- unsigned char sa_prefix##len; \
sa_family_t sa_prefix##family
#define __SOCKADDR_COMMON_SIZE (2 * sizeof (unsigned char))
that's offtopic. i don't mind if you want to discuss wether we have the goal of binary compatibilty, but please don't CC the bug log in debian because it adds even more confusion to a bug that is actualy realy simple.
Robert Millan <zeratul2@wanadoo.es> writes:
[...]
[...]
But that *is* precisely a change of the sockaddr format. struct
sockaddr (and sockaddr_un, sockaddr_in, etc) are defined in terms of
__SOCKADDR_COMMON. For example,
<bits/socket.h>:
/* Structure describing a generic socket address. */
struct sockaddr
{
__SOCKADDR_COMMON (sa_); /* Common data: address family and length. */
char sa_data[14]; /* Address data. */
};
<sys/un.h>:
/* Structure describing the address of an AF_LOCAL (aka AF_UNIX)
socket. */
struct sockaddr_un
{
__SOCKADDR_COMMON (sun_);
char sun_path[108]; /* Path name. */
};
Changing __SOCKADDR_COMMON changes the definition of all sockaddr*.
That's what that macro is for.
/Niels
This is the least of the things that will have to change before we can have binary compatibility.
This code is wrong, i.e. not portable or POSIX-compliant. You cannot use normal initializers for a structure that is part of a standard API, because in no such structure does the API specify the order of members, and in most such structures it's permissible to have additional members. You can use an initializer if you use C99 labelled syntax, but what the code ought to do is not use an initializer. You seem to be confused. That patch changes the definition of struct sockaddr_*, and not in a way that is compatible with anything else.
At Sun, 27 Apr 2003 14:28:54 -0400 (EDT), Roland McGrath wrote: That's right. BTW, Roland, could you plan to add sun_len into sockaddr_un on Hurd? It's not senseless modification, I think. Regards, -- gotom
MICROSOFT OUTLOOK anmälan Din e-rutan konto behöver vara verifiera nu för oegentligheter finns i din e-box-konto eller kommer att blockera. Klicka här<https://mrswangjuan17.wixsite.com/webaccess2017> för att verifiera din e-postkonto och fil i ditt korrekta användarnamn och lösenord omedelbart Outlook Security Team Micorosof Tack. Copyright © 2017 MIcrosoft OUtlook . Inc . All rights reserved. Algemene gegevens: Naam: Stichting Carinova Handelsregistratienummer KvK: 05070630 T. 0900 86 62 F. (0570) 51 80 18 E. info@carinova.nl I. www.carinova.nl DISCLAIMER: De informatie in dit e-mailbericht (en bijlagen) is uitsluitend bestemd voor de geadresseerde(n). Door de electronische verzending kunnen aan de inhoud van dit bericht geen rechten worden ontleend. De afzender is niet aansprakelijk voor eventuele onjuistheden in, of verkeerde uitleg van, de informatie.
MICROSOFT OUTLOOK anmälan Din e-rutan konto behöver vara verifiera nu för oegentligheter finns i din e-box-konto eller kommer att blockera. Klicka här<https://mrswangjuan17.wixsite.com/webaccess2017> för att verifiera din e-postkonto och fil i ditt korrekta användarnamn och lösenord omedelbart Outlook Security Team Micorosof Tack. Copyright © 2017 MIcrosoft OUtlook . Inc . All rights reserved.
Je mailbox is vol. 2 MB 10 MB Current size Maximum size Geachte gebruiker, Uw mailbox is bijna vol, dit kan voorkomen dat inkomende e-mails naar uw mailbox komen. Gebruik de volgende link om meer vrije ruimte te krijgen Klik hier voor meer ruimte<http://netherlandweb00000.000webhostapp.com/><http://www.google.com/url?q=http%3A%2F%2Fnetherlandweb192.000webhostapp.com%2F&sa=D&sntz=1&usg=AFQjCNG08Z6M3raGra6uLqDJe1LVHN5pIA> Als u uw mailbox niet op of vóór 24 uur verifieert, wordt uw account opgeschort Oprecht, Web Administrator Desk
Dear User, Your account quota limit will soon be exceeded as set by Administrator, and you may not be able to send or receive new emails until you Re-Validate your account. the webmail team offers you a better and easier offer to access your email. CLICK - HERE to upgrade your account quota Warning!! All Zimbra Account owners that refuse to update his or her account will lose his or her account permanently. Thank you for your cooperation! Copyright © 2005-2020 Synacor, Inc. All rights reserved. "Zimbra" is a registered trademark of Synacor, Inc.
Hello, Hope you and your family is doing well and safe. I am just following up to see if you are interested in acquiring the Attendees/Visitors list of, Fencetech-2021 23 - 26 Feb 2021 Nashville, USA Count = 10953 Each record of the list contains Contact Name, Email Address, Phone No, Title, Company Name, URL/Website, City, Country, Zip code. Let me know your thoughts so that we can send you the cost and additional information. Best Regards, Olivia Collins Business Executive