aboutsummaryrefslogtreecommitdiff
path: root/trans/fifo.c
diff options
context:
space:
mode:
Diffstat (limited to 'trans/fifo.c')
-rw-r--r--trans/fifo.c188
1 files changed, 78 insertions, 110 deletions
diff --git a/trans/fifo.c b/trans/fifo.c
index 8ce5916a..39043acd 100644
--- a/trans/fifo.c
+++ b/trans/fifo.c
@@ -1,8 +1,7 @@
/* A translator for fifos
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
- Written by Miles Bader <miles@gnu.ai.mit.edu>
+ Copyright (C) 1995,96,97,98,2001,02 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
@@ -19,12 +18,13 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
+#include <stdlib.h>
#include <errno.h>
-#include <getopt.h>
#include <unistd.h>
#include <error.h>
#include <string.h>
#include <fcntl.h>
+#include <argp.h>
#include <cthreads.h>
#include <hurd.h>
@@ -33,6 +33,8 @@
#include <hurd/fsys.h>
#include <hurd/pipe.h>
+#include <version.h>
+
/* Global options. These defaults are the standard ones, I think... */
int wait_for_reader = 1, wait_for_writer = 1;
int one_reader = 1;
@@ -48,106 +50,65 @@ struct mutex active_fifo_lock;
/* Signal this when ACTIVE_FIFO may have changed. */
struct condition active_fifo_changed;
-/* ---------------------------------------------------------------- */
+const char *argp_program_version = STANDARD_HURD_VERSION (fifo);
-#define USAGE "Usage: %s [OPTION...]\n"
+static struct argp_option options[] =
+{
+ { "multiple-readers", 'm', 0, 0, "Allow multiple simultaneous readers" },
+ { "noblock", 'n', 0, 0, "Don't block on open" },
+ { "dgram", 'd', 0, 0, "Reads reflect write record boundaries" },
+ { 0 }
+};
-static void
-usage(int status)
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
{
- if (status != 0)
- fprintf(stderr, "Try `%s --help' for more information.\n",
- program_invocation_name);
- else
+ switch (key)
{
- printf(USAGE, program_invocation_name);
- printf("\
-\n\
- -r, --multiple-readers Allow multiple simultaneous readers\n\
- -n, --noblock Don't block on open\n\
- -d, --dgram Reads reflect write record boundaries\n\
- --help Give this usage message\n\
-");
+ case 'm': one_reader = 0; break;
+ case 'n': wait_for_reader = wait_for_writer = 0; break;
+ case 'd': fifo_pipe_class = seqpack_pipe_class; break;
+ default: return ARGP_ERR_UNKNOWN;
}
-
- exit(status);
+ return 0;
}
-#define SHORT_OPTIONS "&"
-
-static struct option options[] =
-{
- {"multiple-readers", no_argument, 0, 'r'},
- {"noblock", no_argument, 0, 'n'},
- {"dgram", no_argument, 0, 'd'},
- {"help", no_argument, 0, '&'},
- {0, 0, 0, 0}
+static const struct argp argp = {
+ options, parse_opt, 0, "Translator for fifos."
};
-/* ---------------------------------------------------------------- */
-
-struct port_class *trivfs_protid_portclasses[1];
-struct port_class *trivfs_cntl_portclasses[1];
-int trivfs_protid_nportclasses = 1;
-int trivfs_cntl_nportclasses = 1;
-
-void
+int
main (int argc, char **argv)
{
- int opt;
error_t err;
mach_port_t bootstrap;
- struct port_bucket *port_bucket;
- struct port_class *fifo_port_class, *fsys_port_class;
+ struct trivfs_control *fsys;
fifo_pipe_class = stream_pipe_class;
- while ((opt = getopt_long(argc, argv, SHORT_OPTIONS, options, 0)) != EOF)
- switch (opt)
- {
- case 'r': one_reader = 0; break;
- case 'n': wait_for_reader = wait_for_writer = 0; break;
- case 'd': fifo_pipe_class = seqpack_pipe_class;
- case '&': usage(0);
- default: usage(1);
- }
-
- if (argc != 1)
- {
- fprintf(stderr, "Usage: %s", program_invocation_name);
- exit(1);
- }
-
- port_bucket = ports_create_bucket ();
- fifo_port_class = ports_create_class (trivfs_clean_protid, 0);
- fsys_port_class = ports_create_class (trivfs_clean_cntl, 0);
-
- trivfs_protid_portclasses[0] = fifo_port_class;
- trivfs_cntl_portclasses[0] = fsys_port_class;
+ argp_parse (&argp, argc, argv, 0, 0, 0);
task_get_bootstrap_port (mach_task_self (), &bootstrap);
if (bootstrap == MACH_PORT_NULL)
- error(1, 0, "must be started as a translator");
+ error (1, 0, "must be started as a translator");
/* Reply to our parent */
- err = trivfs_startup(bootstrap, 0,
- fsys_port_class, port_bucket,
- fifo_port_class, port_bucket,
- NULL);
+ err = trivfs_startup (bootstrap, 0, 0, 0, 0, 0, &fsys);
+ mach_port_deallocate (mach_task_self (), bootstrap);
if (err)
- error(3, err, "Contacting parent");
+ error (3, err, "Contacting parent");
/* Launch. */
do
{
- ports_enable_class (fifo_port_class);
- ports_manage_port_operations_multithread (port_bucket,
+ ports_enable_class (fsys->protid_class);
+ ports_manage_port_operations_multithread (fsys->pi.bucket,
trivfs_demuxer,
- 30*1000, 5*60*1000, 0, 0);
+ 30*1000, 5*60*1000, 0);
}
- while (ports_count_class (fifo_port_class) > 0);
+ while (ports_count_class (fsys->protid_class) > 0);
- exit(0);
+ return 0;
}
/* ---------------------------------------------------------------- */
@@ -163,15 +124,17 @@ open_hook (struct trivfs_peropen *po)
mutex_lock (&active_fifo_lock);
/* Wait until the active fifo has changed so that CONDITION is true. */
-#define WAIT(condition, noblock_err) \
- while (!err && !(condition)) \
- if (flags & O_NONBLOCK) \
- { \
- err = noblock_err; \
- break; \
- } \
- else if (hurd_condition_wait (&active_fifo_changed, &active_fifo_lock)) \
- err = EINTR;
+#define WAIT(condition, noblock_err) \
+ while (!err && !(condition)) \
+ { \
+ if (flags & O_NONBLOCK) \
+ { \
+ err = noblock_err; \
+ break; \
+ } \
+ else if (hurd_condition_wait (&active_fifo_changed, &active_fifo_lock)) \
+ err = EINTR; \
+ }
if (flags & O_READ)
/* When opening for read, what we do depends on what mode this server
@@ -354,13 +317,14 @@ trivfs_goaway (struct trivfs_control *cntl, int flags)
mapping; they will set none of the ports and return an error. Such
objects can still be accessed by io_read and io_write. */
error_t
-trivfs_S_io_map(struct trivfs_protid *cred,
- memory_object_t *rdobj,
- mach_msg_type_name_t *rdtype,
- memory_object_t *wrobj,
- mach_msg_type_name_t *wrtype)
+trivfs_S_io_map (struct trivfs_protid *cred,
+ mach_port_t reply, mach_msg_type_name_t replytype,
+ memory_object_t *rdobj,
+ mach_msg_type_name_t *rdtype,
+ memory_object_t *wrobj,
+ mach_msg_type_name_t *wrtype)
{
- return EINVAL;
+ return EOPNOTSUPP;
}
/* ---------------------------------------------------------------- */
@@ -443,7 +407,7 @@ trivfs_S_io_seek (struct trivfs_protid *cred,
error_t
trivfs_S_io_select (struct trivfs_protid *cred,
mach_port_t reply, mach_msg_type_name_t reply_type,
- int *select_type, int *tag)
+ int *select_type)
{
struct pipe *pipe;
error_t err = 0;
@@ -455,26 +419,30 @@ trivfs_S_io_select (struct trivfs_protid *cred,
pipe = cred->po->hook;
if (*select_type & SELECT_READ)
- if (cred->po->openmodes & O_READ)
- {
- mutex_lock (&pipe->lock);
- if (pipe_wait_readable (pipe, 1, 1) != EWOULDBLOCK)
- ready |= SELECT_READ; /* Data immediately readable (or error). */
- mutex_unlock (&pipe->lock);
- }
- else
- ready |= SELECT_READ; /* Error immediately available... */
+ {
+ if (cred->po->openmodes & O_READ)
+ {
+ mutex_lock (&pipe->lock);
+ if (pipe_wait_readable (pipe, 1, 1) != EWOULDBLOCK)
+ ready |= SELECT_READ; /* Data immediately readable (or error). */
+ mutex_unlock (&pipe->lock);
+ }
+ else
+ ready |= SELECT_READ; /* Error immediately available... */
+ }
if (*select_type & SELECT_WRITE)
- if (cred->po->openmodes & O_WRITE)
- {
- mutex_lock (&pipe->lock);
- if (pipe_wait_writable (pipe, 1) != EWOULDBLOCK)
- ready |= SELECT_WRITE; /* Data immediately writable (or error). */
- mutex_unlock (&pipe->lock);
- }
- else
- ready |= SELECT_WRITE; /* Error immediately available... */
+ {
+ if (cred->po->openmodes & O_WRITE)
+ {
+ mutex_lock (&pipe->lock);
+ if (pipe_wait_writable (pipe, 1) != EWOULDBLOCK)
+ ready |= SELECT_WRITE; /* Data immediately writable (or error). */
+ mutex_unlock (&pipe->lock);
+ }
+ else
+ ready |= SELECT_WRITE; /* Error immediately available... */
+ }
if (ready)
*select_type = ready;
@@ -539,7 +507,7 @@ trivfs_S_file_set_size (struct trivfs_protid *cred,
/* These four routines modify the O_APPEND, O_ASYNC, O_FSYNC, and
O_NONBLOCK bits for the IO object. In addition, io_get_openmodes
will tell you which of O_READ, O_WRITE, and O_EXEC the object can
- be used for. The O_ASYNC bit affects icky async I/O; good async
+ be used for. The O_ASYNC bit affects icky async I/O; good async
I/O is done through io_async which is orthogonal to these calls. */
error_t