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