aboutsummaryrefslogtreecommitdiff
path: root/trans/null.c
diff options
context:
space:
mode:
Diffstat (limited to 'trans/null.c')
-rw-r--r--trans/null.c142
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