proc_tty.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * proc_tty.c -- handles /proc/tty
  3.  *
  4.  * Copyright 1997, Theodore Ts'o
  5.  */
  6. #include <asm/uaccess.h>
  7. #include <linux/init.h>
  8. #include <linux/errno.h>
  9. #include <linux/sched.h>
  10. #include <linux/proc_fs.h>
  11. #include <linux/stat.h>
  12. #include <linux/tty.h>
  13. #include <asm/bitops.h>
  14. extern struct tty_driver *tty_drivers; /* linked list of tty drivers */
  15. extern struct tty_ldisc ldiscs[];
  16. static int tty_drivers_read_proc(char *page, char **start, off_t off,
  17.  int count, int *eof, void *data);
  18. static int tty_ldiscs_read_proc(char *page, char **start, off_t off,
  19. int count, int *eof, void *data);
  20. /*
  21.  * The /proc/tty directory inodes...
  22.  */
  23. static struct proc_dir_entry *proc_tty_ldisc, *proc_tty_driver;
  24. /*
  25.  * This is the handler for /proc/tty/drivers
  26.  */
  27. static int tty_drivers_read_proc(char *page, char **start, off_t off,
  28.  int count, int *eof, void *data)
  29. {
  30. int len = 0;
  31. off_t begin = 0;
  32. struct tty_driver *p;
  33. char range[20], deftype[20];
  34. char *type;
  35. for (p = tty_drivers; p; p = p->next) {
  36. if (p->num > 1)
  37. sprintf(range, "%d-%d", p->minor_start,
  38. p->minor_start + p->num - 1);
  39. else
  40. sprintf(range, "%d", p->minor_start);
  41. switch (p->type) {
  42. case TTY_DRIVER_TYPE_SYSTEM:
  43. if (p->subtype == SYSTEM_TYPE_TTY)
  44. type = "system:/dev/tty";
  45. else if (p->subtype == SYSTEM_TYPE_SYSCONS)
  46. type = "system:console";
  47. else if (p->subtype == SYSTEM_TYPE_CONSOLE)
  48. type = "system:vtmaster";
  49. else
  50. type = "system";
  51. break;
  52. case TTY_DRIVER_TYPE_CONSOLE:
  53. type = "console";
  54. break;
  55. case TTY_DRIVER_TYPE_SERIAL:
  56. if (p->subtype == 2)
  57. type = "serial:callout";
  58. else
  59. type = "serial";
  60. break;
  61. case TTY_DRIVER_TYPE_PTY:
  62. if (p->subtype == PTY_TYPE_MASTER)
  63. type = "pty:master";
  64. else if (p->subtype == PTY_TYPE_SLAVE)
  65. type = "pty:slave";
  66. else
  67. type = "pty";
  68. break;
  69. default:
  70. sprintf(deftype, "type:%d.%d", p->type, p->subtype);
  71. type = deftype;
  72. break;
  73. }
  74. len += sprintf(page+len, "%-20s /dev/%-8s %3d %7s %sn",
  75.        p->driver_name ? p->driver_name : "unknown",
  76.        p->name, p->major, range, type);
  77. if (len+begin > off+count)
  78. break;
  79. if (len+begin < off) {
  80. begin += len;
  81. len = 0;
  82. }
  83. }
  84. if (!p)
  85. *eof = 1;
  86. if (off >= len+begin)
  87. return 0;
  88. *start = page + (off-begin);
  89. return ((count < begin+len-off) ? count : begin+len-off);
  90. }
  91. /*
  92.  * This is the handler for /proc/tty/ldiscs
  93.  */
  94. static int tty_ldiscs_read_proc(char *page, char **start, off_t off,
  95. int count, int *eof, void *data)
  96. {
  97. int i;
  98. int len = 0;
  99. off_t begin = 0;
  100. for (i=0; i < NR_LDISCS; i++) {
  101. if (!(ldiscs[i].flags & LDISC_FLAG_DEFINED))
  102. continue;
  103. len += sprintf(page+len, "%-10s %2dn",
  104.        ldiscs[i].name ? ldiscs[i].name : "???", i);
  105. if (len+begin > off+count)
  106. break;
  107. if (len+begin < off) {
  108. begin += len;
  109. len = 0;
  110. }
  111. }
  112. if (i >= NR_LDISCS)
  113. *eof = 1;
  114. if (off >= len+begin)
  115. return 0;
  116. *start = page + (off-begin);
  117. return ((count < begin+len-off) ? count : begin+len-off);
  118. }
  119. /*
  120.  * Thsi function is called by register_tty_driver() to handle
  121.  * registering the driver's /proc handler into /proc/tty/driver/<foo>
  122.  */
  123. void proc_tty_register_driver(struct tty_driver *driver)
  124. {
  125. struct proc_dir_entry *ent;
  126. if ((!driver->read_proc && !driver->write_proc) ||
  127.     !driver->driver_name ||
  128.     driver->proc_entry)
  129. return;
  130. ent = create_proc_entry(driver->driver_name, 0, proc_tty_driver);
  131. if (!ent)
  132. return;
  133. ent->read_proc = driver->read_proc;
  134. ent->write_proc = driver->write_proc;
  135. ent->data = driver;
  136. driver->proc_entry = ent;
  137. }
  138. /*
  139.  * This function is called by unregister_tty_driver()
  140.  */
  141. void proc_tty_unregister_driver(struct tty_driver *driver)
  142. {
  143. struct proc_dir_entry *ent;
  144. ent = driver->proc_entry;
  145. if (!ent)
  146. return;
  147. remove_proc_entry(driver->driver_name, proc_tty_driver);
  148. driver->proc_entry = 0;
  149. }
  150. /*
  151.  * Called by proc_root_init() to initialize the /proc/tty subtree
  152.  */
  153. void __init proc_tty_init(void)
  154. {
  155. if (!proc_mkdir("tty", 0))
  156. return;
  157. proc_tty_ldisc = proc_mkdir("tty/ldisc", 0);
  158. proc_tty_driver = proc_mkdir("tty/driver", 0);
  159. create_proc_read_entry("tty/ldiscs", 0, 0, tty_ldiscs_read_proc,NULL);
  160. create_proc_read_entry("tty/drivers", 0, 0, tty_drivers_read_proc,NULL);
  161. }