summaryrefslogtreecommitdiff
path: root/pflocal
diff options
context:
space:
mode:
Diffstat (limited to 'pflocal')
-rw-r--r--pflocal/ChangeLog248
-rw-r--r--pflocal/Makefile5
-rw-r--r--pflocal/connq.c34
-rw-r--r--pflocal/connq.h3
-rw-r--r--pflocal/io.c73
-rw-r--r--pflocal/mig-decls.h16
-rw-r--r--pflocal/pf.c51
-rw-r--r--pflocal/pflocal.c12
-rw-r--r--pflocal/sock.c58
-rw-r--r--pflocal/sock.h17
-rw-r--r--pflocal/socket.c61
-rw-r--r--pflocal/sserver.c5
12 files changed, 225 insertions, 358 deletions
diff --git a/pflocal/ChangeLog b/pflocal/ChangeLog
deleted file mode 100644
index 5b2d5b36..00000000
--- a/pflocal/ChangeLog
+++ /dev/null
@@ -1,248 +0,0 @@
-Tue Jul 23 19:44:29 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * sock.c (sock_create): Remove NEXT_SOCK_ID.
-
-Sat Jul 13 20:20:55 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * io.c (S_io_reauthenticate): Repeat sock_create_port and
- auth_server_authenticate for as long as we get EINTR.
-
-Sun Jul 7 21:30:33 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * io.c (S_io_reauthenticate): Don't use unsafe MOVE_SEND in call
- to auth_server_authenticate.
-
-Mon Jul 1 18:45:35 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * sock.c (sock_create): Initialize ID field to MACH_PORT_NULL.
-
-Thu Jun 27 17:58:09 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * Makefile (LCLHDRS): Add sserver.h.
-
-Thu Jun 20 16:33:06 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * Makefile (pflocal): Depend on ../libfshelp/libfshelp.a.
-
-Wed May 15 20:27:38 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * sock.c (sock_free): Destroy SOCK's id port if necessary.
-
-Tue May 14 14:05:33 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * io.c (S_io_identity): New function.
- * sock.h (struct sock): Make the id field a receive right, not an int.
-
-Thu May 9 20:20:20 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * io.c (S_io_reauthenticate): Use new auth_server_authenticate
- protocol.
-
-Thu May 9 12:14:37 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * io.c (S_io_select): Remove TAG arg.
-
-Mon Apr 15 12:52:32 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * Makefile (MIGSFLAGS): Look for mig-mutate.h in $(srcdir).
-
-Fri Jan 26 16:46:37 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * socket.c (S_socket_recv): Test for MSG_OOB in IN_FLAGS, not FLAGS.
- Return EINVAL if we get MSG_OOB, not EOPNOTSUPP.
-
-Thu Jan 25 17:34:50 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * sock.c (sock_create_port, addr_create): Use ports_create_port
- instead of ports_allocate_port.
- * pflocal.c (trivfs_goaway): Handle errors from
- ports_inhibit_bucket_rpcs.
- (thread_cancel): Function deleted.
-
-Tue Jan 23 21:31:40 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * socket.c (S_socket_connect): Handle connectionless protocols
- correctly.
-
- * socket.c (S_socket_send): Allow DEST_ADDR to be null if the
- socket is connected.
-
- * sock.c (sock_bind): Don't change SOCK's ref count if we're
- returning an error.
-
-Thu Jan 4 15:44:13 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * io.c (S_io_select): Reworked to avoid calling
- ports_interrupt_self_on_port_death() if there's data immediately
- available. Also, don't block if we can return EOF/EPIPE.
-
-Thu Dec 28 13:46:32 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * io.c (S_io_select): Use handy macro to avoid unthinkable line break.
-
-Tue Dec 26 17:30:18 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * io.c (S_io_select): Add reply port parameter, and request
- notification if it dies.
- * mig-mutate.h (IO_SELECT_REPLY_PORT): New def.
-
-Mon Nov 13 14:03:03 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * socket.c (S_socket_bind, S_socket_connect): Drop ADDR's send right.
-
-Thu Nov 9 13:18:44 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * socket.c (S_socket_connect): Drop our reference to ADDR.
-
-Sun Nov 5 10:01:15 1995 Miles Bader <miles@gnu.ai.mit.edu>
-
- * pf.c (S_socket_create_address): Removing BINDING argument.
-
- * pflocal.c (main): Add FLAGS argument to trivfs_startup call.
-
-Tue Sep 19 14:07:24 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * io.c (S_io_pathconf): New function.
- (S_io_set_all_openmodes, S_io_set_some_openmodes,
- S_io_clear_some_openmodes): The user specifies O_NONBLOCK, not
- SOCK_NONBLOCK.
- (S_io_get_openmodes): Always return O_APPEND.
-
-Wed Sep 6 11:53:48 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * sserver.c (sock_demuxer): Use ports_interrupt_server and
- ports_notify_server instead of our own version.
- (do_mach_notify_no_senders, do_mach_notify_port_deleted,
- do_mach_notify_msg_accepted, do_mach_notify_port_destroyed,
- do_mach_notify_port_deleted, do_mach_notify_send_once,
- do_mach_notify_dead_name): Functions deleted.
- * io.c (S_interrupt_operation): Function deleted.
- * Makefile (MIGSTUBS): Remove notifyServer.o and interruptServer.o.
-
- * io.c (S_io_read, S_io_readable): Don't return EPIPE on EOF.
-
-Tue Sep 5 14:22:18 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * io.c (S_io_stat): Only attempt to use the read pipe if it exists.
-
-Thu Aug 31 16:31:18 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * io.c (S_io_select): Change the way selects are done, now that
- writes can block.
- (S_io_write): Pass in the new NOBLOCK parameter to pipe_write.
- * socket.c (S_socket_send): Pass in the new NOBLOCK parameter to
- pipe_send.
-
-Tue Aug 29 14:33:14 1995 Miles Bader <miles@geech.gnu.ai.mit.edu>
-
- * io.c (S_io_select): Use pipe_select instead of pipe_wait.
-
- * connq.c (struct connq): Remove interrupt_seq_num field.
- (connq_listen): Use hurd_condition_wait to detect interrupts
- instead of previous ad-hoc mechanism.
- (connq_interrupt, connq_interrupt_sock): Functions deleted.
- * connq.h (connq_interrupt, connq_interrupt_sock): Decls deleted.
- * io.c (S_interrupt_operation): Use ports_interrupt_rpc to
- interrupt waiting threads.
-
- * sock.c (sock_acquire_read_pipe, sock_acquire_write_pipe):
- `aquire' -> `acquire'.
- * socket.c (S_socket_send, S_socket_recv): Ditto.
- * sock.h: Ditto.
-
-Tue Aug 29 14:30:59 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * io.c (S_io_select): Fix typo in masking off SELECT_URG.
- Don't check open modes and return EBADF.
-
-Thu Aug 24 10:35:58 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * Makefile (pflocal): Put all dependencies here.
- (OBJS): Remove error.o.
- (HURDLIBS): Removed.
- Removed all rules dealing with error.o.
-
-Mon Aug 21 16:37:32 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * pflocal.c (trivfs_goaway, trivfs_modify_stat): Update arguments.
-
-Fri Aug 11 15:33:28 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * sock.h (struct sock): Store the pipe class in a separate field,
- as READ_PIPE is no longer always defined.
- * sock.c (sock_create, sock_connect): Set/use the PIPE_CLASS field.
- (sock_connect, sock_aquire_write_pipe): Use pipe_aquire_writer
- instead of pipe_aquire.
- (sock_aquire_read_pipe): Use pipe_aquire_reader instead of
- pipe_aquire. Handle the case where there is no read pipe (in
- which case return EPIPE).
- (sock_shutdown): Make shutting down the read half just like the
- write half -- the pipe goes away...
- (sock_create): Don't bump the read pipe ref count ourself.
- (sock_free): Use sock_shutdown to trash the read pipe too.
-
- * socket.c
- (S_socket_recv): Use pipe_release_reader instead of pipe_release.
- (S_socket_send): Use pipe_release_writer instead of pipe_release.
- (S_socket_recv): Reflect EPIPE as EOF.
-
- * io.c (S_io_read, S_interrupt_operation, S_io_readable, S_io_select):
- Use pipe_release_reader instead of pipe_release.
- (S_io_write): Use pipe_release_writer instead of pipe_release.
- (S_io_readable, S_io_read): Reflect EPIPE as EOF.
-
-Mon Jul 31 13:59:15 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * connq.c (connq_compress): New function.
- (connq_interrupt_sock): Use connq_compress to compress the queue.
-
-Sun Jul 30 10:30:24 1995 Miles Bader <miles@duality.gnu.ai.mit.edu>
-
- * connq.c (connq_interrupt_sock): Reset CQ's tail to the end of
- the compressed queue.
-
-Sat Jul 29 00:00:57 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * socket.c (S_socket_send): Only free SOURCE_ADDR if the send
- fails, as otherwise it's consumed; also free all the ports in
- PORTS if the send fails.
-
- * io.c (S_interrupt_operation): Allow socket trying to connect to
- be interrupted.
- * connq.c (connq_interrupt_sock): New function.
- * socket.c (S_socket_connect): Use the CONNECT_QUEUE field to
- allow only a single connection attempt at once.
- Check for already-connected sockets here instead of waiting for
- the final rendezvous.
- * connq.h (connq_interrupt_sock): New declaration.
-
- * connq.c (connq_listen, connq_connect, connq_interrupt,
- connq_set_length): Reverse the roles of the HEAD and TAIL fields,
- and make sure they're used correctly.
- (qprev): Deleted function.
-
- * sock.h (struct sock, all uses changed): Add the CONNECT_QUEUE
- field, and rename the CONNQ field to LISTEN_QUEUE.
- * sock.c (sock_create): Initialize the CONNECT_QUEUE field and
- rename CONNQ to LISTEN_QUEUE.
-
- * connq.c (connq_set_length): When shrinking the queue, actually
- do so, and don't leak memory.
-
- * socket.c (S_socket_connect): Return ECONNREFUSED when trying to
- connect to a non-existant address, instead of EADDRNOTAVAIL.
-
- * connq.c (struct connq): Add the INTERRUPT_SEQ_NUM field, used to
- detect interupts.
- (connq_listen): Detect when we get interrupted, and return EINTR.
- (connq_interrupt): New function.
- * connq.h (connq_interrupt): New declaration.
- * io.c (S_interrupt_operation): Call connq_interrupt when appropiate.
-
- * connq.c (connq_connect): Initialize REQ before using it.
- (connq_request_init): Swap the arguments.
- (connq_listen): Don't lock the accepted request just to get its sock.
-
- * socket.c (S_socket_connect): Actually use the connq operations
- to connect, like the listening socket is expecting, instead of
- connecting directly to it.
diff --git a/pflocal/Makefile b/pflocal/Makefile
index 5ab1a86e..7258e587 100644
--- a/pflocal/Makefile
+++ b/pflocal/Makefile
@@ -1,6 +1,6 @@
# Makefile for pflocal
#
-# Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+# Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
@@ -26,9 +26,8 @@ LCLHDRS = connq.h sock.h mig-decls.h mig-mutate.h sserver.h
MIGSTUBS = ioServer.o socketServer.o
OBJS = $(SRCS:.c=.o) $(MIGSTUBS)
+HURDLIBS = pipe trivfs iohelp fshelp threads ports ihash shouldbeinlibc
MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
-pflocal: $(OBJS) ../libpipe/libpipe.a ../libtrivfs/libtrivfs.a ../libfshelp/libfshelp.a ../libports/libports.a ../libthreads/libthreads.a ../libihash/libihash.a ../libshouldbeinlibc/libshouldbeinlibc.a
-
include ../Makeconf
diff --git a/pflocal/connq.c b/pflocal/connq.c
index 5efeb5d2..d4103840 100644
--- a/pflocal/connq.c
+++ b/pflocal/connq.c
@@ -1,8 +1,8 @@
/* Listen queue functions
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995,96,2001 Free Software Foundation, Inc.
- Written by Miles Bader <miles@gnu.ai.mit.edu>
+ Written by Miles Bader <miles@gnu.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -19,6 +19,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <cthreads.h>
+#include <assert.h>
#include "connq.h"
@@ -108,6 +109,20 @@ connq_create (struct connq **cq)
*cq = new;
return 0;
}
+
+/* Destroy a queue. */
+void
+connq_destroy (struct connq *cq)
+{
+ /* Everybody in the queue should hold a reference to the socket
+ containing the queue. */
+ assert (cq->length == 0);
+ /* Nevertheless, malloc(0) or realloc(0) might allocate some small
+ space. */
+ if (cq->queue)
+ free (cq->queue);
+ free (cq);
+}
/* ---------------------------------------------------------------- */
@@ -117,14 +132,17 @@ connq_create (struct connq **cq)
to allow the requesting thread to continue. If NOBLOCK is true,
EWOULDBLOCK is returned when there are no immediate connections
available. */
-error_t
+error_t
connq_listen (struct connq *cq, int noblock,
struct connq_request **req, struct sock **sock)
{
mutex_lock (&cq->lock);
if (noblock && cq->head == cq->tail)
- return EWOULDBLOCK;
+ {
+ mutex_unlock (&cq->lock);
+ return EWOULDBLOCK;
+ }
cq->num_listeners++;
@@ -132,7 +150,7 @@ connq_listen (struct connq *cq, int noblock,
if (hurd_condition_wait (&cq->listeners, &cq->lock))
{
cq->num_listeners--;
- mutex_unlock (&cq->lock);
+ mutex_unlock (&cq->lock);
return EINTR;
}
@@ -149,7 +167,7 @@ connq_listen (struct connq *cq, int noblock,
mutex_unlock (&cq->lock);
- return 0;
+ return 0;
}
/* Return the error code ERR to the thread that made the listen request REQ,
@@ -211,6 +229,7 @@ connq_connect (struct connq *cq, int noblock, struct sock *sock)
return err;
}
+#if 0
/* `Compresses' CQ, by removing any NULL entries. CQ should be locked. */
static void
connq_compress (struct connq *cq)
@@ -231,10 +250,11 @@ connq_compress (struct connq *cq)
/* Move back tail to only include what we kept in the queue. */
cq->tail = comp_tail;
}
+#endif
/* Set CQ's queue length to LENGTH. Any sockets already waiting for a
connections that are past the new length will fail with ECONNREFUSED. */
-error_t
+error_t
connq_set_length (struct connq *cq, int length)
{
mutex_lock (&cq->lock);
diff --git a/pflocal/connq.h b/pflocal/connq.h
index 8486eb17..1039bff9 100644
--- a/pflocal/connq.h
+++ b/pflocal/connq.h
@@ -33,6 +33,9 @@ struct sock;
is already listening (change this with connq_set_length). */
error_t connq_create (struct connq **cq);
+/* Destroy a queue. */
+void connq_destroy (struct connq *cq);
+
/* Wait for a connection attempt to be made on CQ, and return the connecting
socket in SOCK, and a request tag in REQ. If REQ is NULL, the request is
left in the queue, otherwise connq_request_complete must be called on REQ
diff --git a/pflocal/io.c b/pflocal/io.c
index 02dfbd40..36221a66 100644
--- a/pflocal/io.c
+++ b/pflocal/io.c
@@ -1,8 +1,9 @@
/* Socket I/O operations
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1998, 1999, 2000, 2002, 2007
+ Free Software Foundation, Inc.
- Written by Miles Bader <miles@gnu.ai.mit.edu>
+ Written by Miles Bader <miles@gnu.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -23,6 +24,7 @@
#include <sys/types.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
+#include <sys/mman.h>
#include <hurd.h> /* for getauth() */
#include <hurd/hurd_types.h>
@@ -104,7 +106,7 @@ S_io_write (struct sock_user *user,
{
err = pipe_write (pipe, user->sock->flags & SOCK_NONBLOCK,
source_addr, data, data_len, amount);
- if (source_addr)
+ if (err && source_addr)
ports_port_deref (source_addr);
}
@@ -117,7 +119,7 @@ S_io_write (struct sock_user *user,
/* Tell how much data can be read from the object without blocking for
a "long time" (this should be the same meaning of "long time" used
by the nonblocking flag. */
-error_t
+error_t
S_io_readable (struct sock_user *user, mach_msg_type_number_t *amount)
{
error_t err;
@@ -196,17 +198,19 @@ S_io_select (struct sock_user *user,
*select_type &= SELECT_READ;
if (*select_type & SELECT_READ)
- /* Wait for a connect. Passing in NULL for REQ means that the
- request won't be dequeued. */
- if (connq_listen (sock->listen_queue, 1, NULL, NULL) == 0)
- /* We can satisfy this request immediately. */
- return 0;
- else
- /* Gotta wait... */
- {
- ports_interrupt_self_on_port_death (user, reply);
- return connq_listen (sock->listen_queue, 0, NULL, NULL);
- }
+ {
+ /* Wait for a connect. Passing in NULL for REQ means that the
+ request won't be dequeued. */
+ if (connq_listen (sock->listen_queue, 1, NULL, NULL) == 0)
+ /* We can satisfy this request immediately. */
+ return 0;
+ else
+ /* Gotta wait... */
+ {
+ ports_interrupt_self_on_port_death (user, reply);
+ return connq_listen (sock->listen_queue, 0, NULL, NULL);
+ }
+ }
}
else
/* Sock is a normal read/write socket. */
@@ -270,10 +274,10 @@ S_io_stat (struct sock_user *user, struct stat *st)
struct sock *sock;
struct pipe *rpipe, *wpipe;
- void copy_time (time_value_t *from, time_t *to_sec, unsigned long *to_usec)
+ void copy_time (time_value_t *from, time_t *to_sec, unsigned long *to_nsec)
{
*to_sec = from->seconds;
- *to_usec = from->microseconds;
+ *to_nsec = from->microseconds * 1000;
}
if (!user)
@@ -284,7 +288,7 @@ S_io_stat (struct sock_user *user, struct stat *st)
bzero (st, sizeof (struct stat));
st->st_fstype = FSTYPE_SOCKET;
- st->st_mode = S_IFSOCK;
+ st->st_mode = sock->mode;
st->st_fsid = getpid ();
st->st_ino = sock->id;
/* As we try to be clever with large transfers, ask for them. */
@@ -298,7 +302,7 @@ S_io_stat (struct sock_user *user, struct stat *st)
if (rpipe)
{
mutex_lock (&rpipe->lock);
- copy_time (&rpipe->read_time, &st->st_atime, &st->st_atime_usec);
+ copy_time (&rpipe->read_time, &st->st_atim.tv_sec, &st->st_atim.tv_nsec);
/* This seems useful. */
st->st_size = pipe_readable (rpipe, 1);
mutex_unlock (&rpipe->lock);
@@ -307,11 +311,11 @@ S_io_stat (struct sock_user *user, struct stat *st)
if (wpipe)
{
mutex_lock (&wpipe->lock);
- copy_time (&wpipe->write_time, &st->st_mtime, &st->st_mtime_usec);
+ copy_time (&wpipe->write_time, &st->st_mtim.tv_sec, &st->st_mtim.tv_nsec);
mutex_unlock (&wpipe->lock);
}
- copy_time (&sock->change_time, &st->st_ctime, &st->st_ctime_usec);
+ copy_time (&sock->change_time, &st->st_ctim.tv_sec, &st->st_ctim.tv_nsec);
mutex_unlock (&sock->lock);
@@ -389,8 +393,8 @@ S_io_reauthenticate (struct sock_user *user, mach_port_t rendezvous)
uid_t *uids = uids_buf, *aux_uids = aux_uids_buf;
gid_t gids_buf[NIDS], aux_gids_buf[NIDS];
gid_t *gids = gids_buf, *aux_gids = aux_gids_buf;
- unsigned num_uids = NIDS, num_aux_uids = NIDS;
- unsigned num_gids = NIDS, num_aux_gids = NIDS;
+ size_t num_uids = NIDS, num_aux_uids = NIDS;
+ size_t num_gids = NIDS, num_aux_gids = NIDS;
if (!user)
return EOPNOTSUPP;
@@ -402,14 +406,14 @@ S_io_reauthenticate (struct sock_user *user, mach_port_t rendezvous)
return err;
auth_server = getauth ();
- err = mach_port_insert_right (mach_task_self (), new_user_port,
+ err = mach_port_insert_right (mach_task_self (), new_user_port,
new_user_port, MACH_MSG_TYPE_MAKE_SEND);
assert_perror (err);
do
err =
- auth_server_authenticate (auth_server,
+ auth_server_authenticate (auth_server,
rendezvous, MACH_MSG_TYPE_COPY_SEND,
- new_user_port, MACH_MSG_TYPE_COPY_SEND,
+ new_user_port, MACH_MSG_TYPE_COPY_SEND,
&uids, &num_uids, &aux_uids, &num_aux_uids,
&gids, &num_gids, &aux_gids, &num_aux_gids);
while (err == EINTR);
@@ -420,7 +424,7 @@ S_io_reauthenticate (struct sock_user *user, mach_port_t rendezvous)
/* Throw away the ids we went through all that trouble to get... */
#define TRASH_IDS(ids, buf, num) \
if (buf != ids) \
- vm_deallocate (mach_task_self (), (vm_address_t)ids, num * sizeof (uid_t));
+ munmap (ids, num * sizeof (uid_t));
TRASH_IDS (uids, uids_buf, num_uids);
TRASH_IDS (gids, gids_buf, num_gids);
@@ -434,8 +438,8 @@ error_t
S_io_restrict_auth (struct sock_user *user,
mach_port_t *new_port,
mach_msg_type_name_t *new_port_type,
- uid_t *uids, unsigned num_uids,
- uid_t *gids, unsigned num_gids)
+ uid_t *uids, size_t num_uids,
+ uid_t *gids, size_t num_gids)
{
if (!user)
return EOPNOTSUPP;
@@ -466,7 +470,7 @@ error_t
S_io_identity (struct sock_user *user,
mach_port_t *id, mach_msg_type_name_t *id_type,
mach_port_t *fsys_id, mach_msg_type_name_t *fsys_id_type,
- int *fileno)
+ ino_t *fileno)
{
static mach_port_t server_id = MACH_PORT_NULL;
error_t err = 0;
@@ -508,10 +512,17 @@ S_io_identity (struct sock_user *user,
return err;
}
+
/* Stubs for currently unsupported rpcs. */
error_t
+S_io_revoke (struct sock_user *user)
+{
+ return EOPNOTSUPP;
+}
+
+error_t
S_io_async(struct sock_user *user,
mach_port_t notify_port,
mach_port_t *async_id_port,
@@ -526,7 +537,7 @@ S_io_mod_owner(struct sock_user *user, pid_t owner)
return EOPNOTSUPP;
}
-error_t
+error_t
S_io_get_owner(struct sock_user *user, pid_t *owner)
{
return EOPNOTSUPP;
diff --git a/pflocal/mig-decls.h b/pflocal/mig-decls.h
index fe4aefdf..983de9d1 100644
--- a/pflocal/mig-decls.h
+++ b/pflocal/mig-decls.h
@@ -1,8 +1,8 @@
/* Type decls for mig-produced server stubs
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995,2001 Free Software Foundation, Inc.
- Written by Miles Bader <miles@gnu.ai.mit.edu>
+ Written by Miles Bader <miles@gnu.org>
This file is part of the GNU Hurd.
@@ -30,26 +30,26 @@
typedef struct sock_user *sock_user_t;
typedef struct addr *addr_t;
-extern inline
-sock_user_t begin_using_sock_user_port(mach_port_t port)
+static inline sock_user_t __attribute__ ((unused))
+begin_using_sock_user_port(mach_port_t port)
{
return (sock_user_t)ports_lookup_port (0, port, sock_user_port_class);
}
-extern inline void
+static inline void __attribute__ ((unused))
end_using_sock_user_port (sock_user_t sock_user)
{
if (sock_user != NULL)
ports_port_deref (sock_user);
}
-extern inline
-addr_t begin_using_addr_port(mach_port_t port)
+static inline addr_t __attribute__ ((unused))
+begin_using_addr_port(mach_port_t port)
{
return (addr_t)ports_lookup_port (0, port, addr_port_class);
}
-extern inline void
+static inline void __attribute__ ((unused))
end_using_addr_port (addr_t addr)
{
if (addr != NULL)
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;
}
diff --git a/pflocal/pflocal.c b/pflocal/pflocal.c
index 27148bd6..7a4e8d91 100644
--- a/pflocal/pflocal.c
+++ b/pflocal/pflocal.c
@@ -1,6 +1,6 @@
/* A server for local sockets, of type PF_LOCAL
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc.
Written by Miles Bader <miles@gnu.ai.mit.edu>
@@ -55,7 +55,9 @@ pf_demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
return socket_server (inp, outp) || trivfs_demuxer (inp, outp);
}
-void main(int argc, char *argv[])
+
+int
+main(int argc, char *argv[])
{
error_t err;
mach_port_t bootstrap;
@@ -69,7 +71,7 @@ void main(int argc, char *argv[])
task_get_bootstrap_port (mach_task_self (), &bootstrap);
if (bootstrap == MACH_PORT_NULL)
error(2, 0, "Must be started as a translator");
-
+
pf_port_bucket = ports_create_bucket ();
trivfs_cntl_portclasses[0] = ports_create_class (trivfs_clean_cntl, 0);
@@ -93,10 +95,10 @@ void main(int argc, char *argv[])
do
ports_manage_port_operations_multithread (pf_port_bucket,
pf_demuxer,
- 30*1000, 5*60*1000, 0, 0);
+ 30*1000, 5*60*1000, 0);
while (sock_global_shutdown () != 0);
- exit(0);
+ return 0;
}
void
diff --git a/pflocal/sock.c b/pflocal/sock.c
index 350c7de8..292e4290 100644
--- a/pflocal/sock.c
+++ b/pflocal/sock.c
@@ -1,8 +1,7 @@
/* Sock functions
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
- Written by Miles Bader <miles@gnu.ai.mit.edu>
+ Copyright (C) 1995,96,2000,01,02, 2005 Free Software Foundation, Inc.
+ Written by Miles Bader <miles@gnu.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -18,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-#include <string.h> /* For bzero() */
+#include <string.h> /* For memset() */
#include <cthreads.h>
@@ -26,6 +25,7 @@
#include "sock.h"
#include "sserver.h"
+#include "connq.h"
/* ---------------------------------------------------------------- */
@@ -94,7 +94,7 @@ sock_acquire_write_pipe (struct sock *sock, struct pipe **pipe)
/* Return a new socket with the given pipe class in SOCK. */
error_t
-sock_create (struct pipe_class *pipe_class, struct sock **sock)
+sock_create (struct pipe_class *pipe_class, mode_t mode, struct sock **sock)
{
error_t err;
struct sock *new = malloc (sizeof (struct sock));
@@ -116,12 +116,13 @@ sock_create (struct pipe_class *pipe_class, struct sock **sock)
new->refs = 0;
new->flags = 0;
new->write_pipe = NULL;
+ new->mode = mode;
new->id = MACH_PORT_NULL;
new->listen_queue = NULL;
new->connect_queue = NULL;
new->pipe_class = pipe_class;
new->addr = NULL;
- bzero (&new->change_time, sizeof (new->change_time));
+ memset (&new->change_time, 0, sizeof (new->change_time));
mutex_init (&new->lock);
*sock = new;
@@ -135,6 +136,8 @@ sock_free (struct sock *sock)
sock_shutdown (sock, SOCK_SHUTDOWN_READ | SOCK_SHUTDOWN_WRITE);
if (sock->id != MACH_PORT_NULL)
mach_port_destroy (mach_task_self (), sock->id);
+ if (sock->listen_queue)
+ connq_destroy (sock->listen_queue);
free (sock);
}
@@ -155,7 +158,7 @@ _sock_norefs (struct sock *sock)
error_t
sock_clone (struct sock *template, struct sock **sock)
{
- error_t err = sock_create (template->pipe_class, sock);
+ error_t err = sock_create (template->pipe_class, template->mode, sock);
if (err)
return err;
@@ -444,6 +447,8 @@ void
sock_shutdown (struct sock *sock, unsigned flags)
{
unsigned old_flags;
+ struct pipe *read_pipe = NULL;
+ struct pipe *write_pipe = NULL;
mutex_lock (&sock->lock);
@@ -451,36 +456,25 @@ sock_shutdown (struct sock *sock, unsigned flags)
sock->flags |= flags;
if (flags & SOCK_SHUTDOWN_READ && !(old_flags & SOCK_SHUTDOWN_READ))
- /* Shutdown the read half. */
{
- struct pipe *pipe = sock->read_pipe;
- if (pipe != NULL)
- {
- sock->read_pipe = NULL;
- /* Unlock SOCK here, as we may subsequently wake up other threads. */
- mutex_unlock (&sock->lock);
- pipe_remove_reader (pipe);
- }
- else
- mutex_unlock (&sock->lock);
+ /* Shutdown the read half. */
+ read_pipe = sock->read_pipe;
+ sock->read_pipe = NULL;
}
-
if (flags & SOCK_SHUTDOWN_WRITE && !(old_flags & SOCK_SHUTDOWN_WRITE))
- /* Shutdown the write half. */
{
- struct pipe *pipe = sock->write_pipe;
- if (pipe != NULL)
- {
- sock->write_pipe = NULL;
- /* Unlock SOCK here, as we may subsequently wake up other threads. */
- mutex_unlock (&sock->lock);
- pipe_remove_writer (pipe);
- }
- else
- mutex_unlock (&sock->lock);
+ /* Shutdown the write half. */
+ write_pipe = sock->write_pipe;
+ sock->write_pipe = NULL;
}
- else
- mutex_unlock (&sock->lock);
+
+ /* Unlock SOCK here, as we may subsequently wake up other threads. */
+ mutex_unlock (&sock->lock);
+
+ if (read_pipe)
+ pipe_remove_reader (read_pipe);
+ if (write_pipe)
+ pipe_remove_writer (write_pipe);
}
/* ---------------------------------------------------------------- */
diff --git a/pflocal/sock.h b/pflocal/sock.h
index f09e5ca8..6bad8af8 100644
--- a/pflocal/sock.h
+++ b/pflocal/sock.h
@@ -1,8 +1,8 @@
/* Internal sockets
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995,96,99,2000,01 Free Software Foundation, Inc.
- Written by Miles Bader <miles@gnu.ai.mit.edu>
+ Written by Miles Bader <miles@gnu.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -23,13 +23,15 @@
#include <assert.h>
#include <cthreads.h> /* For mutexes */
+#include <sys/mman.h>
+#include <sys/types.h>
#include <hurd/ports.h>
struct pipe;
struct pipe_class;
-/* A port on SOCK. Multiple sock_user's can point to the same socket. */
+/* A port on SOCK. Multiple sock_user's can point to the same socket. */
struct sock_user
{
struct port_info pi;
@@ -59,6 +61,10 @@ struct sock
/* Last time the socket got frobbed. */
time_value_t change_time;
+ /* File mode as reported by stat. Usually this is S_ISOCK, but it
+ should be S_IFIFO for sockets (ab)used in a pipe. */
+ mode_t mode;
+
/* This socket's local address. Note that we don't hold any references on
ADDR, and depend on the addr zeroing our pointer if it goes away (which
is ok, as we can then just make up another address if necessary, and no
@@ -99,7 +105,8 @@ error_t sock_acquire_write_pipe (struct sock *sock, struct pipe **pipe);
error_t sock_connect (struct sock *sock1, struct sock *sock2);
/* Return a new socket with the given pipe class in SOCK. */
-error_t sock_create (struct pipe_class *pipe_class, struct sock **sock);
+error_t sock_create (struct pipe_class *pipe_class, mode_t mode,
+ struct sock **sock);
/* Free SOCK, assuming there are no more handle on it. */
void sock_free (struct sock *sock);
@@ -108,7 +115,7 @@ void sock_free (struct sock *sock);
void _sock_norefs (struct sock *sock);
/* Remove a reference from SOCK, possibly freeing it. */
-extern inline void
+static inline void __attribute__ ((unused))
sock_deref (struct sock *sock)
{
mutex_lock (&sock->lock);
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;
}
diff --git a/pflocal/sserver.c b/pflocal/sserver.c
index af0f0c1e..7e00b323 100644
--- a/pflocal/sserver.c
+++ b/pflocal/sserver.c
@@ -1,6 +1,6 @@
/* Server for socket ops
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1997 Free Software Foundation, Inc.
Written by Miles Bader <miles@gnu.ai.mit.edu>
@@ -52,8 +52,7 @@ handle_sock_requests ()
{
ports_enable_bucket (sock_port_bucket);
ports_manage_port_operations_multithread (sock_port_bucket, sock_demuxer,
- 30*1000, 2*60*1000,
- 1, MACH_PORT_NULL);
+ 30*1000, 2*60*1000, 0);
}
/* The last service thread is about to exist; make this known. */