diff options
Diffstat (limited to 'trans/fifo.c')
-rw-r--r-- | trans/fifo.c | 188 |
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 |