FreeCalypso > hg > freecalypso-tools
view loadtools/tpinterf2.c @ 248:cb1ba53a1106
beginning of factored-out libserial
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 21 Sep 2017 21:43:34 +0000 |
parents | e7502631a0f9 |
children | 8d7dcfd9df53 |
line wrap: on
line source
/* * This module provides a more advanced target interface function * than tpinterf.c - programmatic capture of target responses, * for dumps etc. It will be linked by fc-loadtool, but not fc-chainload. */ #include <sys/types.h> #include <sys/time.h> #include <sys/errno.h> #include <stdio.h> #include <string.h> #include <strings.h> #include <stdlib.h> extern int errno; extern int target_fd; /* * This functions reads the serial output from the target until a * '=' prompt is received. All intermediate output is parsed into * lines and passed to a callback function. * * The callback function is called with a pointer to each received * line, stored in a buffer ending in NUL, with CRLF stripped. * The callback function is expected to return an int. If the * callback return value is negative, this function returns immediately * with that negative value. If the callback return value is positive * or zero, it is added to an accumulator. * * Termination: this function returns when it has received a '=' at * the beginning of a line (return value is the callback return * accumulator, or 0 if no lines came), if the callback returns a * negative value (that value is returned), or if an error is detected * within this function (return value -1, and an error message * printed on stderr). */ tpinterf_capture_output(timeout, callback) int timeout; /* seconds */ int (*callback)(); { char buf[512], *cp; char line[1024], *dp = line; fd_set fds; struct timeval tv; int cc, linelen = 0; int totout = 0, cbret; for (;;) { FD_ZERO(&fds); FD_SET(target_fd, &fds); tv.tv_sec = timeout; tv.tv_usec = 0; cc = select(target_fd+1, &fds, NULL, NULL, &tv); if (cc < 0) { if (errno == EINTR) continue; perror("select"); return(-1); } if (cc < 1) { fprintf(stderr, "error: timeout waiting for \'=\' prompt from target\n"); return(-1); } cc = read(target_fd, buf, sizeof buf); if (cc <= 0) { perror("read after successful select"); return(-1); } for (cp = buf; cc; cp++) { cc--; if (*cp == '=' && !linelen && !cc) return(totout); if (*cp == '\r') continue; if (*cp == '\n') { *dp = '\0'; cbret = callback(line); if (cbret < 0) return(cbret); totout += cbret; dp = line; linelen = 0; continue; } *dp++ = *cp; linelen++; if (linelen >= sizeof line) { fprintf(stderr, "error: target response line length exceeds buffer\n"); return(-1); } } } } /* single line response capture mechanism */ /* same line buffer size as in tpinterf_capture_output() */ char target_response_line[1024]; static oneline_catcher(linein) char *linein; { strcpy(target_response_line, linein); return(1); } tpinterf_capture_output_oneline(timeout) { return tpinterf_capture_output(timeout, oneline_catcher); }