summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1996-05-29 20:50:40 +0000
committerMiles Bader <miles@gnu.org>1996-05-29 20:50:40 +0000
commit3ca0dd1b80abe4ec13fec5ea8a8d62ea3b7e80aa (patch)
tree6851085f3d6156ba9ae44e59680ed063a9bc2305
parente3889fcd1bfa90420eaf0b99ba1c5a4aae8f089c (diff)
Initial revision
-rw-r--r--trans/devport.c185
1 files changed, 185 insertions, 0 deletions
diff --git a/trans/devport.c b/trans/devport.c
new file mode 100644
index 00000000..a6dfe7f8
--- /dev/null
+++ b/trans/devport.c
@@ -0,0 +1,185 @@
+/* A really stupid translator allowing a user to get a device port
+
+ Copyright (C) 1996 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <error.h>
+#include <string.h>
+
+#include <hurd.h>
+#include <hurd/ports.h>
+#include <hurd/trivfs.h>
+#include <hurd/fsys.h>
+
+#include <device/device.h>
+
+static mach_port_t device_master = MACH_PORT_NULL;
+static char *device_name = 0;
+
+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
+main (int argc, char **argv)
+{
+ error_t err;
+ mach_port_t bootstrap;
+ struct port_class *control_class;
+ struct port_class *node_class;
+ struct port_bucket *port_bucket;
+
+ 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;
+
+ if (argc != 2)
+ {
+ fprintf (stderr, "Usage: %s DEVICE-NAME", program_invocation_name);
+ exit(1);
+ }
+
+ device_name = argv[1];
+
+ task_get_bootstrap_port (mach_task_self (), &bootstrap);
+ if (bootstrap == MACH_PORT_NULL)
+ error (1, 0, "must be started as a translator");
+
+ err = get_privileged_ports (0, &device_master);
+ if (err)
+ error (2, err, "Can't get device master port");
+
+ /* Reply to our parent */
+ err = trivfs_startup (bootstrap, 0, control_class, port_bucket,
+ node_class, port_bucket, NULL);
+ if (err)
+ error (3, err, "Contacting parent");
+
+ /* Launch. */
+ ports_manage_port_operations_one_thread (port_bucket, trivfs_demuxer, 0);
+
+ exit(0);
+}
+
+/* Trivfs hooks */
+
+int trivfs_fstype = FSTYPE_DEV;
+int trivfs_fsid = 0;
+
+int trivfs_support_read = 0;
+int trivfs_support_write = 0;
+int trivfs_support_exec = 0;
+
+int trivfs_allow_open = 0;
+
+void
+trivfs_modify_stat (struct trivfs_protid *cred, struct stat *st)
+{
+ st->st_size = 0;
+ st->st_blocks = 0;
+ st->st_mode &= ~S_IFMT;
+ st->st_mode |= S_IFCHR;
+}
+
+error_t
+trivfs_goaway (struct trivfs_control *fsys, int flags)
+{
+ exit (0);
+}
+
+error_t
+trivfs_S_file_get_storage_info (struct trivfs_protid *cred,
+ mach_port_t reply,
+ mach_msg_type_name_t reply_type,
+ mach_port_t **ports,
+ mach_msg_type_name_t *ports_type,
+ mach_msg_type_number_t *num_ports,
+ int **ints, mach_msg_type_number_t *num_ints,
+ off_t **offsets,
+ mach_msg_type_number_t *num_offsets,
+ char **data, mach_msg_type_number_t *data_len)
+{
+ error_t err = 0;
+
+ if (!cred)
+ err = EOPNOTSUPP;
+ else
+ {
+ /* True when we've allocated memory for the corresponding vector. */
+ int al_ports = 0, al_ints = 0, al_offsets = 0, al_data = 0;
+ size_t name_len = strlen (device_name) + 1;
+
+#define ENSURE_MEM(v, vl, alp, num) \
+ if (!err && *vl < num) \
+ { \
+ err = vm_allocate (mach_task_self (), \
+ (vm_address_t *)v, num * sizeof (**v), 1); \
+ if (! err) \
+ { \
+ *vl = num; \
+ alp = 1; \
+ } \
+ }
+
+ ENSURE_MEM (ports, num_ports, al_ports, 1);
+ ENSURE_MEM (ints, num_ints, al_ints, 6);
+ ENSURE_MEM (offsets, num_offsets, al_offsets, 0);
+ ENSURE_MEM (data, data_len, al_data, name_len);
+
+ if (! err)
+ err = device_open (device_master, 0, device_name, *ports);
+
+ if (! err)
+ {
+ (*ints)[0] = STORAGE_DEVICE; /* type */
+ (*ints)[1] = 0; /* flags */
+ (*ints)[2] = 0; /* block_size */
+ (*ints)[3] = 0; /* num_runs */
+ (*ints)[4] = name_len; /* name_len */
+ (*ints)[5] = 0; /* misc_len */
+ *num_ints = 6;
+
+ strcpy (*data, device_name);
+ *data_len = name_len;
+
+ *num_ports = 1;
+ *ports_type = MACH_MSG_TYPE_MOVE_SEND;
+
+ *num_offsets = 0;
+ }
+ else
+ /* Some memory allocation failed (not bloody likely). */
+ {
+#define DISCARD_MEM(v, vl, alp) \
+ if (alp) \
+ vm_deallocate (mach_task_self (), (vm_address_t)*v, *vl * sizeof (**v));
+
+ DISCARD_MEM (ports, num_ports, al_ports);
+ DISCARD_MEM (ints, num_ints, al_ints);
+ DISCARD_MEM (offsets, num_offsets, al_offsets);
+ DISCARD_MEM (data, data_len, al_data);
+ }
+ }
+
+ return err;
+}