Hi,
The hurd console, by nature, is already very well accessible, there is
only one missing bit: applications to be able to know which console
console-client is currently showing, and to be able to switch consoles.
We've been discussing about it for some time on #hurd (or ##hurd), and
here is a patch to extend Marco's console repeater translator to handle
symlinks, and a vcs repeater that adds a symlink to the currently showed
console. One can switch console by mksymlink()ing it.
Changelog for console-client/:
2005-03-05 Samuel Thibault <[EMAIL PROTECTED]>
* Makefile (modules): Add `vcs_repeat' and its rule.
* console.c (console_current_id): New function.
* input.h (console_current_id): New prototype.
* trans.c (struct netnode): New member `symlink_path'.
(console_demuxer): Handle case when node it anonymous.
(netfs_S_io_select): Likewise.
(netfs_S_io_read): Likewise.
(netfs_S_io_write): Likewise.
(netfs_report_access): Likewise.
(netfs_attempt_mksymlink): Implement symlinks.
(netfs_attempt_lookup): Likewise.
(netfs_attempt_unlink): Likewise.
(netfs_attempt_link): Likewise.
(netfs_attempt_mkfile): Likewise.
(netfs_attempt_readlink): Likewise.
(netfs_get_dirents): Likewise.
(netfs_create_consnode): Likewise.
* trans.h (struct consnode): New members `readlink' and `mksymlink'.
* vcs-repeat.c: New file.
Changelog for libcons/:
2005-03-05 Samuel Thibault <[EMAIL PROTECTED]>
* priv.h (_cons_file): Prototype moved and renamed to...
* cons.h (cons_file): ... this.
* init-init.c (cons_init): Updated `_cons_file' reference.
* opts-std-startup.c (_cons_file): Renamed into `cons_file'. Updated
reference.
Regards,
Samuel
Index: console-client/ChangeLog
===================================================================
RCS file: /cvsroot/hurd/hurd/console-client/ChangeLog,v
retrieving revision 1.22
diff -u -u -p -r1.22 ChangeLog
--- console-client/ChangeLog 17 Jan 2005 02:00:00 -0000 1.22
+++ console-client/ChangeLog 5 Mar 2005 15:52:59 -0000
@@ -1,3 +1,25 @@
+2005-03-05 Samuel Thibault <[EMAIL PROTECTED]>
+
+ * Makefile (modules): Add `vcs_repeat' and its rule.
+ * console.c (console_current_id): New function.
+ * input.h (console_current_id): New prototype.
+ * trans.c (struct netnode): New member `symlink_path'.
+ (console_demuxer): Handle case when node it anonymous.
+ (netfs_S_io_select): Likewise.
+ (netfs_S_io_read): Likewise.
+ (netfs_S_io_write): Likewise.
+ (netfs_report_access): Likewise.
+ (netfs_attempt_mksymlink): Implement symlinks.
+ (netfs_attempt_lookup): Likewise.
+ (netfs_attempt_unlink): Likewise.
+ (netfs_attempt_link): Likewise.
+ (netfs_attempt_mkfile): Likewise.
+ (netfs_attempt_readlink): Likewise.
+ (netfs_get_dirents): Likewise.
+ (netfs_create_consnode): Likewise.
+ * trans.h (struct consnode): New members `readlink' and `mksymlink'.
+ * vcs-repeat.c: New file.
+
2005-01-10 Alfred M. Szmidt <[EMAIL PROTECTED]>
* console.c (consnode_path): Renamed to ...
Index: console-client/Makefile
===================================================================
RCS file: /cvsroot/hurd/hurd/console-client/Makefile,v
retrieving revision 1.3
diff -u -u -p -r1.3 Makefile
--- console-client/Makefile 6 Jan 2005 21:43:53 -0000 1.3
+++ console-client/Makefile 5 Mar 2005 15:52:59 -0000
@@ -41,7 +41,7 @@ driver-CPPFLAGS = -D'CONSOLE_DEFPATH="$(
console: ../libcons/libcons.a ../libports/libports.a \
../libthreads/libthreads.a ../libshouldbeinlibc/libshouldbeinlibc.a
-modules = vga pc_kbd generic_speaker pc_mouse
+modules = vga pc_kbd generic_speaker pc_mouse vcs_repeat
vga-CPPFLAGS = -DDEFAULT_VGA_FONT_DIR=\"${datadir}/hurd/\"
vga.so.$(hurd-version): $(patsubst %.c,%_pic.o,bdf.c vga-dynafont.c \
@@ -49,6 +49,7 @@ vga.so.$(hurd-version): $(patsubst %.c,%
pc_kbd.so.$(hurd-version): $(patsubst %.c,%_pic.o,pc-kbd.c kdioctlServer.o
kbd-repeat.c)
pc_mouse.so.$(hurd-version): $(patsubst %.c,%_pic.o,pc-mouse.c)
generic_speaker.so.$(hurd-version): $(patsubst %.c,%_pic.o,generic-speaker.c)
+vcs_repeat.so.$(hurd-version): $(patsubst %.c,%_pic.o,vcs-repeat.c)
ifneq ($(LIBNCURSESW),)
modules += ncursesw
Index: console-client/console.c
===================================================================
RCS file: /cvsroot/hurd/hurd/console-client/console.c,v
retrieving revision 1.6
diff -u -u -p -r1.6 console.c
--- console-client/console.c 17 Jan 2005 02:00:00 -0000 1.6
+++ console-client/console.c 5 Mar 2005 15:52:59 -0000
@@ -64,6 +64,24 @@ static char *console_node;
/* Callbacks for input source drivers. */
+/* Returns current console ID. */
+error_t
+console_current_id (int *cur)
+{
+ vcons_t vcons;
+
+ mutex_lock (&global_lock);
+ vcons = active_vcons;
+ if (!vcons)
+ {
+ mutex_unlock (&global_lock);
+ return ENODEV;
+ }
+ *cur = vcons->id;
+ mutex_unlock (&global_lock);
+ return 0;
+}
+
/* Switch the active console to console ID or DELTA (relative to the
active console). */
error_t
Index: console-client/input.h
===================================================================
RCS file: /cvsroot/hurd/hurd/console-client/input.h,v
retrieving revision 1.2
diff -u -u -p -r1.2 input.h
--- console-client/input.h 6 Jan 2005 21:43:53 -0000 1.2
+++ console-client/input.h 5 Mar 2005 15:52:59 -0000
@@ -55,6 +55,9 @@ error_t console_input (char *buf, size_t
cons_vcons_scrollback. */
int console_scrollback (cons_scroll_t type, float value);
+/* Returns current console ID. */
+error_t console_current_id (int *cur);
+
/* Switch the active console to console ID or DELTA (relative to the
active console). */
error_t console_switch (int id, int delta);
Index: console-client/trans.c
===================================================================
RCS file: /cvsroot/hurd/hurd/console-client/trans.c,v
retrieving revision 1.1
diff -u -u -p -r1.1 trans.c
--- console-client/trans.c 6 Jan 2005 21:43:53 -0000 1.1
+++ console-client/trans.c 5 Mar 2005 15:52:59 -0000
@@ -41,6 +41,7 @@ static consnode_t node_list = 0;
struct netnode
{
consnode_t node;
+ char *symlink_path;
};
typedef mach_msg_header_t request_t;
@@ -69,7 +70,7 @@ console_demuxer (mach_msg_header_t *inp,
return 0;
}
- if (!ret && user->po->np->nn->node->demuxer)
+ if (!ret && user->po->np->nn->node && user->po->np->nn->node->demuxer)
ret = user->po->np->nn->node->demuxer (inp, outp);
ports_port_deref (user);
@@ -125,6 +126,15 @@ error_t
netfs_attempt_mksymlink (struct iouser *cred, struct node *np,
char *name)
{
+ if (!np->nn->node)
+ {
+ if (np->nn->symlink_path)
+ free (np->nn->symlink_path);
+ np->nn->symlink_path = strdup (name);
+ return 0;
+ }
+ else if (np->nn->node->mksymlink)
+ return np->nn->node->mksymlink (cred, np, name);
return EOPNOTSUPP;
}
@@ -272,8 +282,18 @@ netfs_attempt_lookup (struct iouser *use
nn->node = cn;
(*node)->nn_stat = netfs_root_node->nn_stat;
- (*node)->nn_stat.st_mode = S_IFCHR |
(netfs_root_node->nn_stat.st_mode & ~S_IFMT & ~S_ITRANS);
+ (*node)->nn_stat.st_mode = (netfs_root_node->nn_stat.st_mode &
~S_IFMT & ~S_ITRANS);
(*node)->nn_stat.st_ino = 5;
+ if (cn->readlink)
+ {
+ (*node)->nn_stat.st_mode |= S_IFLNK;
+ (*node)->nn_stat.st_size = cn->readlink (user, NULL, NULL);
+ }
+ else
+ {
+ (*node)->nn_stat.st_mode |= S_IFCHR;
+ (*node)->nn_stat.st_size = 0;
+ }
cn->node = *node;
goto out;
}
@@ -325,7 +345,7 @@ netfs_S_io_select (struct protid *user,
np = user->po->np;
- if (np->nn->node->select)
+ if (np->nn->node && np->nn->node->select)
return np->nn->node->select (user, reply, replytype, type);
return EOPNOTSUPP;
}
@@ -336,6 +356,21 @@ error_t
netfs_attempt_unlink (struct iouser *user, struct node *dir,
char *name)
{
+ error_t err;
+ consnode_t cn;
+
+ err = fshelp_access (&dir->nn_stat, S_IWRITE, user);
+ if (err)
+ return err;
+
+ for (cn = node_list; cn; cn = cn->next)
+ if (!strcmp (name, cn->name))
+ {
+ if (cn->mksymlink)
+ return 0;
+ else
+ break;
+ }
return EOPNOTSUPP;
}
@@ -378,6 +413,30 @@ error_t
netfs_attempt_link (struct iouser *user, struct node *dir,
struct node *file, char *name, int excl)
{
+ error_t err;
+ consnode_t cn;
+
+ err = fshelp_access (&dir->nn_stat, S_IWRITE, user);
+ if (err)
+ return err;
+
+ if (!file->nn->node && file->nn->symlink_path)
+ {
+ for (cn = node_list; cn; cn = cn->next)
+ if (!strcmp (name, cn->name))
+ {
+ if (cn->mksymlink)
+ {
+ file->nn->node = cn;
+ cn->mksymlink (user, file, file->nn->symlink_path);
+ free (file->nn->symlink_path);
+ file->nn->symlink_path = NULL;
+ return 0;
+ }
+ else
+ break;
+ }
+ }
return EOPNOTSUPP;
}
@@ -389,7 +448,27 @@ error_t
netfs_attempt_mkfile (struct iouser *user, struct node *dir,
mode_t mode, struct node **np)
{
- return EOPNOTSUPP;
+ error_t err;
+ struct netnode *nn;
+
+ mutex_unlock (&dir->lock);
+
+ err = fshelp_access (&dir->nn_stat, S_IWRITE, user);
+ if (err)
+ {
+ *np = 0;
+ return err;
+ }
+
+ nn = calloc (1, sizeof (*nn));
+ if (!nn)
+ return ENOMEM;
+
+ *np = netfs_make_node (nn);
+ mutex_lock (&(*np)->lock);
+ spin_unlock (&netfs_node_refcnt_lock);
+
+ return 0;
}
@@ -413,6 +492,8 @@ error_t
netfs_attempt_readlink (struct iouser *user, struct node *np,
char *buf)
{
+ if (np->nn->node && np->nn->node->readlink)
+ return np->nn->node->readlink (user, np, buf);
return EOPNOTSUPP;
}
@@ -471,7 +552,7 @@ netfs_S_io_read (struct protid *user,
return EOPNOTSUPP;
np = user->po->np;
- if (np->nn->node->read)
+ if (np->nn->node && np->nn->node->read)
return np->nn->node->read (user, data, datalen, offset, amount);
return EOPNOTSUPP;
}
@@ -490,7 +571,7 @@ netfs_S_io_write (struct protid *user,
return EOPNOTSUPP;
np = user->po->np;
- if (np->nn->node->read)
+ if (np->nn->node && np->nn->node->write)
return np->nn->node->write (user, data, datalen, offset, amount);
return EOPNOTSUPP;
}
@@ -517,9 +598,15 @@ netfs_report_access (struct iouser *cred
void netfs_node_norefs (struct node *np)
{
- if (np->nn->node->close)
- np->nn->node->close ();
- np->nn->node->node = 0;
+ if (np->nn->node)
+ {
+ if (np->nn->node->close)
+ np->nn->node->close ();
+ np->nn->node->node = 0;
+ }
+
+ if (np->nn->symlink_path)
+ free (np->nn->symlink_path);
spin_unlock (&netfs_node_refcnt_lock);
free (np->nn);
@@ -645,7 +732,7 @@ netfs_get_dirents (struct iouser *cred,
/* Fill in the real directory entries. */
for (cn = first_node; cn; cn = cn->next)
- if (!add_dir_entry (cn->name, cn->id, DT_CHR))
+ if (!add_dir_entry (cn->name, cn->id, cn->readlink ? DT_LNK : DT_CHR))
break;
}
@@ -689,6 +776,9 @@ console_create_consnode (const char *nam
return ENOMEM;
}
+ (*cn)->readlink = NULL;
+ (*cn)->mksymlink = NULL;
+
return 0;
}
Index: console-client/trans.h
===================================================================
RCS file: /cvsroot/hurd/hurd/console-client/trans.h,v
retrieving revision 1.1
diff -u -u -p -r1.1 trans.h
--- console-client/trans.h 6 Jan 2005 21:43:53 -0000 1.1
+++ console-client/trans.h 5 Mar 2005 15:53:00 -0000
@@ -54,6 +54,12 @@ struct consnode
/* The demuxer used for this node. */
int (*demuxer) (mach_msg_header_t *inp, mach_msg_header_t *outp);
+ /* Called when the symlink is read */
+ error_t (*readlink) (struct iouser *user, struct node *np, char *buf);
+
+ /* Called when the symlink is written */
+ error_t (*mksymlink) (struct iouser *cred, struct node *np, char *name);
+
struct consnode *next;
};
Index: console-client/vcs-repeat.c
===================================================================
RCS file: console-client/vcs-repeat.c
diff -N console-client/vcs-repeat.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ console-client/vcs-repeat.c 5 Mar 2005 15:53:00 -0000
@@ -0,0 +1,223 @@
+/* vcs-repeat.c -- Add a repeater for "current vcs" as a symlink in the
+ console translator node.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ Written by Samuel Thibault.
+
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <argp.h>
+#include <driver.h>
+#include <input.h>
+#include <stdio.h>
+#include <error.h>
+#include <sys/mman.h>
+
+#include "trans.h"
+
+
+/* The default name of the node of the repeater. */
+#define DEFAULT_REPEATER_NODE "vcs"
+
+/* The name of the repeater node. */
+static char *repeater_node;
+
+/* The repeater node. */
+static consnode_t vcs_node;
+
+
+/* Callbacks for vcs console node. */
+
+/* Reading the link to get current vcs, returns length of path (trailing \0
+ excluded). */
+static error_t
+vcs_readlink (struct iouser *user, struct node *np, char *buf)
+{
+ int cur;
+ error_t ret = 0;
+
+ ret = console_current_id (&cur);
+ if (!ret)
+ {
+ if (!buf)
+ ret = snprintf (NULL, 0, "%s/%d", cons_file, cur);
+ else
+ ret = sprintf (buf, "%s/%d", cons_file, cur);
+
+ if (ret < 0)
+ ret = errno;
+ }
+ return ret;
+}
+
+static error_t
+vcs_read (struct protid *user, char **data,
+ mach_msg_type_number_t * datalen, off_t offset,
+ mach_msg_type_number_t amount)
+{
+ int err;
+ int size;
+
+ if (amount > 0)
+ {
+ size = vcs_readlink (user->user, NULL, NULL);
+ if (size < 0)
+ return size;
+
+ {
+ char buf[size];
+
+ err = vcs_readlink (user->user, NULL, buf);
+
+ if (err < 0)
+ return err;
+
+ if (offset + amount > size)
+ amount = size - offset;
+ if (amount < 0)
+ amount = 0;
+
+ if (*datalen < amount)
+ {
+ *data = mmap (0, amount, PROT_READ | PROT_WRITE, MAP_ANON, 0, 0);
+ if (*data == MAP_FAILED)
+ return ENOMEM;
+ }
+
+ memcpy (*data, buf + offset, amount);
+ *datalen = amount;
+ }
+ }
+ return 0;
+}
+
+/* Making a link to set current vcs.
+ Relative values perform relative switches. */
+static error_t
+vcs_mksymlink (struct iouser *user, struct node *np, char *name)
+{
+ char *c, *d;
+ int vt, delta = 0;
+
+ c = strrchr (name, '/');
+ if (!c)
+ c = name;
+ else
+ c++;
+ if (!*c)
+ return EINVAL;
+
+ if (*c == '-' || *c == '+')
+ delta = 1;
+
+ vt = strtol (c, &d, 10);
+ if (*d)
+ /* Bad number. */
+ return EINVAL;
+
+ if (!vt)
+ return 0;
+ return console_switch (delta ? 0 : vt, delta ? vt : 0);
+}
+
+
+static const char doc[] = "VCS Repeater Driver";
+
+static const struct argp_option options[] =
+ {
+ { "repeater", 'r', "NODE", OPTION_ARG_OPTIONAL,
+ "Set a repeater translator on NODE (default: " DEFAULT_REPEATER_NODE
")"},
+ { 0 }
+ };
+
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+ int *pos = (int *) state->input;
+
+ switch (key)
+ {
+ case 'r':
+ repeater_node = arg ? arg: DEFAULT_REPEATER_NODE;
+ break;
+
+ case ARGP_KEY_END:
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+
+ *pos = state->next;
+ return 0;
+}
+
+static struct argp argp = {options, parse_opt, 0, doc};
+
+/* Initialize the VCS Repeater driver. */
+static error_t
+vcs_repeat_init (void **handle, int no_exit, int argc, char *argv[], int *next)
+{
+ error_t err;
+ int pos = 1;
+
+ /* Parse the arguments. */
+ err = argp_parse (&argp, argc, argv, ARGP_IN_ORDER | ARGP_NO_EXIT
+ | ARGP_SILENT, 0, &pos);
+ *next += pos - 1;
+
+ if (err && err != EINVAL)
+ return err;
+
+ return 0;
+}
+
+static error_t
+vcs_repeat_start (void *handle)
+{
+ error_t err;
+
+ err = console_create_consnode (repeater_node, &vcs_node);
+ if (err)
+ return err;
+
+ vcs_node->read = vcs_read;
+ vcs_node->write = NULL;
+ vcs_node->select = NULL;
+ vcs_node->open = NULL;
+ vcs_node->close = NULL;
+ vcs_node->demuxer = NULL;
+ vcs_node->readlink = vcs_readlink;
+ vcs_node->mksymlink = vcs_mksymlink;
+ console_register_consnode (vcs_node);
+
+ return 0;
+}
+
+static error_t
+vcs_repeat_fini (void *handle, int force)
+{
+ console_unregister_consnode (vcs_node);
+ console_destroy_consnode (vcs_node);
+ return 0;
+}
+
+
+struct driver_ops driver_vcs_repeat_ops =
+ {
+ vcs_repeat_init,
+ vcs_repeat_start,
+ vcs_repeat_fini
+ };
+
Index: libcons/ChangeLog
===================================================================
RCS file: /cvsroot/hurd/hurd/libcons/ChangeLog,v
retrieving revision 1.17
diff -u -u -p -r1.17 ChangeLog
--- libcons/ChangeLog 6 Jan 2005 21:53:26 -0000 1.17
+++ libcons/ChangeLog 5 Mar 2005 15:53:00 -0000
@@ -1,3 +1,11 @@
+2005-03-05 Samuel Thibault <[EMAIL PROTECTED]>
+
+ * priv.h (_cons_file): Prototype moved and renamed to...
+ * cons.h (cons_file): ... this.
+ * init-init.c (cons_init): Updated `_cons_file' reference.
+ * opts-std-startup.c (_cons_file): Renamed into `cons_file'. Updated
+ reference.
+
2005-01-06 Marco Gerards <[EMAIL PROTECTED]>
* Makefile (SRCS): Add `vcons-move-mouse.c' and `vcons-event.c'.
Index: libcons/cons.h
===================================================================
RCS file: /cvsroot/hurd/hurd/libcons/cons.h,v
retrieving revision 1.9
diff -u -u -p -r1.9 cons.h
--- libcons/cons.h 6 Jan 2005 21:53:26 -0000 1.9
+++ libcons/cons.h 5 Mar 2005 15:53:00 -0000
@@ -298,6 +298,9 @@ extern const struct argp cons_startup_ar
extern struct port_bucket *cons_port_bucket;
extern struct port_class *cons_port_class;
+/* The filename of the console server. */
+extern char *cons_file;
+
error_t cons_init (void);
void cons_server_loop (void);
int cons_demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp);
Index: libcons/init-init.c
===================================================================
RCS file: /cvsroot/hurd/hurd/libcons/init-init.c,v
retrieving revision 1.2
diff -u -u -p -r1.2 init-init.c
--- libcons/init-init.c 8 Sep 2002 21:55:59 -0000 1.2
+++ libcons/init-init.c 5 Mar 2005 15:53:00 -0000
@@ -56,7 +56,7 @@ cons_init (void)
mutex_init (&cons->lock);
cons->vcons_list = NULL;
cons->vcons_last = NULL;
- cons->dir = opendir (_cons_file);
+ cons->dir = opendir (cons_file);
cons->slack = _cons_slack;
if (!cons->dir)
{
Index: libcons/opts-std-startup.c
===================================================================
RCS file: /cvsroot/hurd/hurd/libcons/opts-std-startup.c,v
retrieving revision 1.7
diff -u -u -p -r1.7 opts-std-startup.c
--- libcons/opts-std-startup.c 6 Jan 2005 21:53:26 -0000 1.7
+++ libcons/opts-std-startup.c 5 Mar 2005 15:53:00 -0000
@@ -58,7 +58,7 @@ int _cons_jump_down_on_input = 1;
int _cons_jump_down_on_output;
/* The filename of the console server. */
-char *_cons_file;
+char *cons_file;
/* The type of bell used for the visual bell. */
bell_type_t _cons_visual_bell = BELL_VISUAL;
@@ -206,7 +206,7 @@ parse_startup_opt (int opt, char *arg, s
if (state->arg_num > 0)
/* Too many arguments. */
argp_error (state, "Too many non option arguments");
- _cons_file = arg;
+ cons_file = arg;
break;
case ARGP_KEY_NO_ARGS:
Index: libcons/priv.h
===================================================================
RCS file: /cvsroot/hurd/hurd/libcons/priv.h,v
retrieving revision 1.5
diff -u -u -p -r1.5 priv.h
--- libcons/priv.h 6 Jan 2005 21:53:26 -0000 1.5
+++ libcons/priv.h 5 Mar 2005 15:53:00 -0000
@@ -45,9 +45,6 @@ extern int _cons_jump_down_on_input;
/* If we jump down at output. */
extern int _cons_jump_down_on_output;
-/* The filename of the console server. */
-extern char *_cons_file;
-
/* The type of bell used for the visual bell. */
extern bell_type_t _cons_visual_bell;
_______________________________________________
Bug-hurd mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-hurd