devwd.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #include "u.h"
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "io.h"
  7. #include "../port/error.h"
  8. enum {
  9. Qdir,
  10. Qwdctl,
  11. };
  12. static Watchdog *wd;
  13. static Dirtab wddir[] = {
  14. ".", { Qdir, 0, QTDIR }, 0, 0550,
  15. "wdctl", { Qwdctl, 0 }, 0, 0660,
  16. };
  17. void
  18. addwatchdog(Watchdog *watchdog)
  19. {
  20. if(wd){
  21. print("addwatchdog: watchdog already installed\n");
  22. return;
  23. }
  24. wd = watchdog;
  25. if(wd)
  26. wd->disable();
  27. }
  28. static Chan*
  29. wdattach(char *spec)
  30. {
  31. return devattach('w', spec);
  32. }
  33. static Walkqid*
  34. wdwalk(Chan *c, Chan *nc, char **name, int nname)
  35. {
  36. return devwalk(c, nc, name, nname, wddir, nelem(wddir), devgen);
  37. }
  38. static int
  39. wdstat(Chan *c, uchar *dp, int n)
  40. {
  41. return devstat(c, dp, n, wddir, nelem(wddir), devgen);
  42. }
  43. static Chan*
  44. wdopen(Chan* c, int omode)
  45. {
  46. return devopen(c, omode, wddir, nelem(wddir), devgen);
  47. }
  48. static void
  49. wdclose(Chan*)
  50. {
  51. }
  52. static long
  53. wdread(Chan* c, void* a, long n, vlong off)
  54. {
  55. char *p;
  56. ulong offset = off;
  57. switch((ulong)c->qid.path){
  58. case Qdir:
  59. return devdirread(c, a, n, wddir, nelem(wddir), devgen);
  60. case Qwdctl:
  61. if(wd == nil || wd->stat == nil)
  62. return 0;
  63. p = malloc(READSTR);
  64. if(waserror()){
  65. free(p);
  66. nexterror();
  67. }
  68. wd->stat(p, p + READSTR);
  69. n = readstr(offset, a, n, p);
  70. poperror();
  71. free(p);
  72. return n;
  73. default:
  74. error(Egreg);
  75. break;
  76. }
  77. return 0;
  78. }
  79. static void
  80. wdctl(char *a)
  81. {
  82. int n;
  83. char *field[6];
  84. n = tokenize(a, field, nelem(field));
  85. if(n < 1)
  86. error(Ebadarg);
  87. if(!strcmp(field[0], "enable"))
  88. wd->enable();
  89. else if(!strcmp(field[0], "disable"))
  90. wd->disable();
  91. else if(!strcmp(field[0], "restart"))
  92. wd->restart();
  93. else
  94. error(Ebadarg);
  95. }
  96. static long
  97. wdwrite(Chan* c, void* a, long n, vlong off)
  98. {
  99. char *p;
  100. ulong offset = off;
  101. switch((ulong)c->qid.path){
  102. case Qdir:
  103. error(Eperm);
  104. case Qwdctl:
  105. if(wd == nil)
  106. return n;
  107. if(offset || n >= READSTR)
  108. error(Ebadarg);
  109. p = malloc(READSTR);
  110. if(waserror()){
  111. free(p);
  112. nexterror();
  113. }
  114. memmove(p, a, n);
  115. p[n] = 0;
  116. wdctl(p);
  117. poperror();
  118. free(p);
  119. return n;
  120. default:
  121. error(Egreg);
  122. break;
  123. }
  124. return 0;
  125. }
  126. Dev wddevtab = {
  127. 'w',
  128. "watchdog",
  129. devreset,
  130. devinit,
  131. devshutdown,
  132. wdattach,
  133. wdwalk,
  134. wdstat,
  135. wdopen,
  136. devcreate,
  137. wdclose,
  138. wdread,
  139. devbread,
  140. wdwrite,
  141. devbwrite,
  142. devremove,
  143. devwstat,
  144. devpower,
  145. };