|
2 | 2 | * Copyright (c) 2016-2018, Linaro Ltd. |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | | - * Redistribution and use in source and binary forms, with or without |
6 | | - * modification, are permitted provided that the following conditions are met: |
7 | | - * |
8 | | - * 1. Redistributions of source code must retain the above copyright notice, |
9 | | - * this list of conditions and the following disclaimer. |
10 | | - * |
11 | | - * 2. Redistributions in binary form must reproduce the above copyright notice, |
12 | | - * this list of conditions and the following disclaimer in the documentation |
13 | | - * and/or other materials provided with the distribution. |
14 | | - * |
15 | | - * 3. Neither the name of the copyright holder nor the names of its contributors |
16 | | - * may be used to endorse or promote products derived from this software without |
17 | | - * specific prior written permission. |
18 | | - * |
19 | | - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
20 | | - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
21 | | - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
22 | | - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
23 | | - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | | - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | | - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | | - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | | - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | | - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | | - * POSSIBILITY OF SUCH DAMAGE. |
| 5 | + * SPDX-License-Identifier: BSD-3-Clause |
30 | 6 | */ |
31 | | -#include <sys/time.h> |
32 | | -#include <alloca.h> |
33 | 7 | #include <err.h> |
34 | 8 | #include <errno.h> |
35 | 9 | #include <fcntl.h> |
|
46 | 20 | #include "device_parser.h" |
47 | 21 | #include "fastboot.h" |
48 | 22 | #include "list.h" |
| 23 | +#include "watch.h" |
49 | 24 |
|
50 | | -static bool quit_invoked; |
51 | 25 | static const char *username; |
52 | 26 |
|
53 | 27 | struct device *selected_device; |
54 | 28 |
|
55 | | -int tty_open(const char *tty, struct termios *old) |
56 | | -{ |
57 | | - struct termios tios; |
58 | | - int ret; |
59 | | - int fd; |
60 | | - |
61 | | - fd = open(tty, O_RDWR | O_NOCTTY | O_EXCL); |
62 | | - if (fd < 0) |
63 | | - err(1, "unable to open \"%s\"", tty); |
64 | | - |
65 | | - ret = tcgetattr(fd, old); |
66 | | - if (ret < 0) |
67 | | - err(1, "unable to retrieve \"%s\" tios", tty); |
68 | | - |
69 | | - memset(&tios, 0, sizeof(tios)); |
70 | | - tios.c_cflag = B115200 | CS8 | CLOCAL | CREAD; |
71 | | - tios.c_iflag = IGNPAR; |
72 | | - tios.c_oflag = 0; |
73 | | - |
74 | | - tcflush(fd, TCIFLUSH); |
75 | | - |
76 | | - ret = tcsetattr(fd, TCSANOW, &tios); |
77 | | - if (ret < 0) |
78 | | - err(1, "unable to update \"%s\" tios", tty); |
79 | | - |
80 | | - return fd; |
81 | | -} |
82 | | - |
83 | 29 | static void fastboot_opened(struct fastboot *fb, void *data) |
84 | 30 | { |
85 | 31 | const uint8_t one = 1; |
@@ -109,12 +55,14 @@ static struct fastboot_ops fastboot_ops = { |
109 | 55 |
|
110 | 56 | static void msg_select_board(const void *param) |
111 | 57 | { |
112 | | - selected_device = device_open(param, username, &fastboot_ops); |
| 58 | + selected_device = device_open(param, username); |
113 | 59 | if (!selected_device) { |
114 | 60 | fprintf(stderr, "failed to open %s\n", (const char *)param); |
115 | | - quit_invoked = true; |
| 61 | + watch_quit(); |
116 | 62 | } |
117 | 63 |
|
| 64 | + device_fastboot_open(selected_device, &fastboot_ops); |
| 65 | + |
118 | 66 | cdba_send(MSG_SELECT_BOARD); |
119 | 67 | } |
120 | 68 |
|
@@ -248,119 +196,14 @@ static int handle_stdin(int fd, void *buf) |
248 | 196 | return 0; |
249 | 197 | } |
250 | 198 |
|
251 | | -struct watch { |
252 | | - struct list_head node; |
253 | | - |
254 | | - int fd; |
255 | | - int (*cb)(int, void*); |
256 | | - void *data; |
257 | | -}; |
258 | | - |
259 | | -struct timer { |
260 | | - struct list_head node; |
261 | | - struct timeval tv; |
262 | | - |
263 | | - void (*cb)(void *); |
264 | | - void *data; |
265 | | -}; |
266 | | - |
267 | | -static struct list_head read_watches = LIST_INIT(read_watches); |
268 | | -static struct list_head timer_watches = LIST_INIT(timer_watches); |
269 | | - |
270 | | -void watch_add_readfd(int fd, int (*cb)(int, void*), void *data) |
271 | | -{ |
272 | | - struct watch *w; |
273 | | - |
274 | | - w = calloc(1, sizeof(*w)); |
275 | | - w->fd = fd; |
276 | | - w->cb = cb; |
277 | | - w->data = data; |
278 | | - |
279 | | - list_add(&read_watches, &w->node); |
280 | | -} |
281 | | - |
282 | | -void watch_timer_add(int timeout_ms, void (*cb)(void *), void *data) |
283 | | -{ |
284 | | - struct timeval tv_timeout; |
285 | | - struct timeval now; |
286 | | - struct timer *t; |
287 | | - |
288 | | - t = calloc(1, sizeof(*t)); |
289 | | - |
290 | | - gettimeofday(&now, NULL); |
291 | | - |
292 | | - tv_timeout.tv_sec = timeout_ms / 1000; |
293 | | - tv_timeout.tv_usec = (timeout_ms % 1000) * 1000; |
294 | | - |
295 | | - t->cb = cb; |
296 | | - t->data = data; |
297 | | - timeradd(&now, &tv_timeout, &t->tv); |
298 | | - |
299 | | - list_add(&timer_watches, &t->node); |
300 | | -} |
301 | | - |
302 | | -static struct timeval *watch_timer_next(void) |
303 | | -{ |
304 | | - static struct timeval timeout; |
305 | | - struct timeval now; |
306 | | - struct timer *next; |
307 | | - struct timer *t; |
308 | | - |
309 | | - if (list_empty(&timer_watches)) |
310 | | - return NULL; |
311 | | - |
312 | | - next = list_entry_first(&timer_watches, struct timer, node); |
313 | | - |
314 | | - list_for_each_entry(t, &timer_watches, node) { |
315 | | - if (timercmp(&t->tv, &next->tv, <)) |
316 | | - next = t; |
317 | | - } |
318 | | - |
319 | | - gettimeofday(&now, NULL); |
320 | | - timersub(&next->tv, &now, &timeout); |
321 | | - if (timeout.tv_sec < 0) { |
322 | | - timeout.tv_sec = 0; |
323 | | - timeout.tv_usec = 0; |
324 | | - } |
325 | | - |
326 | | - return &timeout; |
327 | | -} |
328 | | - |
329 | | -static void watch_timer_invoke(void) |
330 | | -{ |
331 | | - struct timeval now; |
332 | | - struct timer *tmp; |
333 | | - struct timer *t; |
334 | | - |
335 | | - gettimeofday(&now, NULL); |
336 | | - |
337 | | - list_for_each_entry_safe(t, tmp, &timer_watches, node) { |
338 | | - if (timercmp(&t->tv, &now, <)) { |
339 | | - t->cb(t->data); |
340 | | - |
341 | | - list_del(&t->node); |
342 | | - free(t); |
343 | | - } |
344 | | - } |
345 | | -} |
346 | | - |
347 | 199 | static void sigpipe_handler(int signo) |
348 | 200 | { |
349 | | - quit_invoked = true; |
350 | | -} |
351 | | - |
352 | | -void watch_quit(void) |
353 | | -{ |
354 | | - quit_invoked = true; |
| 201 | + watch_quit(); |
355 | 202 | } |
356 | 203 |
|
357 | 204 | int main(int argc, char **argv) |
358 | 205 | { |
359 | | - struct timeval *timeoutp; |
360 | | - struct watch *w; |
361 | | - fd_set rfds; |
362 | 206 | int flags; |
363 | | - int nfds; |
364 | 207 | int ret; |
365 | 208 |
|
366 | 209 | signal(SIGPIPE, sigpipe_handler); |
@@ -389,40 +232,7 @@ int main(int argc, char **argv) |
389 | 232 | flags = fcntl(STDIN_FILENO, F_GETFL, 0); |
390 | 233 | fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK); |
391 | 234 |
|
392 | | - while (!quit_invoked) { |
393 | | - nfds = 0; |
394 | | - |
395 | | - list_for_each_entry(w, &read_watches, node) { |
396 | | - nfds = MAX(nfds, w->fd); |
397 | | - FD_SET(w->fd, &rfds); |
398 | | - } |
399 | | - |
400 | | - if (!FD_ISSET(STDIN_FILENO, &rfds)) { |
401 | | - fprintf(stderr, "rfds is trash!\n"); |
402 | | - goto done; |
403 | | - } |
404 | | - |
405 | | - timeoutp = watch_timer_next(); |
406 | | - ret = select(nfds + 1, &rfds, NULL, NULL, timeoutp); |
407 | | - if (ret < 0 && errno == EINTR) |
408 | | - continue; |
409 | | - else if (ret < 0) |
410 | | - break; |
411 | | - |
412 | | - watch_timer_invoke(); |
413 | | - |
414 | | - list_for_each_entry(w, &read_watches, node) { |
415 | | - if (FD_ISSET(w->fd, &rfds)) { |
416 | | - ret = w->cb(w->fd, w->data); |
417 | | - if (ret < 0) { |
418 | | - fprintf(stderr, "cb returned %d\n", ret); |
419 | | - goto done; |
420 | | - } |
421 | | - } |
422 | | - } |
423 | | - } |
424 | | - |
425 | | -done: |
| 235 | + watch_run(); |
426 | 236 |
|
427 | 237 | /* if we got here, stdin/out/err might be not accessible anymore */ |
428 | 238 | ret = open("/dev/null", O_RDWR); |
|
0 commit comments