FreeCalypso > hg > freecalypso-sw
comparison loadtools/tpinterf2.c @ 35:05af070c4b60
loadtool: preparations for dump2bin and dump2srec
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 05 May 2013 02:24:56 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
34:2c6b2a74ac7c | 35:05af070c4b60 |
---|---|
1 /* | |
2 * This module provides a more advanced target interface function | |
3 * than tpinterf.c - programmatic capture of target responses, | |
4 * for dumps etc. It will be linked by fc-loadtool, but not fc-chainload. | |
5 */ | |
6 | |
7 #include <sys/types.h> | |
8 #include <sys/time.h> | |
9 #include <sys/errno.h> | |
10 #include <stdio.h> | |
11 #include <string.h> | |
12 #include <strings.h> | |
13 #include <stdlib.h> | |
14 | |
15 extern int errno; | |
16 | |
17 extern int target_fd; | |
18 | |
19 /* | |
20 * This functions reads the serial output from the target until a | |
21 * '=' prompt is received. All intermediate output is parsed into | |
22 * lines and passed to a callback function. | |
23 * | |
24 * The callback function is called with a pointer to each received | |
25 * line, stored in a buffer ending in NUL, with CRLF stripped. | |
26 * The callback function is expected to return an int. If the | |
27 * callback return value is negative, this function returns immediately | |
28 * with that negative value. If the callback return value is positive | |
29 * or zero, it is added to an accumulator. | |
30 * | |
31 * Termination: this function returns when it has received a '=' at | |
32 * the beginning of a line (return value is the callback return | |
33 * accumulator, or 0 if no lines came), if the callback returns a | |
34 * negative value (that value is returned), or if an error is detected | |
35 * within this function (return value -1, and an error message | |
36 * printed on stderr). | |
37 */ | |
38 tpinterf_capture_output(timeout, callback) | |
39 int timeout; /* seconds */ | |
40 int (*callback)(); | |
41 { | |
42 char buf[512], *cp; | |
43 char line[1024], *dp = line; | |
44 fd_set fds; | |
45 struct timeval tv; | |
46 int cc, linelen = 0; | |
47 int totout = 0, cbret; | |
48 | |
49 for (;;) { | |
50 FD_ZERO(&fds); | |
51 FD_SET(target_fd, &fds); | |
52 tv.tv_sec = timeout; | |
53 tv.tv_usec = 0; | |
54 cc = select(target_fd+1, &fds, NULL, NULL, &tv); | |
55 if (cc < 0) { | |
56 if (errno == EINTR) | |
57 continue; | |
58 perror("select"); | |
59 return(-1); | |
60 } | |
61 if (cc < 1) { | |
62 fprintf(stderr, | |
63 "error: timeout waiting for \'=\' prompt from target\n"); | |
64 return(-1); | |
65 } | |
66 cc = read(target_fd, buf, sizeof buf); | |
67 if (cc <= 0) { | |
68 perror("read after successful select"); | |
69 return(-1); | |
70 } | |
71 for (cp = buf; cc; cp++) { | |
72 cc--; | |
73 if (*cp == '=' && !linelen && !cc) | |
74 return(totout); | |
75 if (*cp == '\r') | |
76 continue; | |
77 if (*cp == '\n') { | |
78 *dp = '\0'; | |
79 cbret = callback(line); | |
80 if (cbret < 0) | |
81 return(cbret); | |
82 totout += cbret; | |
83 dp = line; | |
84 linelen = 0; | |
85 continue; | |
86 } | |
87 *dp++ = *cp; | |
88 linelen++; | |
89 if (linelen >= sizeof line) { | |
90 fprintf(stderr, | |
91 "error: target response line length exceeds buffer\n"); | |
92 return(-1); | |
93 } | |
94 } | |
95 } | |
96 } | |
97 | |
98 /* single line response capture mechanism */ | |
99 /* same line buffer size as in tpinterf_capture_output() */ | |
100 char target_response_line[1024]; | |
101 | |
102 static | |
103 oneline_catcher(linein) | |
104 char *linein; | |
105 { | |
106 strcpy(target_response_line, linein); | |
107 return(1); | |
108 } | |
109 | |
110 tpinterf_capture_output_oneline(timeout) | |
111 { | |
112 return tpinterf_capture_output(timeout, oneline_catcher); | |
113 } |