diff options
Diffstat (limited to 'pflocal/pf.c')
-rw-r--r-- | pflocal/pf.c | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/pflocal/pf.c b/pflocal/pf.c index d404743d..55824d41 100644 --- a/pflocal/pf.c +++ b/pflocal/pf.c @@ -1,6 +1,6 @@ /* Protocol family operations - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1999, 2000, 2008 Free Software Foundation, Inc. Written by Miles Bader <miles@gnu.ai.mit.edu> @@ -18,8 +18,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <stddef.h> #include <sys/socket.h> - #include <hurd/pipe.h> #include "sock.h" @@ -36,9 +36,25 @@ S_socket_create (mach_port_t pf, error_t err; struct sock *sock; struct pipe_class *pipe_class; - - if (protocol != 0) - return EPROTONOSUPPORT; + mode_t mode; + + /* We have a set of `magic' protocols that allow the user to choose + the file type of the socket. The primary application is to make + sockets that pretend to be a FIFO, for the implementations of + pipes. */ + switch (protocol) + { + case 0: + mode = S_IFSOCK; + break; + case S_IFCHR: + case S_IFSOCK: + case S_IFIFO: + mode = protocol; + break; + default: + return EPROTONOSUPPORT; + } switch (sock_type) { @@ -49,10 +65,10 @@ S_socket_create (mach_port_t pf, case SOCK_SEQPACKET: pipe_class = seqpack_pipe_class; break; default: - return ESOCKTNOSUPPORT; + return EPROTOTYPE; } - err = sock_create (pipe_class, &sock); + err = sock_create (pipe_class, mode, &sock); if (!err) { err = sock_create_port (sock, port); @@ -92,14 +108,33 @@ S_socket_fabricate_address (mach_port_t pf, *addr_port = ports_get_right (addr); *addr_port_type = MACH_MSG_TYPE_MAKE_SEND; + ports_port_deref (addr); return 0; } +/* Implement socket_whatis_address as described in <hurd/socket.defs>. + Since we cannot tell what our address is, return an empty string as + the file name. This is primarily for the implementation of accept + and recvfrom. The functions getsockname and getpeername remain + unsupported for the local namespace. */ error_t S_socket_whatis_address (struct addr *addr, int *sockaddr_type, char **sockaddr, size_t *sockaddr_len) { - return EOPNOTSUPP; + socklen_t addr_len = (offsetof (struct sockaddr, sa_data) + 1); + + if (! addr) + return EOPNOTSUPP; + + *sockaddr_type = AF_LOCAL; + if (*sockaddr_len < addr_len) + *sockaddr = mmap (0, addr_len, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); + ((struct sockaddr *) *sockaddr)->sa_len = addr_len; + ((struct sockaddr *) *sockaddr)->sa_family = *sockaddr_type; + ((struct sockaddr *) *sockaddr)->sa_data[0] = 0; + *sockaddr_len = addr_len; + + return 0; } |