summaryrefslogtreecommitdiff
path: root/devnode
diff options
context:
space:
mode:
Diffstat (limited to 'devnode')
-rw-r--r--devnode/ChangeLog~25
-rw-r--r--devnode/README~25
-rw-r--r--devnode/devnode.c27
-rw-r--r--devnode/devnode.c~337
4 files changed, 26 insertions, 388 deletions
diff --git a/devnode/ChangeLog~ b/devnode/ChangeLog~
deleted file mode 100644
index 5efa8a5e..00000000
--- a/devnode/ChangeLog~
+++ /dev/null
@@ -1,25 +0,0 @@
-2008-08-28 Zheng Da <zhengda1936@gmail.com>
-
- * devnode.c (ds_device_open): Return the error instead of stopping the
- translator.
-
-2008-08-20 Zheng Da <zhengda1936@gmail.com>
-
- * devnode.c (ds_device_open): Test device_name before using it.
-
- * util.h (DEBUG): Remove the macro.
-
-2008-08-18 Zheng Da <zhengda1936@gmail.com>
-
- * README: New file.
-
- * devnode.c (options): Replace the option '-i' with '-d'.
- (parse_opt): Handle the option '-d'.
-
-2008-08-17 Zheng Da <zhengda1936@gmail.com>
-
- * Makefile: New file.
-
- * util.h: New file.
-
- * devnode.c: New file.
diff --git a/devnode/README~ b/devnode/README~
deleted file mode 100644
index 5686da7b..00000000
--- a/devnode/README~
+++ /dev/null
@@ -1,25 +0,0 @@
-[Introduction]
-
-devnode is a translator that creates the device file for the kernel device. It provides another way for other programs to open the kernel device.
-The device file should be created in /dev with the device name as its file name, so clients can find the device file easily.
-Clients need to get the port to the devnode translator by calling file_name_lookup() and uses this port as a master device port to open the device by calling device_open(). The device name used in device_open() is specified by '-n' option of devnode.
-
-
-[Usage]
-
-Usage: devnode [OPTION...] device
-Hurd devnode translator.
-
- -n, --name=DEVICENAME Accept open from clients only with DEVICENAME
- -M, --master_device=FILE Get a pseudo master device port
- -?, --help Give this help list
- --usage Give a short usage message
- -V, --version Print program version
-
-The '-n' option specifies the device name used by clients in device_open(). It can be optional. If it's specified, clients must use the name to open the device. Otherwise, every device name used by clients in device_open() is acceptable.
-The '-M' option specifies the file where devnode can get the master device port. This option can be useful to open the virtual interface created by eth-multiplexer, for example.
-
-
-[Internal]
-
-devnode is very simple. It implements the server side functions in device.defs, so it can receive the request of opening a device from other programs. Only ds_device_open is actually implemented, which opens the device and returns the port to the device. Normally, devnode shouldn't get other requests.
diff --git a/devnode/devnode.c b/devnode/devnode.c
index 7abf2bf8..299de3c3 100644
--- a/devnode/devnode.c
+++ b/devnode/devnode.c
@@ -27,6 +27,7 @@
#include <errno.h>
#include <error.h>
#include <stddef.h>
+#include <fcntl.h>
#include <hurd.h>
#include <mach.h>
@@ -42,6 +43,7 @@
static char *device_name;
/* The device name used by the socket servers. */
static char *user_device_name;
+static char *master_file;
/* The master device port for opening the interface. */
static mach_port_t master_device;
@@ -67,7 +69,7 @@ int trivfs_fsid = 0;
int trivfs_support_read = 0;
int trivfs_support_write = 0;
int trivfs_support_exec = 0;
-int trivfs_allow_open = 0;
+int trivfs_allow_open = O_READ | O_WRITE;
struct port_class *trivfs_protid_portclasses[1];
struct port_class *trivfs_cntl_portclasses[1];
@@ -237,6 +239,28 @@ ds_device_set_filter (device_t device, mach_port_t receive_port,
return D_INVALID_OPERATION;
}
+error_t
+trivfs_append_args (struct trivfs_control *fsys, char **argz, size_t *argz_len)
+{
+ error_t err = 0;
+
+#define ADD_OPT(fmt, args...) \
+ do { char buf[100]; \
+ if (! err) { \
+ snprintf (buf, sizeof buf, fmt , ##args); \
+ err = argz_add (argz, argz_len, buf); } } while (0)
+
+ if (user_device_name)
+ ADD_OPT ("--name=%s", user_device_name);
+ if (master_file)
+ ADD_OPT ("--master-device=%s", master_file);
+
+ ADD_OPT (device_name);
+
+#undef ADD_OPT
+ return err;
+}
+
void
trivfs_modify_stat (struct trivfs_protid *cred, io_statbuf_t *stat)
{
@@ -274,6 +298,7 @@ parse_opt (int opt, char *arg, struct argp_state *state)
switch (opt)
{
case 'M':
+ master_file = arg;
master_device = file_name_lookup (arg, 0, 0);
if (master_device == MACH_PORT_NULL)
error (1, errno, "file_name_lookup");
diff --git a/devnode/devnode.c~ b/devnode/devnode.c~
deleted file mode 100644
index 5b85fcb5..00000000
--- a/devnode/devnode.c~
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- Copyright (C) 2008 Free Software Foundation, Inc.
- Written by Zheng Da.
-
- This file is part of the GNU Hurd.
-
- The GNU Hurd 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.
-
- The GNU Hurd 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 the GNU Hurd; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/*
- * This program is a translator that sits on the top of the network
- * interface and helps socket servers open the interface.
- */
-
-#include <argp.h>
-#include <errno.h>
-#include <error.h>
-#include <stddef.h>
-
-#include <hurd.h>
-#include <mach.h>
-#include <device/device.h>
-#include <hurd/trivfs.h>
-#include <hurd/ports.h>
-
-#include "ourdevice_S.h"
-#include "notify_S.h"
-#include "util.h"
-
-/* The name of the network interface that the translator sits on. */
-static char *device_name;
-/* The device name used by the socket servers. */
-static char *user_device_name;
-/* The master device port for opening the interface. */
-static mach_port_t master_device;
-
-const char *argp_program_version = "devnode 0.1";
-const char *argp_program_bug_address = "<bug-hurd@gnu.org>";
-static const char args_doc[] = "device";
-static const char doc[] = "Hurd devnode translator.";
-static const struct argp_option options[] =
-{
- {"name", 'n', "DEVICENAME", 0,
- "The device name used by clients in device_open()", 2},
- {"master-device", 'M', "FILE", 0,
- "Get a pseudo master device port", 3},
- {0}
-};
-
-/* Port bucket we service requests on. */
-struct port_bucket *port_bucket;
-
-/* Trivfs hooks. */
-int trivfs_fstype = FSTYPE_MISC;
-int trivfs_fsid = 0;
-int trivfs_support_read = 0;
-int trivfs_support_write = 0;
-int trivfs_support_exec = 0;
-int trivfs_allow_open = 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;
-
-static int
-devnode_demuxer (mach_msg_header_t *inp,
- mach_msg_header_t *outp)
-{
- extern int device_server (mach_msg_header_t *, mach_msg_header_t *);
- extern int notify_server (mach_msg_header_t *, mach_msg_header_t *);
- return device_server (inp, outp) || notify_server (inp, outp)
- || trivfs_demuxer (inp, outp);
-}
-
-/* Implementation of notify interface */
-kern_return_t
-do_mach_notify_port_deleted (mach_port_t notify,
- mach_port_t name)
-{
- return EOPNOTSUPP;
-}
-
-kern_return_t
-do_mach_notify_msg_accepted (mach_port_t notify,
- mach_port_t name)
-{
- return EOPNOTSUPP;
-}
-
-kern_return_t
-do_mach_notify_port_destroyed (mach_port_t notify,
- mach_port_t port)
-{
- return EOPNOTSUPP;
-}
-
-kern_return_t
-do_mach_notify_no_senders (mach_port_t notify,
- mach_port_mscount_t mscount)
-{
- return ports_do_mach_notify_no_senders (notify, mscount);
-}
-
-kern_return_t
-do_mach_notify_send_once (mach_port_t notify)
-{
- return EOPNOTSUPP;
-}
-
-kern_return_t
-do_mach_notify_dead_name (mach_port_t notify,
- mach_port_t name)
-{
- return EOPNOTSUPP;
-}
-
-/* Implementation of device interface */
-kern_return_t
-ds_xxx_device_set_status (device_t device, dev_flavor_t flavor,
- dev_status_t status, size_t statu_cnt)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_xxx_device_get_status (device_t device, dev_flavor_t flavor,
- dev_status_t status, size_t *statuscnt)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_xxx_device_set_filter (device_t device, mach_port_t rec,
- int pri, filter_array_t filt, size_t len)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_device_open (mach_port_t master_port, mach_port_t reply_port,
- mach_msg_type_name_t reply_portPoly,
- dev_mode_t mode, dev_name_t name, mach_port_t *device,
- mach_msg_type_name_t *devicetype)
-{
- error_t err;
-
- debug ("ds_device_open is called\n");
-
- if ((user_device_name && strcmp (user_device_name, name))
- || device_name == NULL)
- return D_NO_SUCH_DEVICE;
-
- err = device_open (master_device, mode, device_name, device);
- *devicetype = MACH_MSG_TYPE_MOVE_SEND;
- return err;
-}
-
-kern_return_t
-ds_device_close (device_t device)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_device_write (device_t device, mach_port_t reply_port,
- mach_msg_type_name_t reply_type, dev_mode_t mode,
- recnum_t recnum, io_buf_ptr_t data, size_t datalen,
- int *bytes_written)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_device_write_inband (device_t device, mach_port_t reply_port,
- mach_msg_type_name_t reply_type, dev_mode_t mode,
- recnum_t recnum, io_buf_ptr_inband_t data,
- size_t datalen, int *bytes_written)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_device_read (device_t device, mach_port_t reply_port,
- mach_msg_type_name_t reply_type, dev_mode_t mode,
- recnum_t recnum, int bytes_wanted,
- io_buf_ptr_t *data, size_t *datalen)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_device_read_inband (device_t device, mach_port_t reply_port,
- mach_msg_type_name_t reply_type, dev_mode_t mode,
- recnum_t recnum, int bytes_wanted,
- io_buf_ptr_inband_t data, size_t *datalen)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_device_map (device_t device, vm_prot_t prot, vm_offset_t offset,
- vm_size_t size, memory_object_t *pager, int unmap)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_device_set_status (device_t device, dev_flavor_t flavor,
- dev_status_t status, size_t statuslen)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_device_get_status (device_t device, dev_flavor_t flavor,
- dev_status_t status, size_t *statuslen)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_device_set_filter (device_t device, mach_port_t receive_port,
- int priority, filter_array_t filter, size_t filterlen)
-{
- return D_INVALID_OPERATION;
-}
-
-void
-trivfs_modify_stat (struct trivfs_protid *cred, io_statbuf_t *stat)
-{
-}
-
-error_t
-trivfs_goaway (struct trivfs_control *fsys, int flags)
-{
- int count;
-
- /* Stop new requests. */
- ports_inhibit_class_rpcs (trivfs_cntl_portclasses[0]);
- ports_inhibit_class_rpcs (trivfs_protid_portclasses[0]);
-
- count = ports_count_class (trivfs_protid_portclasses[0]);
- debug ("the number of ports alive: %d\n", count);
-
- if (count && !(flags & FSYS_GOAWAY_FORCE))
- {
- /* We won't go away, so start things going again... */
- ports_enable_class (trivfs_protid_portclasses[0]);
- ports_resume_class_rpcs (trivfs_cntl_portclasses[0]);
- ports_resume_class_rpcs (trivfs_protid_portclasses[0]);
- return EBUSY;
- }
-
- mach_port_deallocate (mach_task_self (), master_device);
- debug ("the translator is gone away\n");
- exit (0);
-}
-
-static error_t
-parse_opt (int opt, char *arg, struct argp_state *state)
-{
- switch (opt)
- {
- case 'M':
- master_device = file_name_lookup (arg, 0, 0);
- if (master_device == MACH_PORT_NULL)
- error (1, errno, "file_name_lookup");
- break;
- case 'n':
- user_device_name = arg;
- break;
- case ARGP_KEY_ARG:
- device_name = arg;
- break;
- case ARGP_KEY_ERROR:
- case ARGP_KEY_SUCCESS:
- case ARGP_KEY_INIT:
- break;
- default:
- return ARGP_ERR_UNKNOWN;
- }
- return 0;
-}
-
-int
-main (int argc, char *argv[])
-{
- error_t err;
- mach_port_t bootstrap;
- struct trivfs_control *fsys;
- const struct argp argp = { options, parse_opt, args_doc, doc };
-
- port_bucket = ports_create_bucket ();
- trivfs_cntl_portclasses[0] = ports_create_class (trivfs_clean_cntl, 0);
- trivfs_protid_portclasses[0] = ports_create_class (trivfs_clean_protid, 0);
-
- 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");
-
- if (master_device == MACH_PORT_NULL)
- {
- err = get_privileged_ports (0, &master_device);
- if (err)
- error (1, err, "get_privileged_ports");
- }
-
- /* Reply to our parent. */
- err = trivfs_startup (bootstrap, 0,
- trivfs_cntl_portclasses[0], port_bucket,
- trivfs_protid_portclasses[0], port_bucket, &fsys);
- mach_port_deallocate (mach_task_self (), bootstrap);
- if (err)
- error (1, err, "Contacting parent");
-
- /* Launch. */
- do
- {
- ports_manage_port_operations_one_thread (port_bucket,
- devnode_demuxer, 0);
- } while (trivfs_goaway (fsys, 0));
- return 0;
-}