mirror of
https://github.com/tio/tio.git
synced 2026-05-01 14:57:59 +02:00
Add timeout feature to expect()
This commit is contained in:
parent
3ad090caf7
commit
51300cc4f0
6 changed files with 60 additions and 34 deletions
|
|
@ -222,11 +222,13 @@ Tio suppots Lua scripting to easily automate interaction with the tty device.
|
||||||
In addition to the Lua API tio makes the following functions available:
|
In addition to the Lua API tio makes the following functions available:
|
||||||
|
|
||||||
```
|
```
|
||||||
expect(string)
|
expect(string, timeout)
|
||||||
Expect string - waits for string to match before continueing.
|
Expect string - waits for string to match or timeout before continueing.
|
||||||
|
|
||||||
Supports regular expressions. Special characters must be escaped with '\\'.
|
Supports regular expressions. Special characters must be escaped with '\\'.
|
||||||
|
|
||||||
|
Timeout is in milliseconds, defaults to 0 meaning it will wait forever.
|
||||||
|
|
||||||
send(string)
|
send(string)
|
||||||
Send string.
|
Send string.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -379,8 +379,10 @@ In addition to the Lua API tio makes the following functions available:
|
||||||
|
|
||||||
.TP 6n
|
.TP 6n
|
||||||
|
|
||||||
.IP "\fBexpect(string)"
|
.IP "\fBexpect(string, timeout)"
|
||||||
Expect string - waits for string to match before continueing. Supports regular expressions. Special characters must be escaped with '\\\\'.
|
Expect string - waits for string to match or timeout before continueing.
|
||||||
|
Supports regular expressions. Special characters must be escaped with '\\\\'.
|
||||||
|
Timeout is in milliseconds, defaults to 0 meaning it will wait forever.
|
||||||
.IP "\fBsend(string)"
|
.IP "\fBsend(string)"
|
||||||
Send string.
|
Send string.
|
||||||
.IP "\fBmodem_send(file, protocol)"
|
.IP "\fBmodem_send(file, protocol)"
|
||||||
|
|
|
||||||
29
src/misc.c
29
src/misc.c
|
|
@ -28,6 +28,7 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "print.h"
|
#include "print.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
@ -112,3 +113,31 @@ bool regex_match(const char *string, const char *pattern)
|
||||||
// Match
|
// Match
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int read_poll(int fd, void *data, size_t len, int timeout)
|
||||||
|
{
|
||||||
|
struct pollfd fds;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
fds.events = POLLIN;
|
||||||
|
fds.fd = fd;
|
||||||
|
|
||||||
|
/* Wait data available */
|
||||||
|
ret = poll(&fds, 1, timeout);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
tio_error_print("%s", strerror(errno));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else if (ret > 0)
|
||||||
|
{
|
||||||
|
if (fds.revents & POLLIN)
|
||||||
|
{
|
||||||
|
// Read ready data
|
||||||
|
return read(fd, data, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Timeout */
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#define UNUSED(expr) do { (void)(expr); } while (0)
|
#define UNUSED(expr) do { (void)(expr); } while (0)
|
||||||
|
|
||||||
|
|
@ -33,3 +34,4 @@ void alert_connect(void);
|
||||||
void alert_disconnect(void);
|
void alert_disconnect(void);
|
||||||
bool fs_dir_exists(const char *path);
|
bool fs_dir_exists(const char *path);
|
||||||
bool regex_match(const char *string, const char *pattern);
|
bool regex_match(const char *string, const char *pattern);
|
||||||
|
int read_poll(int fd, void *data, size_t len, int timeout);
|
||||||
|
|
|
||||||
18
src/script.c
18
src/script.c
|
|
@ -256,20 +256,27 @@ bool match_regex(regex_t *regex)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// lua: expect(string)
|
// lua: expect(string, timeout)
|
||||||
static int expect(lua_State *L)
|
static int expect(lua_State *L)
|
||||||
{
|
{
|
||||||
const char *string = lua_tostring(L, 1);
|
const char *string = lua_tostring(L, 1);
|
||||||
|
long timeout = lua_tointeger(L, 2);
|
||||||
regex_t regex;
|
regex_t regex;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
if (string == NULL)
|
if ((string == NULL) || (timeout < 0))
|
||||||
{
|
{
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (timeout == 0)
|
||||||
|
{
|
||||||
|
// Let poll() wait forever
|
||||||
|
timeout = -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Compile the regular expression
|
// Compile the regular expression
|
||||||
ret = regcomp(®ex, string, REG_EXTENDED);
|
ret = regcomp(®ex, string, REG_EXTENDED);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
@ -282,7 +289,7 @@ static int expect(lua_State *L)
|
||||||
// Main loop to read and match
|
// Main loop to read and match
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
ssize_t bytes_read = read(serial_fd, &c, 1);
|
ssize_t bytes_read = read_poll(serial_fd, &c, 1, timeout);
|
||||||
if (bytes_read > 0)
|
if (bytes_read > 0)
|
||||||
{
|
{
|
||||||
putchar(c);
|
putchar(c);
|
||||||
|
|
@ -293,6 +300,11 @@ static int expect(lua_State *L)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Timeout or error
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
|
|
|
||||||
|
|
@ -65,27 +65,6 @@ static uint16_t crc16(const uint8_t *data, uint16_t size)
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int serial_poll(int sio, void *data, size_t len, int timeout)
|
|
||||||
{
|
|
||||||
struct pollfd fds[1];
|
|
||||||
fds[0].fd = sio;
|
|
||||||
fds[0].events = POLLIN ;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
/* Wait data available */
|
|
||||||
ret = poll(fds, 1, timeout);
|
|
||||||
if (ret < 0) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
else if (ret > 0) {
|
|
||||||
if(fds[0].revents & POLLIN) {
|
|
||||||
return read(sio, data, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Timeout */
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int xmodem_1k(int sio, const void *data, size_t len, int seq)
|
static int xmodem_1k(int sio, const void *data, size_t len, int seq)
|
||||||
{
|
{
|
||||||
struct xpacket_1k packet;
|
struct xpacket_1k packet;
|
||||||
|
|
@ -99,7 +78,7 @@ static int xmodem_1k(int sio, const void *data, size_t len, int seq)
|
||||||
while(1) {
|
while(1) {
|
||||||
if (key_hit)
|
if (key_hit)
|
||||||
return -1;
|
return -1;
|
||||||
rc = serial_poll(sio, &resp, 1, 50);
|
rc = read_poll(sio, &resp, 1, 50);
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
if (resp == 'C') break;
|
if (resp == 'C') break;
|
||||||
if (resp == CAN) return ERR;
|
if (resp == CAN) return ERR;
|
||||||
|
|
@ -156,7 +135,7 @@ static int xmodem_1k(int sio, const void *data, size_t len, int seq)
|
||||||
for(int n=0; n < 20; n++) {
|
for(int n=0; n < 20; n++) {
|
||||||
if (key_hit)
|
if (key_hit)
|
||||||
return ERR;
|
return ERR;
|
||||||
rc = serial_poll(sio, &resp, 1, 50);
|
rc = read_poll(sio, &resp, 1, 50);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
tio_error_print("Read ack/nak from serial failed");
|
tio_error_print("Read ack/nak from serial failed");
|
||||||
return ERR;
|
return ERR;
|
||||||
|
|
@ -193,7 +172,7 @@ static int xmodem_1k(int sio, const void *data, size_t len, int seq)
|
||||||
}
|
}
|
||||||
write(STDOUT_FILENO, "|", 1);
|
write(STDOUT_FILENO, "|", 1);
|
||||||
/* 1s timeout */
|
/* 1s timeout */
|
||||||
rc = serial_poll(sio, &resp, 1, 1000);
|
rc = read_poll(sio, &resp, 1, 1000);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
tio_error_print("Read from serial failed");
|
tio_error_print("Read from serial failed");
|
||||||
return ERR;
|
return ERR;
|
||||||
|
|
@ -221,7 +200,7 @@ static int xmodem(int sio, const void *data, size_t len)
|
||||||
while(1) {
|
while(1) {
|
||||||
if (key_hit)
|
if (key_hit)
|
||||||
return -1;
|
return -1;
|
||||||
rc = serial_poll(sio, &resp, 1, 50);
|
rc = read_poll(sio, &resp, 1, 50);
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
if (resp == 'C') break;
|
if (resp == 'C') break;
|
||||||
if (resp == CAN) return ERR;
|
if (resp == CAN) return ERR;
|
||||||
|
|
@ -275,7 +254,7 @@ static int xmodem(int sio, const void *data, size_t len)
|
||||||
for(int n=0; n < 20; n++) {
|
for(int n=0; n < 20; n++) {
|
||||||
if (key_hit)
|
if (key_hit)
|
||||||
return ERR;
|
return ERR;
|
||||||
rc = serial_poll(sio, &resp, 1, 50);
|
rc = read_poll(sio, &resp, 1, 50);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
tio_error_print("Read ack/nak from serial failed");
|
tio_error_print("Read ack/nak from serial failed");
|
||||||
return ERR;
|
return ERR;
|
||||||
|
|
@ -312,7 +291,7 @@ static int xmodem(int sio, const void *data, size_t len)
|
||||||
}
|
}
|
||||||
write(STDOUT_FILENO, "|", 1);
|
write(STDOUT_FILENO, "|", 1);
|
||||||
/* 1s timeout */
|
/* 1s timeout */
|
||||||
rc = serial_poll(sio, &resp, 1, 1000);
|
rc = read_poll(sio, &resp, 1, 1000);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
tio_error_print("Read from serial failed");
|
tio_error_print("Read from serial failed");
|
||||||
return ERR;
|
return ERR;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue