diff options
Diffstat (limited to 'pflocal/socket.c')
-rw-r--r-- | pflocal/socket.c | 59 |
1 files changed, 51 insertions, 8 deletions
diff --git a/pflocal/socket.c b/pflocal/socket.c index 0bc72066..faa9951d 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> @@ -245,6 +245,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 +309,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 +323,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 +395,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 +411,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; } |