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