devwd.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "u.h"
  10. #include "../port/lib.h"
  11. #include "mem.h"
  12. #include "dat.h"
  13. #include "fns.h"
  14. #include "io.h"
  15. #include "../port/error.h"
  16. enum {
  17. Qdir,
  18. Qwdctl,
  19. };
  20. static Watchdog *wd;
  21. static Dirtab wddir[] = {
  22. ".", { Qdir, 0, QTDIR }, 0, 0550,
  23. "wdctl", { Qwdctl, 0 }, 0, 0660,
  24. };
  25. void
  26. addwatchdog(Watchdog *watchdog)
  27. {
  28. if(wd){
  29. print("addwatchdog: watchdog already installed\n");
  30. return;
  31. }
  32. wd = watchdog;
  33. if(wd)
  34. wd->disable();
  35. }
  36. static Chan*
  37. wdattach(char *spec)
  38. {
  39. return devattach('w', spec);
  40. }
  41. static Walkqid*
  42. wdwalk(Chan *c, Chan *nc, char **name, int nname)
  43. {
  44. return devwalk(c, nc, name, nname, wddir, nelem(wddir), devgen);
  45. }
  46. static int32_t
  47. wdstat(Chan *c, uint8_t *dp, int32_t n)
  48. {
  49. return devstat(c, dp, n, wddir, nelem(wddir), devgen);
  50. }
  51. static Chan*
  52. wdopen(Chan* c, int omode)
  53. {
  54. return devopen(c, omode, wddir, nelem(wddir), devgen);
  55. }
  56. static void
  57. wdclose(Chan* c)
  58. {
  59. }
  60. static int32_t
  61. wdread(Chan* c, void* a, int32_t n, int64_t off)
  62. {
  63. int32_t offset;
  64. char s[READSTR];
  65. offset = off;
  66. switch((uint32_t)c->qid.path){
  67. case Qdir:
  68. return devdirread(c, a, n, wddir, nelem(wddir), devgen);
  69. case Qwdctl:
  70. if(wd == nil || wd->stat == nil)
  71. return 0;
  72. wd->stat(s, s + READSTR);
  73. return readstr(offset, a, n, s);
  74. default:
  75. error(Egreg);
  76. break;
  77. }
  78. return 0;
  79. }
  80. static int32_t
  81. wdwrite(Chan* c, void* a, int32_t n, int64_t off)
  82. {
  83. char *p;
  84. switch((uint32_t)c->qid.path){
  85. case Qdir:
  86. error(Eperm);
  87. case Qwdctl:
  88. if(wd == nil)
  89. return n;
  90. if(off != 0ll)
  91. error(Ebadarg);
  92. if(p = strchr(a, '\n'))
  93. *p = 0;
  94. if(!strncmp(a, "enable", n))
  95. wd->enable();
  96. else if(!strncmp(a, "disable", n))
  97. wd->disable();
  98. else if(!strncmp(a, "restart", n))
  99. wd->restart();
  100. else
  101. error(Ebadarg);
  102. return n;
  103. default:
  104. error(Egreg);
  105. break;
  106. }
  107. return 0;
  108. }
  109. Dev wddevtab = {
  110. .dc = 'w',
  111. .name = "watchdog",
  112. .reset = devreset,
  113. .init = devinit,
  114. .shutdown = devshutdown,
  115. .attach = wdattach,
  116. .walk = wdwalk,
  117. .stat = wdstat,
  118. .open = wdopen,
  119. .create = devcreate,
  120. .close = wdclose,
  121. .read = wdread,
  122. .bread = devbread,
  123. .write = wdwrite,
  124. .bwrite = devbwrite,
  125. .remove = devremove,
  126. .wstat = devwstat,
  127. .power = devpower,
  128. };