diff options
Diffstat (limited to 'trans/null.c')
-rw-r--r-- | trans/null.c | 142 |
1 files changed, 60 insertions, 82 deletions
diff --git a/trans/null.c b/trans/null.c index f972d4a1..9673a758 100644 --- a/trans/null.c +++ b/trans/null.c @@ -1,8 +1,7 @@ /* A translator for providing endless empty space and immediate eof. - Copyright (C) 1995 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> + Copyright (C) 1995,96,97,98,99,2001,02,03 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 @@ -22,67 +21,70 @@ #include <hurd/ports.h> #include <hurd/trivfs.h> #include <hurd/fsys.h> +#include <version.h> #include <stdio.h> +#include <stdlib.h> #include <unistd.h> #include <error.h> #include <string.h> #include <fcntl.h> #include <limits.h> +#include <argp.h> -/* ---------------------------------------------------------------- */ +const char *argp_program_version = STANDARD_HURD_VERSION (null); -struct port_class *control_class; -struct port_class *node_class; -struct port_bucket *port_bucket; +/* Error code to return for write attempts. + If zero, they succeed in writing to the bitbucket. */ +static error_t write_error_code; -struct port_class *trivfs_protid_portclasses[1]; -struct port_class *trivfs_cntl_portclasses[1]; -int trivfs_protid_nportclasses = 1; -int trivfs_cntl_nportclasses = 1; +static const struct argp_option options[] = +{ + {"full", 'f', 0, 0, "Cause writes to fail as if to a full disk"}, + {0} +}; -/* If true, then reading from this device will yield an endless stream of - zeros instead of immediate EOF. This also makes it mappable. */ -static int provide_zeros = 0; +static error_t +parse_opt (int opt, char *arg, struct argp_state *state) +{ + switch (opt) + { + case 'f': + write_error_code = ENOSPC; + return 0; + } + return ARGP_ERR_UNKNOWN; +} -void +static const struct argp argp = +{ options, parse_opt, 0, "Endless sink and null source" }; + +int main (int argc, char **argv) { error_t err; mach_port_t bootstrap; - - control_class = ports_create_class (trivfs_clean_cntl, 0); - node_class = ports_create_class (trivfs_clean_protid, 0); - port_bucket = ports_create_bucket (); - trivfs_protid_portclasses[0] = node_class; - trivfs_cntl_portclasses[0] = control_class; + struct trivfs_control *fsys; - if (argc == 2 && - (strcmp(argv[1], "-z") == 0 || strcmp(argv[1], "--zero") == 0)) - provide_zeros = 1; - else if (argc != 1) - { - fprintf(stderr, "Usage: %s [-z|--zero]", program_invocation_name); - exit(1); - } + 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, control_class, port_bucket, - node_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"); /* Launch. */ - ports_manage_port_operations_one_thread (port_bucket, trivfs_demuxer, 0); + ports_manage_port_operations_multithread (fsys->pi.bucket, trivfs_demuxer, + 2 * 60 * 1000, 0, 0); - exit(0); + return 0; } -/* ---------------------------------------------------------------- */ /* Trivfs hooks */ int trivfs_fstype = FSTYPE_DEV; @@ -109,11 +111,9 @@ trivfs_modify_stat (struct trivfs_protid *cred, struct stat *st) error_t trivfs_goaway (struct trivfs_control *fsys, int flags) { - exit(0); + exit (0); } -/* ---------------------------------------------------------------- */ - /* Return objects mapping the data underlying this memory object. If the object can be read then memobjrd will be provided; if the object can be written then memobjwr will be provided. For objects @@ -123,50 +123,38 @@ trivfs_goaway (struct trivfs_control *fsys, 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. */ kern_return_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; /* XXX should work! */ + return EOPNOTSUPP; /* XXX should work! */ } -/* ---------------------------------------------------------------- */ - /* Read data from an IO object. If offset if -1, read from the object maintained file pointer. If the object is not seekable, offset is ignored. The amount desired to be read is in AMT. */ kern_return_t trivfs_S_io_read(struct trivfs_protid *cred, mach_port_t reply, mach_msg_type_name_t replytype, - vm_address_t *data, + char **data, mach_msg_type_number_t *datalen, - off_t offs, + loff_t offs, mach_msg_type_number_t amt) { - error_t err = 0; - if (!cred) - err = EOPNOTSUPP; + return EOPNOTSUPP; else if (!(cred->po->openmodes & O_READ)) - err = EBADF; - else if (provide_zeros) + return EBADF; + else { - if (amt > *datalen) - err = vm_allocate(mach_task_self(), data, amt, 1); - else - bzero((void *)*data, amt); - *datalen = amt; + *datalen = 0; + return 0; } - else - *datalen = 0; - - return 0; } -/* ---------------------------------------------------------------- */ - /* 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. */ @@ -179,15 +167,11 @@ trivfs_S_io_readable (struct trivfs_protid *cred, return EOPNOTSUPP; else if (!(cred->po->openmodes & O_READ)) return EINVAL; - else if (provide_zeros) - *amount = INT_MAX; else *amount = 0; return 0; } -/* ---------------------------------------------------------------- */ - /* Change current read/write offset */ kern_return_t trivfs_S_io_seek (struct trivfs_protid *cred, @@ -200,8 +184,6 @@ trivfs_S_io_seek (struct trivfs_protid *cred, return 0; } -/* ---------------------------------------------------------------- */ - /* SELECT_TYPE is the bitwise OR of SELECT_READ, SELECT_WRITE, and SELECT_URG. Block until one of the indicated types of i/o can be done "quickly", and return the types that are then available. ID_TAG is returned as passed; it @@ -210,7 +192,7 @@ trivfs_S_io_seek (struct trivfs_protid *cred, kern_return_t trivfs_S_io_select (struct trivfs_protid *cred, mach_port_t reply, mach_msg_type_name_t replytype, - int *type, int *tag) + int *type) { if (!cred) return EOPNOTSUPP; @@ -222,8 +204,6 @@ trivfs_S_io_select (struct trivfs_protid *cred, return 0; } -/* ---------------------------------------------------------------- */ - /* Write data to an IO object. If offset is -1, write at the object maintained file pointer. If the object is not seekable, offset is ignored. The amount successfully written is returned in amount. A @@ -234,31 +214,30 @@ trivfs_S_io_select (struct trivfs_protid *cred, kern_return_t trivfs_S_io_write (struct trivfs_protid *cred, mach_port_t reply, mach_msg_type_name_t replytype, - vm_address_t data, mach_msg_type_number_t datalen, - off_t offs, mach_msg_type_number_t *amt) + char *data, mach_msg_type_number_t datalen, + loff_t offs, mach_msg_type_number_t *amt) { if (!cred) return EOPNOTSUPP; else if (!(cred->po->openmodes & O_WRITE)) return EBADF; *amt = datalen; - return 0; + return write_error_code; } -/* ---------------------------------------------------------------- */ - /* Truncate file. */ kern_return_t -trivfs_S_file_set_size (struct trivfs_protid *cred, off_t size) +trivfs_S_file_set_size (struct trivfs_protid *cred, + mach_port_t reply, mach_msg_type_name_t replytype, + loff_t size) { return 0; } -/* ---------------------------------------------------------------- */ /* 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. */ kern_return_t @@ -311,7 +290,6 @@ trivfs_S_io_clear_some_openmodes (struct trivfs_protid *cred, return 0; } -/* ---------------------------------------------------------------- */ /* Get/set the owner of the IO object. For terminals, this affects controlling terminal behavior (see term_become_ctty). For all objects this affects old-style async IO. Negative values represent |