FreeCalypso > hg > freecalypso-tools
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 } |
