-
Notifications
You must be signed in to change notification settings - Fork 245
/
zoneevent.c
128 lines (108 loc) · 3.25 KB
/
zoneevent.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <libsysevent.h>
#include <sys/nvpair.h>
void sysev_handler(sysevent_t *ev);
sysevent_handle_t * sysev_register(const char *klass,
void (*handler)(sysevent_t *));
evchan_t * sysev_register_evc(const char *channel, const char *klass,
int (*handler)(sysevent_t *, void *));
static int
sysev_evc_handler(sysevent_t *ev, void *cookie)
{
nvlist_t *nvlist;
nvpair_t *next;
nvpair_t *curr;
data_type_t type;
char *string;
uint32_t uint32;
int32_t int32;
uint64_t uint64;
int64_t int64;
if (sysevent_get_attr_list(ev, &nvlist) != 0) {
// XXX Error
return (1);
}
curr = nvlist_next_nvpair(nvlist, NULL);
printf("{");
while (curr != NULL) {
type = nvpair_type(curr);
switch (type) {
case DATA_TYPE_STRING:
nvpair_value_string(curr, &string);
printf("\"%s\": \"%s\", ", nvpair_name(curr), string);
break;
case DATA_TYPE_UINT32:
nvpair_value_uint32(curr, &uint32);
printf("\"%s\": \"%u\", ", nvpair_name(curr), uint32);
break;
case DATA_TYPE_INT32:
nvpair_value_int32(curr, &int32);
printf("\"%s\": \"%d\", ", nvpair_name(curr), int32);
break;
case DATA_TYPE_UINT64:
nvpair_value_uint64(curr, &uint64);
printf("\"%s\": \"%llu\", ", nvpair_name(curr), uint64);
break;
case DATA_TYPE_INT64:
nvpair_value_int64(curr, &int64);
printf("\"%s\": \"%lld\", ", nvpair_name(curr), int64);
break;
break;
default:
(void) fprintf(stderr,
"don't know what to do with '%s', type: %d\n",
nvpair_name(curr), type);
break;
}
next = nvlist_next_nvpair(nvlist, curr);
curr = next;
}
printf("\"channel\": \"%s\", \"class\": \"%s\", \"subclass\": \"%s\"}\n",
(const char *) cookie,
sysevent_get_class_name(ev),
sysevent_get_subclass_name(ev));
fflush(stdout);
return (0);
}
evchan_t *
sysev_register_evc(const char *channel, const char *klass,
int (*handler)(sysevent_t *, void *))
{
int res;
evchan_t *ch;
char subid[16];
if ((res = sysevent_evc_bind(channel, &ch, 0)) != 0) {
(void) fprintf(stderr, "failed to bind to sysevent channel: %d\n", res);
return (NULL);
}
(void) snprintf(subid, sizeof (subid), "node-%ld", getpid());
if ((res = sysevent_evc_subscribe(ch, subid, klass, handler,
(void *)channel, 0)) != 0) {
(void) fprintf(stderr, "failed to subscribe to channel: %d\n", res);
return (NULL);
}
return (ch);
}
int
main(int argc, char **argv)
{
evchan_t *ch;
// quiet -Wall
argc = argc;
argv = argv;
ch = sysev_register_evc("com.sun:zones:status", "status",
sysev_evc_handler);
if (!ch) {
fprintf(stderr, "failed to register event handler.");
exit(1);
}
for (;;) {
(void) pause();
}
exit(0);
}