readcons.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include <u.h>
  2. #include <libc.h>
  3. #include "drawterm.h"
  4. void*
  5. erealloc(void *v, ulong n)
  6. {
  7. v = realloc(v, n);
  8. if(v == nil)
  9. sysfatal("out of memory");
  10. return v;
  11. }
  12. char*
  13. estrdup(char *s)
  14. {
  15. s = strdup(s);
  16. if(s == nil)
  17. sysfatal("out of memory");
  18. return s;
  19. }
  20. char*
  21. estrappend(char *s, char *fmt, ...)
  22. {
  23. char *t;
  24. va_list arg;
  25. va_start(arg, fmt);
  26. t = vsmprint(fmt, arg);
  27. if(t == nil)
  28. sysfatal("out of memory");
  29. va_end(arg);
  30. s = erealloc(s, strlen(s)+strlen(t)+1);
  31. strcat(s, t);
  32. free(t);
  33. return s;
  34. }
  35. /*
  36. * prompt for a string with a possible default response
  37. */
  38. char*
  39. readcons(char *prompt, char *def, int raw)
  40. {
  41. int fdin, fdout, ctl, n;
  42. char line[10];
  43. char *s;
  44. fdin = open("/dev/cons", OREAD);
  45. if(fdin < 0)
  46. fdin = 0;
  47. fdout = open("/dev/cons", OWRITE);
  48. if(fdout < 0)
  49. fdout = 1;
  50. if(def != nil)
  51. fprint(fdout, "%s[%s]: ", prompt, def);
  52. else
  53. fprint(fdout, "%s: ", prompt);
  54. if(raw){
  55. ctl = open("/dev/consctl", OWRITE);
  56. if(ctl >= 0)
  57. write(ctl, "rawon", 5);
  58. } else
  59. ctl = -1;
  60. s = estrdup("");
  61. for(;;){
  62. n = read(fdin, line, 1);
  63. if(n == 0){
  64. Error:
  65. close(fdin);
  66. close(fdout);
  67. if(ctl >= 0)
  68. close(ctl);
  69. free(s);
  70. return nil;
  71. }
  72. if(n < 0)
  73. goto Error;
  74. if(line[0] == 0x7f)
  75. goto Error;
  76. if(n == 0 || line[0] == '\n' || line[0] == '\r'){
  77. if(raw){
  78. write(ctl, "rawoff", 6);
  79. write(fdout, "\n", 1);
  80. }
  81. close(ctl);
  82. close(fdin);
  83. close(fdout);
  84. if(*s == 0 && def != nil)
  85. s = estrappend(s, "%s", def);
  86. return s;
  87. }
  88. if(line[0] == '\b'){
  89. if(strlen(s) > 0)
  90. s[strlen(s)-1] = 0;
  91. } else if(line[0] == 0x15) { /* ^U: line kill */
  92. if(def != nil)
  93. fprint(fdout, "\n%s[%s]: ", prompt, def);
  94. else
  95. fprint(fdout, "\n%s: ", prompt);
  96. s[0] = 0;
  97. } else {
  98. s = estrappend(s, "%c", line[0]);
  99. }
  100. }
  101. return nil; /* not reached */
  102. }