/[hurd]/hurd/console/console.c
ViewVC logotype

Diff of /hurd/console/console.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.8 by marcus, Sat Jun 8 23:33:04 2002 UTC revision 1.9 by marcus, Wed Jun 12 14:38:39 2002 UTC
# Line 16  Line 16 
16     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
18    
 #include <hurd/netfs.h>  
19  #include <stdio.h>  #include <stdio.h>
20  #include <stdlib.h>  #include <stdlib.h>
21  #include <stddef.h>  #include <stddef.h>
22  #include <unistd.h>  #include <unistd.h>
23    
24  #include <argp.h>  #include <argp.h>
25    #include <argz.h>
26  #include <error.h>  #include <error.h>
27  #include <string.h>  #include <string.h>
28  #include <fcntl.h>  #include <fcntl.h>
29  #include <dirent.h>  #include <dirent.h>
30  #include <sys/mman.h>  #include <sys/mman.h>
31  #include <sys/stat.h>  #include <sys/stat.h>
32    #include <rwlock.h>
33    #include <maptime.h>
34  #include <cthreads.h>  #include <cthreads.h>
 #include <mcheck.h>  
35    
36  #include <version.h>  #include <version.h>
37    
38  #include "console.h"  #include <hurd/netfs.h>
39    
40  #include "display.h"  #include "display.h"
41  #include "input.h"  #include "input.h"
42    
# Line 44  char *netfs_server_name = "console"; Line 46  char *netfs_server_name = "console";
46  char *netfs_server_version = HURD_VERSION;  char *netfs_server_version = HURD_VERSION;
47  int netfs_maxsymlinks = 16;     /* Arbitrary.  */  int netfs_maxsymlinks = 16;     /* Arbitrary.  */
48    
49    /* Handy source of time.  */
50    volatile struct mapped_time_value *console_maptime;
51    
52    #define DEFAULT_ENCODING "ISO-8859-1"
53    
54    
55  struct vcons  struct vcons
56  {  {
# Line 68  struct vcons Line 75  struct vcons
75    struct node *disp_node;    struct node *disp_node;
76    struct node *inpt_node;    struct node *inpt_node;
77  };  };
78    /* A handle for a virtual console device.  */
79    typedef struct vcons *vcons_t;
80    
81  struct cons  struct cons
82  {  {
83    /* The lock protects the console, all virtual consoles contained in    /* The lock protects the console, all virtual consoles contained in
84       it and the reference counters.  It also locks the       it and the reference counters.  It also locks the configuration
85       configuration.  */       parameters.  */
86    struct mutex lock;    struct mutex lock;
87    vcons_t vcons_list;    vcons_t vcons_list;
88    /* The encoding.  */    /* The encoding.  */
89    const char *encoding;    char *encoding;
90    
91    struct node *node;    struct node *node;
92    mach_port_t underlying;    mach_port_t underlying;
93    /* A template for the stat information of all nodes.  */    /* A template for the stat information of all nodes.  */
94    struct stat stat_template;    struct stat stat_template;
95  } mycons;  };
96  cons_t cons = &mycons;  /* A handle for a console device.  */
97    typedef struct cons *cons_t;
98    
99    
100  /* Lookup the virtual console with number ID in the console CONS,  /* Lookup the virtual console with number ID in the console CONS,
101     acquire a reference for it, and return it in R_VCONS.  If CREATE is     acquire a reference for it, and return it in R_VCONS.  If CREATE is
102     true, the virtual console will be created if it doesn't exist yet.     true, the virtual console will be created if it doesn't exist yet.
# Line 150  vcons_lookup (cons_t cons, int id, int c Line 161  vcons_lookup (cons_t cons, int id, int c
161    /* XXX Error checking.  */    /* XXX Error checking.  */
162    
163    mutex_init (&vcons->lock);    mutex_init (&vcons->lock);
164    err = display_create (&vcons->display, cons->encoding);    err = display_create (&vcons->display, cons->encoding ?: DEFAULT_ENCODING);
165    if (err)    if (err)
166      {      {
167        free (vcons->name);        free (vcons->name);
# Line 159  vcons_lookup (cons_t cons, int id, int c Line 170  vcons_lookup (cons_t cons, int id, int c
170        return err;        return err;
171      }      }
172    
173    err = input_create (&vcons->input, cons->encoding);    err = input_create (&vcons->input, cons->encoding ?: DEFAULT_ENCODING);
174    if (err)    if (err)
175      {      {
176        display_destroy (vcons->display);        display_destroy (vcons->display);
# Line 268  new_node (struct node **np, vcons_t vcon Line 279  new_node (struct node **np, vcons_t vcon
279        free (nn);        free (nn);
280        return ENOMEM;        return ENOMEM;
281      }      }
282    (*np)->nn_stat = cons->stat_template;    (*np)->nn_stat = vcons->cons->stat_template;
283    (*np)->nn_translated = 0;    (*np)->nn_translated = 0;
284    
285    switch (type)    switch (type)
# Line 288  new_node (struct node **np, vcons_t vcon Line 299  new_node (struct node **np, vcons_t vcon
299        (*np)->nn_stat.st_ino = (vcons->id << 2) + 2;        (*np)->nn_stat.st_ino = (vcons->id << 2) + 2;
300        (*np)->nn_stat.st_mode |= S_IFREG;        (*np)->nn_stat.st_mode |= S_IFREG;
301        (*np)->nn_stat.st_mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH);        (*np)->nn_stat.st_mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH);
302        (*np)->nn_stat.st_size = 2008 * sizeof (wchar_t); /* XXX */        (*np)->nn_stat.st_size = 2011 * sizeof (wchar_t); /* XXX */
303        break;        break;
304      case VCONS_NODE_INPUT:      case VCONS_NODE_INPUT:
305        (*np)->nn_stat.st_ino = (vcons->id << 2) + 3;        (*np)->nn_stat.st_ino = (vcons->id << 2) + 3;
# Line 300  new_node (struct node **np, vcons_t vcon Line 311  new_node (struct node **np, vcons_t vcon
311    
312    /* If the underlying node isn't a directory, propagate read permission to    /* If the underlying node isn't a directory, propagate read permission to
313       execute permission since we need that for lookups.  */       execute permission since we need that for lookups.  */
314    if (! S_ISDIR (cons->stat_template.st_mode)    if (! S_ISDIR (vcons->cons->stat_template.st_mode)
315        && S_ISDIR ((*np)->nn_stat.st_mode))        && S_ISDIR ((*np)->nn_stat.st_mode))
316      {      {
317        if (cons->stat_template.st_mode & S_IRUSR)        if (vcons->cons->stat_template.st_mode & S_IRUSR)
318          (*np)->nn_stat.st_mode |= S_IXUSR;          (*np)->nn_stat.st_mode |= S_IXUSR;
319        if (cons->stat_template.st_mode & S_IRGRP)        if (vcons->cons->stat_template.st_mode & S_IRGRP)
320          (*np)->nn_stat.st_mode |= S_IXGRP;          (*np)->nn_stat.st_mode |= S_IXGRP;
321        if (cons->stat_template.st_mode & S_IROTH)        if (vcons->cons->stat_template.st_mode & S_IROTH)
322          (*np)->nn_stat.st_mode |= S_IXOTH;          (*np)->nn_stat.st_mode |= S_IXOTH;
323      }      }
324    
# Line 1037  netfs_attempt_read (struct iouser *cred, Line 1048  netfs_attempt_read (struct iouser *cred,
1048    else    else
1049      {      {
1050        /* Pass display content to caller.  */        /* Pass display content to caller.  */
1051        ssize_t amt;        ssize_t amt = *len;
1052        assert (np == vcons->disp_node);        assert (np == vcons->disp_node);
1053        amt  = display_read (vcons->display,  
1054                             /* cred->po->openstat & O_NONBLOCK */ 0,        if (amt > np->nn_stat.st_size)
1055                             offset, data, *len);          amt = np->nn_stat.st_size;
1056          amt = display_read (vcons->display,
1057                              /* cred->po->openstat & O_NONBLOCK */ 0,
1058                              offset, data, amt);
1059        if (amt == -1)        if (amt == -1)
1060          err = errno;          err = errno;
1061        else        else
# Line 1094  netfs_attempt_write (struct iouser *cred Line 1108  netfs_attempt_write (struct iouser *cred
1108  }  }
1109    
1110    
1111    /* Implement io_map as described in <hurd/io.defs>. */
1112    kern_return_t
1113    netfs_S_io_map (struct protid *cred,
1114                    memory_object_t *rdobj,
1115                    mach_msg_type_name_t *rdtype,
1116                    memory_object_t *wrobj,
1117                    mach_msg_type_name_t *wrtype)
1118    {
1119      int flags;
1120      struct node *np;
1121      vcons_t vcons;
1122    
1123      if (!cred)
1124        return EOPNOTSUPP;
1125    
1126      np = cred->po->np;
1127      vcons = np->nn->vcons;
1128      if (!vcons || np != vcons->disp_node)
1129        return EOPNOTSUPP;
1130    
1131      *wrobj = *rdobj = MACH_PORT_NULL;
1132    
1133      flags = cred->po->openstat & (O_READ | O_WRITE);
1134    
1135      mutex_lock (&np->lock);
1136      switch (flags)
1137        {
1138        case O_READ | O_WRITE:
1139          *wrobj = *rdobj = display_get_filemap (vcons->display,
1140                                                 VM_PROT_READ | VM_PROT_WRITE);
1141          if (*wrobj == MACH_PORT_NULL)
1142            goto error;
1143          mach_port_mod_refs (mach_task_self (), *rdobj, MACH_PORT_RIGHT_SEND, 1);
1144          break;
1145        case O_READ:
1146          *rdobj = display_get_filemap (vcons->display, VM_PROT_READ);
1147          if (*rdobj == MACH_PORT_NULL)
1148            goto error;
1149          break;
1150        case O_WRITE:
1151          *wrobj = display_get_filemap (vcons->display, VM_PROT_WRITE);
1152          if (*wrobj == MACH_PORT_NULL)
1153            goto error;
1154          break;
1155        }
1156      mutex_unlock (&np->lock);
1157    
1158      *rdtype = MACH_MSG_TYPE_MOVE_SEND;
1159      *wrtype = MACH_MSG_TYPE_MOVE_SEND;
1160    
1161      return 0;
1162    
1163     error:
1164      mutex_unlock (&np->lock);
1165      return errno;
1166    }
1167    
1168    
1169    static const struct argp_option options[] =
1170    {
1171      {"encoding",  'e', "NAME", 0, "Set encoding of virtual consoles to"
1172       " NAME (default `" DEFAULT_ENCODING "')" },
1173      {0}
1174    };
1175    
1176    static error_t
1177    parse_opt (int opt, char *arg, struct argp_state *state)
1178    {
1179      cons_t cons = state->input;
1180    
1181      switch (opt)
1182        {
1183        default:
1184          return ARGP_ERR_UNKNOWN;
1185        case ARGP_KEY_SUCCESS:
1186        case ARGP_KEY_ERROR:
1187          break;
1188    
1189        case ARGP_KEY_INIT:
1190          mutex_lock (&cons->lock);
1191          break;
1192    
1193        case ARGP_KEY_FINI:
1194          mutex_unlock (&cons->lock);
1195          break;
1196    
1197        case 'e':
1198          /* XXX Check validity of encoding.  Can we perform all necessary
1199             conversions?  */
1200          {
1201            char *new = strdup (arg);
1202            if (!new)
1203              return ENOMEM;
1204            if (cons->encoding)
1205              free (cons->encoding);
1206            cons->encoding = new;
1207          }
1208          break;
1209        }
1210      return 0;
1211    }
1212    
1213    /* Return an argz string describing the current options.  Fill *ARGZ
1214       with a pointer to newly malloced storage holding the list and *LEN
1215       to the length of that storage.  */
1216    error_t
1217    netfs_append_args (char **argz, size_t *argz_len)
1218    {
1219      error_t err = 0;
1220      cons_t cons = netfs_root_node->nn->cons;
1221    
1222      if (cons->encoding && strcmp (cons->encoding, DEFAULT_ENCODING))
1223        {
1224          char *buf;
1225          asprintf (&buf, "--encoding=%s", cons->encoding);
1226          if (buf)
1227            err = argz_add (argz, argz_len, buf);
1228          else
1229            err = errno;
1230        }
1231      return err;
1232    }
1233    
1234    
1235  int  int
1236  main (int argc, char **argv)  main (int argc, char **argv)
1237  {  {
1238    error_t err;    error_t err;
1239    mach_port_t bootstrap;    mach_port_t bootstrap;
1240    struct stat ul_stat;    struct stat ul_stat;
1241    struct netnode root_nn = { cons: cons, vcons: 0 };    cons_t cons;
1242      struct netnode root_nn = { vcons: 0 };
1243    mtrace();    struct argp argp = { options, parse_opt, NULL,
1244    struct argp argp                         "A translator that provides virtual consoles." };
1245      = { NULL, NULL, NULL,  
1246          "A translator that provides virtual console displays." };    cons = malloc (sizeof (struct cons));
1247      if (!malloc)
1248        error (1, ENOMEM, "Cannot create console structure");
1249      mutex_init (&cons->lock);
1250      cons->encoding = NULL;
1251      cons->vcons_list = NULL;
1252      root_nn.cons = cons;
1253    
1254    /* Parse our command line arguments (all none of them).  */    /* Parse our command line arguments (all none of them).  */
1255    argp_parse (&argp, argc, argv, 0, 0, 0);    argp_parse (&argp, argc, argv, 0, 0, cons);
1256    
1257    task_get_bootstrap_port (mach_task_self (), &bootstrap);    task_get_bootstrap_port (mach_task_self (), &bootstrap);
1258    
1259    netfs_init ();    netfs_init ();
1260    
1261      display_init ();
1262    
1263    /* Create the root node (some attributes initialized below).  */    /* Create the root node (some attributes initialized below).  */
1264    netfs_root_node = netfs_make_node (&root_nn);    netfs_root_node = netfs_make_node (&root_nn);
1265    if (! netfs_root_node)    if (! netfs_root_node)
1266      error (5, ENOMEM, "Cannot create root node");      error (2, ENOMEM, "Cannot create root node");
1267    
1268    err = maptime_map (0, 0, &console_maptime);    err = maptime_map (0, 0, &console_maptime);
1269    if (err)    if (err)
1270      error (6, err, "Cannot map time");      error (3, err, "Cannot map time");
1271    
   mutex_init (&cons->lock);  
   cons->encoding = "ISO-8859-1";  
1272    cons->node = netfs_root_node;    cons->node = netfs_root_node;
1273    cons->underlying = netfs_startup (bootstrap, O_READ);    cons->underlying = netfs_startup (bootstrap, O_READ);
1274    if (cons->underlying == MACH_PORT_NULL)    if (cons->underlying == MACH_PORT_NULL)
1275      error (5, err, "Cannot get underlying node");      error (4, err, "Cannot get underlying node");
1276    
1277    err = io_stat (cons->underlying, &ul_stat);    err = io_stat (cons->underlying, &ul_stat);
1278    if (err)    if (err)
1279      error (6, err, "Cannot stat underlying node");      error (5, err, "Cannot stat underlying node");
1280    
1281    /* CONS.stat_template contains some fields that are inherited by all    /* CONS.stat_template contains some fields that are inherited by all
1282       nodes we create.  */       nodes we create.  */
# Line 1164  main (int argc, char **argv) Line 1309  main (int argc, char **argv)
1309    fshelp_touch (&netfs_root_node->nn_stat, TOUCH_ATIME|TOUCH_MTIME|TOUCH_CTIME,    fshelp_touch (&netfs_root_node->nn_stat, TOUCH_ATIME|TOUCH_MTIME|TOUCH_CTIME,
1310                  console_maptime);                  console_maptime);
1311    
1312    netfs_server_loop ();         /* Never returns.  */    netfs_server_loop ();
1313                                    
1314    /*NOTREACHED*/    /*NOTREACHED*/
1315    return 0;    return 0;
1316  }  }

Legend:
Removed from v.1.8  
changed lines
  Added in v.1.9

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26