public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Alejandro Colomar <alx.manpages@gmail.com>
To: Rich Felker <dalias@libc.org>
Cc: linux-man@vger.kernel.org, "Alejandro Colomar" <alx@kernel.org>,
	GCC <gcc@gcc.gnu.org>, glibc <libc-alpha@sourceware.org>,
	"Bastien Roucariès" <rouca@debian.org>,
	"Stefan Puiu" <stefan.puiu@gmail.com>,
	"Igor Sysoev" <igor@sysoev.ru>,
	"Andrew Clayton" <a.clayton@nginx.com>,
	"Richard Biener" <richard.guenther@gmail.com>,
	"Zack Weinberg" <zack@owlfolio.org>,
	"Florian Weimer" <fweimer@redhat.com>,
	"Joseph Myers" <joseph@codesourcery.com>,
	"Jakub Jelinek" <jakub@redhat.com>,
	"Eric Blake" <eblake@redhat.com>
Subject: Re: [PATCH] sockaddr.3type: BUGS: Document that libc should be fixed using a union
Date: Mon, 6 Feb 2023 00:59:48 +0100	[thread overview]
Message-ID: <29bb163d-ab7b-2fb7-a1c8-cfd720984a8d@gmail.com> (raw)
In-Reply-To: <20230205234359.GF3298@brightrain.aerifal.cx>


[-- Attachment #1.1: Type: text/plain, Size: 3869 bytes --]

Hi Rich,

On 2/6/23 00:43, Rich Felker wrote:
> On Sun, Feb 05, 2023 at 04:28:36PM +0100, Alejandro Colomar wrote:
>> As discussed before, and Bastien and I seem to agree, ideally we should
>> define the following types:
>>
>>      struct sockaddr_storage {
>>          union {
>>              struct {
>>                  sa_family_t      ss_family;
>>              };
>>              struct sockaddr_in   sin;
>>              struct sockaddr_in6  sin6;
>>              struct sockaddr_un   sun;
>>              // ...
>>          };
>>      };
> 
> AFAIK this is not permitted because of namespace. sys/socket.h is not
> permitted to expose sockaddr_{in,in6,un}. And if you defined
> differently-tagged structures with the same contents, it would not do
> any good; accessing the members with the wrong-tagged struct type
> would still be UB.

I'm not sure.  ISO C has that restriction that a header can only define what the 
standard says it defines.  However, does POSIX have the same restriction? 
Doesn't POSIX allow including any other POSIX headers (maybe it does, but IIRC 
it doesn't)?  Since <sys/socket.h> is just a POSIX thing, that's the only 
standard we should care about.

> 
> Really, there is no action needed here. Nothing is wrong on libc's
> side. The problem is just that the type is *not useful for anything*
> and should not be used except in the context of sizeof, which is
> purely a documentation issue.
> 
>>      struct [[deprecated]] sockaddr {
>>          sa_family_t              sa_family;
>>      };
>>
>>      union [[gnu::transparent_union]] sockaddr_ptr {
>>          struct sockaddr_storage  *ss;
>>          struct sockaddr          *sa;
>>      };
>>
>> And then we could define APIs like:
>>
>>      int bind(int sockfd, const union sockaddr_ptr *addr, socklen_t len);
> 
> You cannot just change APIs because you wish they were different.

This API is compatible.  In fact, it already is now like that:

alx@debian:/usr/include$ grepc bind
./x86_64-linux-gnu/sys/socket.h:112:
extern int bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)
      __THROW;

alx@debian:/usr/include$ sed -n 83,84p x86_64-linux-gnu/sys/socket.h
typedef union { __SOCKADDR_ALLTYPES
	      } __CONST_SOCKADDR_ARG __attribute__ ((__transparent_union__));


> Ideally bind, etc. would just take void *,

void * is a bit too much unsafe.  GCC's transparent unions are a restricted 
catch-many pointer, rather than a catch-all.

> which is what the struct
> sockaddr * is being used as.

And in fact, void* wouldn't sole the union problem.

> But they don't, so callers have to cast.

With the current glibc implementation, you don't need to cast, thanks to the 
[[gnu::transparent_union]]:


alx@debian:~/tmp$ cat sock.c
#define _GNU_SOURCE
#include <sys/socket.h>
#include <sys/un.h>

int
bind_un(int sfd, const struct sockaddr_un *addr, socklen_t len)
{
	return bind(sfd, addr, len);
}
alx@debian:~/tmp$ cc -Wall -Wextra sock.c -S
alx@debian:~/tmp$ clang -Wall -Wextra sock.c -S
alx@debian:~/tmp$


> It's ugly but it's really not a big deal. Much less of a big deal than
> breaking the interface because you think it would look prettier if it
> had been done differently.

It's not breaking the interface; not in GNU C.  Current code still falls back to 
the a POSIX-complying UB-invoking interface when you don't ask for _GNU_SOURCE, 
but we can keep that.  I'm only asking that we fix the GNU C version.  Moreover, 
in POSIX-complying code, you can keep the interface pointer, since you'll need 
to cast anyway, but can still make sockaddr_storage be implemented through an 
anonymous union.

Cheers,

Alex

> 
> Rich

-- 
<http://www.alejandro-colomar.es/>
GPG key fingerprint: A9348594CE31283A826FBDD8D57633D441E25BB5

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  reply	other threads:[~2023-02-06  0:00 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-05 15:28 Alejandro Colomar
2023-02-05 15:31 ` Alejandro Colomar
2023-02-06  6:02   ` Xi Ruoyao
2023-02-06 11:20     ` Rich Felker
2023-02-06 11:55     ` Alejandro Colomar
2023-02-06 13:38       ` Rich Felker
2023-02-06 14:11         ` Alejandro Colomar
2023-02-06 17:21           ` Zack Weinberg
2023-02-06 17:48           ` Rich Felker
2023-02-05 23:43 ` Rich Felker
2023-02-05 23:59   ` Alejandro Colomar [this message]
2023-02-06  0:15     ` Rich Felker
2023-02-06 18:45 ` Eric Blake
2023-02-07  1:21   ` Alejandro Colomar
2023-03-18  7:54   ` roucaries bastien
2023-03-20 10:49     ` Alejandro Colomar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=29bb163d-ab7b-2fb7-a1c8-cfd720984a8d@gmail.com \
    --to=alx.manpages@gmail.com \
    --cc=a.clayton@nginx.com \
    --cc=alx@kernel.org \
    --cc=dalias@libc.org \
    --cc=eblake@redhat.com \
    --cc=fweimer@redhat.com \
    --cc=gcc@gcc.gnu.org \
    --cc=igor@sysoev.ru \
    --cc=jakub@redhat.com \
    --cc=joseph@codesourcery.com \
    --cc=libc-alpha@sourceware.org \
    --cc=linux-man@vger.kernel.org \
    --cc=richard.guenther@gmail.com \
    --cc=rouca@debian.org \
    --cc=stefan.puiu@gmail.com \
    --cc=zack@owlfolio.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).