diff options
Diffstat (limited to 'pflocal/socket.c')
-rw-r--r-- | pflocal/socket.c | 61 |
1 files changed, 53 insertions, 8 deletions
diff --git a/pflocal/socket.c b/pflocal/socket.c index 0bc72066..2684a723 100644 --- a/pflocal/socket.c +++ b/pflocal/socket.c @@ -1,6 +1,6 @@ /* Socket-specific operations - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 2008, 2010 Free Software Foundation, Inc. Written by Miles Bader <miles@gnu.ai.mit.edu> @@ -37,6 +37,8 @@ S_socket_connect2 (struct sock_user *user1, struct sock_user *user2) return EOPNOTSUPP; err = sock_connect (user1->sock, user2->sock); + if (!err && user1->sock->pipe_class->flags & PIPE_CLASS_CONNECTIONLESS) + err = sock_connect (user2->sock, user1->sock); /* Since USER2 isn't in the receiver position in the rpc, we get a send right for it (although we only use the receive right with the same @@ -245,6 +247,7 @@ S_socket_name (struct sock_user *user, *addr_port = ports_get_right (addr); *addr_port_type = MACH_MSG_TYPE_MAKE_SEND; + ports_port_deref (addr); return 0; } @@ -308,7 +311,7 @@ S_socket_send (struct sock_user *user, struct addr *dest_addr, int flags, if (dest_sock) /* Grab the destination socket's read pipe directly, and stuff data into it. This is not quite the usage sock_acquire_read_pipe was - intended for, but it will work, as the only inappropiate errors + intended for, but it will work, as the only inappropriate errors occur on a broken pipe, which shouldn't be possible with the sort of sockets with which we can use socket_send... XXXX */ err = sock_acquire_read_pipe (dest_sock, &pipe); @@ -322,7 +325,10 @@ S_socket_send (struct sock_user *user, struct addr *dest_addr, int flags, source_addr, data, data_len, control, control_len, ports, num_ports, amount); - pipe_release_writer (pipe); + if (dest_sock) + pipe_release_reader (pipe); + else + pipe_release_writer (pipe); } if (err) @@ -391,7 +397,7 @@ S_socket_recv (struct sock_user *user, /* Setup mach ports for return. */ { *addr_type = MACH_MSG_TYPE_MAKE_SEND; - *ports_type = MACH_MSG_TYPE_MAKE_SEND; + *ports_type = MACH_MSG_TYPE_COPY_SEND; if (source_addr) { *addr = ports_get_right (source_addr); @@ -407,19 +413,58 @@ S_socket_recv (struct sock_user *user, return err; } -/* Stubs for currently unsupported rpcs. */ - error_t S_socket_getopt (struct sock_user *user, int level, int opt, char **value, size_t *value_len) { - return EOPNOTSUPP; + int ret = 0; + + if (!user) + return EOPNOTSUPP; + + mutex_lock (&user->sock->lock); + switch (level) + { + case SOL_SOCKET: + switch (opt) + { + case SO_TYPE: + assert (*value_len >= sizeof (int)); + *(int *)*value = user->sock->pipe_class->sock_type; + *value_len = sizeof (int); + break; + default: + ret = ENOPROTOOPT; + break; + } + break; + default: + ret = ENOPROTOOPT; + break; + } + mutex_unlock (&user->sock->lock); + + return ret; } error_t S_socket_setopt (struct sock_user *user, int level, int opt, char *value, size_t value_len) { - return EOPNOTSUPP; + int ret = 0; + + if (!user) + return EOPNOTSUPP; + + mutex_lock (&user->sock->lock); + switch (level) + { + default: + ret = ENOPROTOOPT; + break; + } + mutex_unlock (&user->sock->lock); + + return ret; } |