comparison loadtools/tpinterf2.c @ 0:e7502631a0f9

initial import from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 11 Jun 2016 00:13:35 +0000
parents
children 8d7dcfd9df53
comparison
equal deleted inserted replaced
-1:000000000000 0:e7502631a0f9
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 }