Mon Dec 25 20:56:39 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>

* sysdeps/mach/hurd/bind.c: Translate EEXIST from dir_link into
	EADDRINUSE.  If translated node doesn't grok ifsock protocol,
	return EADDRINUSE.

	* sysdeps/mach/hurd/connect.c: Make address arg
	`const struct sockaddr_un *'.
	The redecl is kosher and avoids another variable for AF_LOCAL case.
	* sysdeps/mach/hurd/sendto.c: Likewise.
	* sysdeps/mach/hurd/bind.c: Likewise.

	* socket/sys/socket.h (__SOCKADDR_ARG): Enable transparent_union
 	code for GCC >= 2.7; use __transparent_union__ for name safety;
 	add several sockaddr flavors.
	(__SOCKADDR_ALLTYPES, __SOCKADDR_ONETYPE): New macros used in
	constructing the transparent union declarations.
	(__CONST_SOCKADDR_ARG): New type (or macro if not GCC 2.7).
	(bind, connect, sendto): Make the sockaddr argument use that.
This commit is contained in:
Roland McGrath 1995-12-26 10:00:22 +00:00
parent e0f09b6b2a
commit be7e3b7e7e
5 changed files with 86 additions and 43 deletions

View file

@ -1,3 +1,23 @@
Mon Dec 25 20:56:39 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/mach/hurd/bind.c: Translate EEXIST from dir_link into
EADDRINUSE. If translated node doesn't grok ifsock protocol,
return EADDRINUSE.
* sysdeps/mach/hurd/connect.c: Make address arg
`const struct sockaddr_un *'.
The redecl is kosher and avoids another variable for AF_LOCAL case.
* sysdeps/mach/hurd/sendto.c: Likewise.
* sysdeps/mach/hurd/bind.c: Likewise.
* socket/sys/socket.h (__SOCKADDR_ARG): Enable transparent_union
code for GCC >= 2.7; use __transparent_union__ for name safety;
add several sockaddr flavors.
(__SOCKADDR_ALLTYPES, __SOCKADDR_ONETYPE): New macros used in
constructing the transparent union declarations.
(__CONST_SOCKADDR_ARG): New type (or macro if not GCC 2.7).
(bind, connect, sendto): Make the sockaddr argument use that.
Fri Dec 22 00:57:38 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/mach/hurd/setgid.c: In root case, store into NEWAUX, not

View file

@ -115,25 +115,38 @@ struct sockaddr
/* This is the type we use for generic socket address arguments.
NOTE: Since this functionality is volatile, I'm disabling the use of it for
now.
With GCC 2.6 and later, the funky union causes redeclarations or uses with
With GCC 2.7 and later, the funky union causes redeclarations or uses with
any of the listed types to be allowed without complaint. */
#if (!defined (__GNUC__) || __GNUC__ < 2 || \
/*(__GNUC__ == 2 && __GNUC_MINOR__ < 6)*/ 1)
#define __SOCKADDR_ARG struct sockaddr *
(__GNUC__ == 2 && __GNUC_MINOR__ < 7))
#define __SOCKADDR_ARG struct sockaddr *
#define __CONST_SOCKADDR_ARG __const struct sockaddr *
#else
/* Bring these names into being at top-level scope, in case they have not been
defined yet. Add more `struct sockaddr_AF' types here as necessary. */
struct sockaddr_in;
struct sockaddr_un;
struct sockaddr_ns;
typedef union { struct sockaddr *__sa;
struct sockaddr_in *__sa_in;
struct sockaddr_un *__sa_un;
struct sockaddr_ns *__sa_ns;
} __SOCKADDR_ARG __attribute__ ((transparent_union));
/* Add more `struct sockaddr_AF' types here as necessary.
These are all the ones I found on NetBSD and Linux. */
#define __SOCKADDR_ALLTYPES \
__SOCKADDR_ONETYPE (sockaddr) \
__SOCKADDR_ONETYPE (sockaddr_at) \
__SOCKADDR_ONETYPE (sockaddr_ax25) \
__SOCKADDR_ONETYPE (sockaddr_dl) \
__SOCKADDR_ONETYPE (sockaddr_eon) \
__SOCKADDR_ONETYPE (sockaddr_in) \
__SOCKADDR_ONETYPE (sockaddr_in6) \
__SOCKADDR_ONETYPE (sockaddr_inarp) \
__SOCKADDR_ONETYPE (sockaddr_ipx) \
__SOCKADDR_ONETYPE (sockaddr_iso) \
__SOCKADDR_ONETYPE (sockaddr_ns) \
__SOCKADDR_ONETYPE (sockaddr_un) \
__SOCKADDR_ONETYPE (sockaddr_x25)
#define __SOCKADDR_ONETYPE(type) struct type *__##type##__;
typedef union { __SOCKADDR_ALLTYPES
} __SOCKADDR_ARG __attribute__ ((__transparent_union__));
#undef __SOCKADDR_ONETYPE
#define __SOCKADDR_ONETYPE(type) __const struct type *__##type##__;
typedef union { __SOCKADDR_ALLTYPES
} __CONST_SOCKADDR_ARG __attribute__ ((__transparent_union__));
#undef __SOCKADDR_ONETYPE
#endif
@ -151,7 +164,7 @@ extern int socketpair __P ((int __domain, enum __socket_type __type,
int __protocol, int __fds[2]));
/* Give the socket FD the local address ADDR (which is LEN bytes long). */
extern int bind __P ((int __fd, __SOCKADDR_ARG __addr, size_t __len));
extern int bind __P ((int __fd, __CONST_SOCKADDR_ARG __addr, size_t __len));
/* Put the local address of FD into *ADDR and its length in *LEN. */
extern int getsockname __P ((int __fd, __SOCKADDR_ARG __addr,
@ -161,7 +174,8 @@ extern int getsockname __P ((int __fd, __SOCKADDR_ARG __addr,
For connectionless socket types, just set the default address to send to
and the only address from which to accept transmissions.
Return 0 on success, -1 for errors. */
extern int connect __P ((int __fd, __SOCKADDR_ARG __addr, size_t __len));
extern int connect __P ((int __fd,
__CONST_SOCKADDR_ARG __addr, size_t __len));
/* Put the address of the peer connected to socket FD into *ADDR
(which is *LEN bytes long), and its actual length into *LEN. */
@ -192,7 +206,7 @@ extern int recv __P ((int __fd, __ptr_t __buf, size_t __n, int __flags));
/* Send N bytes of BUF on socket FD to peer at address ADDR (which is
ADDR_LEN bytes long). Returns the number sent, or -1 for errors. */
extern int sendto __P ((int __fd, __ptr_t __buf, size_t __n, int __flags,
__SOCKADDR_ARG __addr, size_t __addr_len));
__CONST_SOCKADDR_ARG __addr, size_t __addr_len));
/* Read N bytes into BUF through socket FD.
If ADDR is not NULL, fill in *ADDR_LEN bytes of it with tha address of

View file

@ -32,23 +32,22 @@ Cambridge, MA 02139, USA. */
/* Give the socket FD the local address ADDR (which is LEN bytes long). */
int
DEFUN(bind, (fd, addr, len),
int fd AND struct sockaddr *addr AND size_t len)
int fd AND const struct sockaddr_un *addr AND size_t len)
{
addr_port_t aport;
error_t err;
if (addr->sa_family == AF_LOCAL)
if (addr->sun_family == AF_LOCAL)
{
/* For the local domain, we must create a node in the filesystem
using the ifsock translator and then fetch the address from it. */
struct sockaddr_un *unaddr = (struct sockaddr_un *) addr;
file_t dir, node;
char name[len - offsetof (struct sockaddr_un, sun_path)], *n;
strncpy (name, unaddr->sun_path, sizeof name);
strncpy (name, addr->sun_path, sizeof name);
dir = __file_name_split (name, &n);
if (dir == MACH_PORT_NULL)
return -1;
/* Create a new, unlinked node in the target directory. */
err = __dir_mkfile (dir, O_CREAT, 0666 & ~_hurd_umask, &node);
@ -56,15 +55,19 @@ DEFUN(bind, (fd, addr, len),
{
file_t ifsock;
/* Set the node's translator to make it a local-domain socket. */
err = __file_set_translator (node,
err = __file_set_translator (node,
FS_TRANS_EXCL | FS_TRANS_SET,
FS_TRANS_EXCL | FS_TRANS_SET, 0,
_HURD_IFSOCK, sizeof _HURD_IFSOCK,
MACH_PORT_NULL,
MACH_MSG_TYPE_COPY_SEND);
if (! err)
/* Link the node, now a socket, into the target directory. */
err = __dir_link (dir, node, n);
{
/* Link the node, now a socket, into the target directory. */
err = __dir_link (dir, node, n);
if (err == EEXIST)
err = EADDRINUSE;
}
__mach_port_deallocate (__mach_task_self (), node);
if (! err)
{
@ -78,8 +81,16 @@ DEFUN(bind, (fd, addr, len),
}
}
if (! err)
/* Get the address port. */
err = __ifsock_getsockaddr (ifsock, &aport);
{
/* Get the address port. */
err = __ifsock_getsockaddr (ifsock, &aport);
if (err == MIG_BAD_ID || err == EOPNOTSUPP)
/* We are not talking to /hurd/ifsock. Probably someone
came in after we linked our node, unlinked it, and
replaced it with a different node, before we did our
lookup. Treat it as if our link had failed with EEXIST. */
err = EADDRINUSE;
}
__mach_port_deallocate (__mach_task_self (), ifsock);
}
__mach_port_deallocate (__mach_task_self (), dir);
@ -94,7 +105,7 @@ DEFUN(bind, (fd, addr, len),
({
if (err)
err = __socket_create_address (port,
addr->sa_family,
addr->sun_family,
(char *) addr, len,
&aport);
if (! err)

View file

@ -31,17 +31,16 @@ Cambridge, MA 02139, USA. */
Return 0 on success, -1 for errors. */
int
DEFUN(connect, (fd, addr, len),
int fd AND struct sockaddr *addr AND size_t len)
int fd AND const struct sockaddr_un *addr AND size_t len)
{
error_t err;
addr_port_t aport;
if (addr->sa_family == AF_LOCAL)
if (addr->sun_family == AF_LOCAL)
{
/* For the local domain, we must look up the name as a file and talk
to it with the ifsock protocol. */
struct sockaddr_un *unaddr = (struct sockaddr_un *) addr;
file_t file = __file_name_lookup (unaddr->sun_path, 0, 0);
file_t file = __file_name_lookup (addr->sun_path, 0, 0);
if (file == MACH_PORT_NULL)
return -1;
err = __ifsock_getsockaddr (file, &aport);
@ -54,12 +53,12 @@ DEFUN(connect, (fd, addr, len),
}
else
err = EIEIO;
err = HURD_DPORT_USE (fd,
({
if (err)
err = __socket_create_address (port,
addr->sa_family,
addr->sun_family,
(char *) addr, len,
&aport);
if (! err)

View file

@ -30,18 +30,17 @@ Cambridge, MA 02139, USA. */
int
DEFUN(sendto, (fd, buf, n, flags, addr, addr_len),
int fd AND PTR buf AND size_t n AND int flags AND
struct sockaddr *addr AND size_t addr_len)
const struct sockaddr_un *addr AND size_t addr_len)
{
addr_port_t aport;
error_t err;
int wrote;
if (addr->sa_family == AF_LOCAL)
if (addr->sun_family == AF_LOCAL)
{
/* For the local domain, we must look up the name as a file and talk
to it with the ifsock protocol. */
struct sockaddr_un *unaddr = (struct sockaddr_un *) addr;
file_t file = __file_name_lookup (unaddr->sun_path, 0, 0);
file_t file = __file_name_lookup (addr->sun_path, 0, 0);
if (file == MACH_PORT_NULL)
return -1;
err = __ifsock_getsockaddr (file, &aport);
@ -60,7 +59,7 @@ DEFUN(sendto, (fd, buf, n, flags, addr, addr_len),
({
if (err)
err = __socket_create_address (port,
addr->sa_family,
addr->sun_family,
(char *) addr,
addr_len,
&aport);