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
Bug-hurd@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-hurd

Reply via email to