aboutsummaryrefslogtreecommitdiff
path: root/pflocal/pf.c
diff options
context:
space:
mode:
Diffstat (limited to 'pflocal/pf.c')
-rw-r--r--pflocal/pf.c51
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;
}