On Mon, Jun 03, 2002 at 03:42:44AM +0200, Marcus Brinkmann wrote: > Below is a diff
and here it is --- console-old.c Mon Jun 3 03:29:50 2002 +++ console.c Mon Jun 3 03:32:12 2002 @@ -67,6 +67,7 @@ struct node *dir_node; struct node *cons_node; struct node *disp_node; + struct node *inpt_node; /* The output queue holds the characters that are to be outputted. The display driver might refuse to handle some incomplete @@ -178,14 +179,15 @@ } previous_vcons->next = vcons; } - else { - if (cons->vcons_list) - { - cons->vcons_list->prev = vcons; - vcons->next = cons->vcons_list; - } - cons->vcons_list = vcons; - } + else + { + if (cons->vcons_list) + { + cons->vcons_list->prev = vcons; + vcons->next = cons->vcons_list; + } + cons->vcons_list = vcons; + } mutex_unlock (&cons->lock); *r_vcons = vcons; return 0; @@ -217,25 +219,35 @@ we know that without references, this virtual console is neither active nor used by any input group. */ - /* XXX Destroy the state. */ - free (vcons->name); if (vcons->prev) vcons->prev->next = vcons->next; + else + cons->vcons_list = vcons->next; if (vcons->next) vcons->next->prev = vcons->prev; - if (!vcons->prev && !vcons->next) - vcons->cons->vcons_list = NULL; + + /* XXX Destroy the state. */ + free (vcons->name); free (vcons); } mutex_unlock (&cons->lock); } - +struct netnode +{ + /* The root node points to the console object. */ + cons_t cons; + + /* All other nodes point to the virtual console object. */ + vcons_t vcons; +}; + typedef enum { VCONS_NODE_DIR = 0, VCONS_NODE_CONSOLE, - VCONS_NODE_DISPLAY + VCONS_NODE_DISPLAY, + VCONS_NODE_INPUT } vcons_node_type; /* Make a new virtual node. Always consumes the ports. */ @@ -254,6 +266,7 @@ return ENOMEM; } (*np)->nn_stat = cons->stat_template; + (*np)->nn_translated = 0; switch (type) { @@ -265,13 +278,21 @@ case VCONS_NODE_CONSOLE: (*np)->nn_stat.st_ino = (vcons->id << 2) + 1; (*np)->nn_stat.st_mode |= S_IFCHR; /* Don't set nn_translated! */ + (*np)->nn_stat.st_mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH); (*np)->nn_stat.st_size = 0; break; case VCONS_NODE_DISPLAY: (*np)->nn_stat.st_ino = (vcons->id << 2) + 2; (*np)->nn_stat.st_mode |= S_IFREG; + (*np)->nn_stat.st_mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH); (*np)->nn_stat.st_size = 2000; /* XXX */ break; + case VCONS_NODE_INPUT: + (*np)->nn_stat.st_ino = (vcons->id << 2) + 3; + (*np)->nn_stat.st_mode |= S_IFIFO; + (*np)->nn_stat.st_mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH); + (*np)->nn_stat.st_size = 0; + break; } /* If the underlying node isn't a directory, propagate read permission to @@ -306,17 +327,32 @@ /* The root node does never go away. */ assert (!np->nn->cons && np->nn->vcons); + /* Avoid deadlock. */ + spin_unlock (&netfs_node_refcnt_lock); + /* Find the back reference to ourself in the virtual console structure, and delete it. */ mutex_lock (&vcons->lock); + spin_lock (&netfs_node_refcnt_lock); + if (np->references) + { + /* Someone else got a reference while we were attempting to go + away. This can happen in netfs_attempt_lookup. In this + case, just unlock the node and do nothing else. */ + mutex_unlock (&vcons->lock); + mutex_unlock (&np->lock); + return; + } if (np == vcons->dir_node) vcons->dir_node = 0; else if (np == vcons->cons_node) vcons->cons_node = 0; + else if (np == vcons->disp_node) + vcons->disp_node = 0; else { - assert (np == vcons->disp_node); - vcons->disp_node = 0; + assert (np == vcons->inpt_node); + vcons->inpt_node = 0; } mutex_unlock (&vcons->lock); @@ -559,6 +595,25 @@ } mutex_unlock (&vcons->lock); } + else if (!strcmp (name, "input")) + { + mutex_lock (&vcons->lock); + if (vcons->inpt_node) + { + *node = vcons->inpt_node; + netfs_nref (*node); + } + else + { + err = new_node (node, vcons, VCONS_NODE_INPUT); + if (!err) + { + vcons->inpt_node = *node; + ref_vcons = 1; + } + } + mutex_unlock (&vcons->lock); + } else err = ENOENT; @@ -646,13 +701,8 @@ { /* See how much space we need for the result. */ for (vcons = first_vcons; vcons; vcons = vcons->next) -#if 0 - if (vcons->dir_node /* XXX see above */ - && !bump_size (vcons->name)) -#else - if (!bump_size (vcons->name)) -#endif - break; + if (!bump_size (vcons->name)) + break; } else { @@ -660,6 +710,8 @@ bump_size ("console"); if (first_entry <= 3) bump_size ("display"); + if (first_entry <= 4) + bump_size ("input"); } /* Allocate it. */ @@ -716,11 +768,7 @@ /* Fill in the real directory entries. */ for (vcons = first_vcons; vcons; vcons = vcons->next) - if ( -#if 0 - /* XXX see above */ vcons->dir_node && -#endif - !add_dir_entry (vcons->name, + if (!add_dir_entry (vcons->name, vcons->id << 2, DT_DIR)) break; mutex_unlock (&dir->nn->cons->lock); @@ -734,9 +782,11 @@ add_dir_entry ("..", 2, DT_DIR); if (first_entry <= 2) - add_dir_entry ("console", (vcons->id << 2) + 1, DT_REG); + add_dir_entry ("console", (dir->nn->vcons->id << 2) + 1, DT_REG); if (first_entry <= 3) - add_dir_entry ("display", (vcons->id << 2) + 2, DT_REG); + add_dir_entry ("display", (dir->nn->vcons->id << 2) + 2, DT_REG); + if (first_entry <= 4) + add_dir_entry ("input", (dir->nn->vcons->id << 3) + 2, DT_FIFO); } } @@ -795,6 +845,11 @@ vcons->disp_node->nn_stat.st_uid = uid; vcons->disp_node->nn_stat.st_gid = gid; } + if (vcons->inpt_node) + { + vcons->inpt_node->nn_stat.st_uid = uid; + vcons->inpt_node->nn_stat.st_gid = gid; + } } mutex_unlock (&cons->lock); fshelp_touch (&node->nn_stat, TOUCH_CTIME, console_maptime); @@ -832,6 +887,8 @@ vcons->cons_node->nn_stat.st_author = author; if (vcons->disp_node) vcons->disp_node->nn_stat.st_author = author; + if (vcons->inpt_node) + vcons->inpt_node->nn_stat.st_author = author; } mutex_unlock (&cons->lock); fshelp_touch (&node->nn_stat, TOUCH_CTIME, console_maptime); @@ -956,9 +1013,11 @@ if (np == vcons->cons_node) *len = 0; /* Pass input queue content to caller. */ + else if (np == vcons->disp_node) + *len = 0; /* Pass input queue content to caller. */ else { - assert (np == vcons->disp_node); + assert (np == vcons->inpt_node); *len = 0; /* Pass display content to caller. */ } return 0; @@ -974,6 +1033,8 @@ if (np == vcons->cons_node) *len = 0; /* Write input to text matrix. */ + else if (np == vcons->disp_node) + *len = 0; /* Put input into input queue. */ else { assert (np == vcons->disp_node); -- `Rhubarb is no Egyptian god.' Debian http://www.debian.org [EMAIL PROTECTED] Marcus Brinkmann GNU http://www.gnu.org [EMAIL PROTECTED] [EMAIL PROTECTED] http://www.marcus-brinkmann.de _______________________________________________ Bug-hurd mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-hurd