source: mainline/uspace/app/netecho/netecho.c@ b48e680f

serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since b48e680f was 87822ce, checked in by Jiri Svoboda <jiri@…>, 4 years ago

Avoid infinite loop when console communication is broken

Need to make sure callers of console_get_event_timeout() can distinguish
between timeout and I/O error. Fix all callers of console_get_event()
and console_get_event_timeout() not to enter infinite loop when console
connection is broken. Also avoid setting of errno variable.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 * Copyright (c) 2016 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup netecho
30 * @{
31 */
32/** @file Network UDP echo diagnostic utility.
33 */
34
35#include <stdbool.h>
36#include <errno.h>
37#include <io/console.h>
38#include <stdio.h>
39#include <str.h>
40
41#include "comm.h"
42#include "netecho.h"
43
44#define NAME "netecho"
45
46static console_ctrl_t *con;
47static bool done;
48
49void netecho_received(void *data, size_t size)
50{
51 char *p;
52 size_t i;
53
54 printf("Received message '");
55 p = data;
56
57 for (i = 0; i < size; i++)
58 putchar(p[i]);
59 printf("'.\n");
60}
61
62static void key_handle_ctrl(kbd_event_t *ev)
63{
64 switch (ev->key) {
65 case KC_Q:
66 done = true;
67 break;
68 default:
69 break;
70 }
71}
72
73static void send_char(char32_t c)
74{
75 char cbuf[STR_BOUNDS(1)];
76 size_t offs;
77 errno_t rc;
78
79 offs = 0;
80 chr_encode(c, cbuf, &offs, STR_BOUNDS(1));
81
82 rc = comm_send(cbuf, offs);
83 if (rc != EOK) {
84 printf("[Failed sending data]\n");
85 }
86}
87
88static void key_handle_unmod(kbd_event_t *ev)
89{
90 switch (ev->key) {
91 case KC_ENTER:
92 send_char('\n');
93 break;
94 default:
95 if (ev->c >= 32 || ev->c == '\t' || ev->c == '\b') {
96 send_char(ev->c);
97 }
98 }
99}
100
101static void key_handle(kbd_event_t *ev)
102{
103 if ((ev->mods & KM_ALT) == 0 &&
104 (ev->mods & KM_SHIFT) == 0 &&
105 (ev->mods & KM_CTRL) != 0) {
106 key_handle_ctrl(ev);
107 } else if ((ev->mods & (KM_CTRL | KM_ALT)) == 0) {
108 key_handle_unmod(ev);
109 }
110}
111
112static void print_syntax(void)
113{
114 printf("syntax:\n");
115 printf("\t%s -l <port>\n", NAME);
116 printf("\t%s -d <host>:<port> [<message> [<message...>]]\n", NAME);
117}
118
119/* Interactive mode */
120static void netecho_interact(void)
121{
122 cons_event_t ev;
123 errno_t rc;
124
125 printf("Communication started. Press Ctrl-Q to quit.\n");
126
127 con = console_init(stdin, stdout);
128
129 done = false;
130 while (!done) {
131 rc = console_get_event(con, &ev);
132 if (rc != EOK)
133 break;
134
135 if (ev.type == CEV_KEY && ev.ev.key.type == KEY_PRESS)
136 key_handle(&ev.ev.key);
137 }
138}
139
140static void netecho_send_messages(char **msgs)
141{
142 errno_t rc;
143
144 while (*msgs != NULL) {
145 rc = comm_send(*msgs, str_size(*msgs));
146 if (rc != EOK) {
147 printf("[Failed sending data]\n");
148 }
149
150 ++msgs;
151 }
152}
153
154int main(int argc, char *argv[])
155{
156 char *hostport;
157 char *port;
158 char **msgs;
159 errno_t rc;
160
161 if (argc < 2) {
162 print_syntax();
163 return 1;
164 }
165
166 if (str_cmp(argv[1], "-l") == 0) {
167 if (argc != 3) {
168 print_syntax();
169 return 1;
170 }
171
172 port = argv[2];
173 msgs = NULL;
174
175 rc = comm_open_listen(port);
176 if (rc != EOK) {
177 printf("Error setting up communication.\n");
178 return 1;
179 }
180 } else if (str_cmp(argv[1], "-d") == 0) {
181 if (argc < 3) {
182 print_syntax();
183 return 1;
184 }
185
186 hostport = argv[2];
187 port = NULL;
188 msgs = argv + 3;
189
190 rc = comm_open_talkto(hostport);
191 if (rc != EOK) {
192 printf("Error setting up communication.\n");
193 return 1;
194 }
195 } else {
196 print_syntax();
197 return 1;
198 }
199
200 if (msgs != NULL && *msgs != NULL) {
201 /* Just send messages and quit */
202 netecho_send_messages(msgs);
203 } else {
204 /* Interactive mode */
205 netecho_interact();
206 }
207
208 comm_close();
209 return 0;
210}
211
212/** @}
213 */
Note: See TracBrowser for help on using the repository browser.