diff options
Diffstat (limited to 'Documentation/connector/ucon.c')
-rw-r--r-- | Documentation/connector/ucon.c | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/Documentation/connector/ucon.c b/Documentation/connector/ucon.c index c5092ad0ce4b..4848db8c71ff 100644 --- a/Documentation/connector/ucon.c +++ b/Documentation/connector/ucon.c | |||
@@ -30,18 +30,24 @@ | |||
30 | 30 | ||
31 | #include <arpa/inet.h> | 31 | #include <arpa/inet.h> |
32 | 32 | ||
33 | #include <stdbool.h> | ||
33 | #include <stdio.h> | 34 | #include <stdio.h> |
34 | #include <stdlib.h> | 35 | #include <stdlib.h> |
35 | #include <unistd.h> | 36 | #include <unistd.h> |
36 | #include <string.h> | 37 | #include <string.h> |
37 | #include <errno.h> | 38 | #include <errno.h> |
38 | #include <time.h> | 39 | #include <time.h> |
40 | #include <getopt.h> | ||
39 | 41 | ||
40 | #include <linux/connector.h> | 42 | #include <linux/connector.h> |
41 | 43 | ||
42 | #define DEBUG | 44 | #define DEBUG |
43 | #define NETLINK_CONNECTOR 11 | 45 | #define NETLINK_CONNECTOR 11 |
44 | 46 | ||
47 | /* Hopefully your userspace connector.h matches this kernel */ | ||
48 | #define CN_TEST_IDX CN_NETLINK_USERS + 3 | ||
49 | #define CN_TEST_VAL 0x456 | ||
50 | |||
45 | #ifdef DEBUG | 51 | #ifdef DEBUG |
46 | #define ulog(f, a...) fprintf(stdout, f, ##a) | 52 | #define ulog(f, a...) fprintf(stdout, f, ##a) |
47 | #else | 53 | #else |
@@ -83,6 +89,25 @@ static int netlink_send(int s, struct cn_msg *msg) | |||
83 | return err; | 89 | return err; |
84 | } | 90 | } |
85 | 91 | ||
92 | static void usage(void) | ||
93 | { | ||
94 | printf( | ||
95 | "Usage: ucon [options] [output file]\n" | ||
96 | "\n" | ||
97 | "\t-h\tthis help screen\n" | ||
98 | "\t-s\tsend buffers to the test module\n" | ||
99 | "\n" | ||
100 | "The default behavior of ucon is to subscribe to the test module\n" | ||
101 | "and wait for state messages. Any ones received are dumped to the\n" | ||
102 | "specified output file (or stdout). The test module is assumed to\n" | ||
103 | "have an id of {%u.%u}\n" | ||
104 | "\n" | ||
105 | "If you get no output, then verify the cn_test module id matches\n" | ||
106 | "the expected id above.\n" | ||
107 | , CN_TEST_IDX, CN_TEST_VAL | ||
108 | ); | ||
109 | } | ||
110 | |||
86 | int main(int argc, char *argv[]) | 111 | int main(int argc, char *argv[]) |
87 | { | 112 | { |
88 | int s; | 113 | int s; |
@@ -94,17 +119,34 @@ int main(int argc, char *argv[]) | |||
94 | FILE *out; | 119 | FILE *out; |
95 | time_t tm; | 120 | time_t tm; |
96 | struct pollfd pfd; | 121 | struct pollfd pfd; |
122 | bool send_msgs = false; | ||
97 | 123 | ||
98 | if (argc < 2) | 124 | while ((s = getopt(argc, argv, "hs")) != -1) { |
99 | out = stdout; | 125 | switch (s) { |
100 | else { | 126 | case 's': |
101 | out = fopen(argv[1], "a+"); | 127 | send_msgs = true; |
128 | break; | ||
129 | |||
130 | case 'h': | ||
131 | usage(); | ||
132 | return 0; | ||
133 | |||
134 | default: | ||
135 | /* getopt() outputs an error for us */ | ||
136 | usage(); | ||
137 | return 1; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | if (argc != optind) { | ||
142 | out = fopen(argv[optind], "a+"); | ||
102 | if (!out) { | 143 | if (!out) { |
103 | ulog("Unable to open %s for writing: %s\n", | 144 | ulog("Unable to open %s for writing: %s\n", |
104 | argv[1], strerror(errno)); | 145 | argv[1], strerror(errno)); |
105 | out = stdout; | 146 | out = stdout; |
106 | } | 147 | } |
107 | } | 148 | } else |
149 | out = stdout; | ||
108 | 150 | ||
109 | memset(buf, 0, sizeof(buf)); | 151 | memset(buf, 0, sizeof(buf)); |
110 | 152 | ||
@@ -115,9 +157,11 @@ int main(int argc, char *argv[]) | |||
115 | } | 157 | } |
116 | 158 | ||
117 | l_local.nl_family = AF_NETLINK; | 159 | l_local.nl_family = AF_NETLINK; |
118 | l_local.nl_groups = 0x123; /* bitmask of requested groups */ | 160 | l_local.nl_groups = -1; /* bitmask of requested groups */ |
119 | l_local.nl_pid = 0; | 161 | l_local.nl_pid = 0; |
120 | 162 | ||
163 | ulog("subscribing to %u.%u\n", CN_TEST_IDX, CN_TEST_VAL); | ||
164 | |||
121 | if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) { | 165 | if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) { |
122 | perror("bind"); | 166 | perror("bind"); |
123 | close(s); | 167 | close(s); |
@@ -130,15 +174,15 @@ int main(int argc, char *argv[]) | |||
130 | setsockopt(s, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &on, sizeof(on)); | 174 | setsockopt(s, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &on, sizeof(on)); |
131 | } | 175 | } |
132 | #endif | 176 | #endif |
133 | if (0) { | 177 | if (send_msgs) { |
134 | int i, j; | 178 | int i, j; |
135 | 179 | ||
136 | memset(buf, 0, sizeof(buf)); | 180 | memset(buf, 0, sizeof(buf)); |
137 | 181 | ||
138 | data = (struct cn_msg *)buf; | 182 | data = (struct cn_msg *)buf; |
139 | 183 | ||
140 | data->id.idx = 0x123; | 184 | data->id.idx = CN_TEST_IDX; |
141 | data->id.val = 0x456; | 185 | data->id.val = CN_TEST_VAL; |
142 | data->seq = seq++; | 186 | data->seq = seq++; |
143 | data->ack = 0; | 187 | data->ack = 0; |
144 | data->len = 0; | 188 | data->len = 0; |