Merge pull request #1445 from LudwigOrtmann/issue-476
native: uart reconnect buffer replay (+a little cleanup)
This commit is contained in:
commit
12e55ddaec
@ -45,6 +45,9 @@
|
|||||||
int _native_uart_sock;
|
int _native_uart_sock;
|
||||||
int _native_uart_conn;
|
int _native_uart_conn;
|
||||||
|
|
||||||
|
int _native_replay_enabled;
|
||||||
|
FILE *_native_replay_buffer;
|
||||||
|
|
||||||
fd_set _native_uart_rfds;
|
fd_set _native_uart_rfds;
|
||||||
|
|
||||||
/* uart API */
|
/* uart API */
|
||||||
@ -177,7 +180,7 @@ void handle_uart_in(void)
|
|||||||
|
|
||||||
nread = _native_read(STDIN_FILENO, buf, sizeof(buf));
|
nread = _native_read(STDIN_FILENO, buf, sizeof(buf));
|
||||||
if (nread == -1) {
|
if (nread == -1) {
|
||||||
err(1, "handle_uart_in(): read()");
|
err(EXIT_FAILURE, "handle_uart_in(): read()");
|
||||||
}
|
}
|
||||||
else if (nread == 0) {
|
else if (nread == 0) {
|
||||||
/* end of file / socket closed */
|
/* end of file / socket closed */
|
||||||
@ -227,6 +230,34 @@ void handle_uart_sock(void)
|
|||||||
if (real_dup2(s, STDIN_FILENO) == -1) {
|
if (real_dup2(s, STDIN_FILENO) == -1) {
|
||||||
err(EXIT_FAILURE, "handle_uart_sock: dup2()");
|
err(EXIT_FAILURE, "handle_uart_sock: dup2()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* play back log from last position */
|
||||||
|
if (_native_replay_enabled) {
|
||||||
|
warnx("handle_uart_sock: replaying buffer");
|
||||||
|
size_t nread;
|
||||||
|
char buf[200];
|
||||||
|
while ((nread = real_fread(buf, 1, sizeof(buf), _native_replay_buffer)) != 0) {
|
||||||
|
int nwritten;
|
||||||
|
int pos = 0;
|
||||||
|
while ((nwritten = real_write(STDOUT_FILENO, &buf[pos], nread)) != -1) {
|
||||||
|
nread -= nwritten;
|
||||||
|
pos += nwritten;
|
||||||
|
if (nread == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nwritten == -1) {
|
||||||
|
err(EXIT_FAILURE, "handle_uart_sock: write");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (real_feof(_native_replay_buffer) != 0) {
|
||||||
|
real_clearerr(_native_replay_buffer);
|
||||||
|
}
|
||||||
|
else if (real_ferror(_native_replay_buffer) != 0) {
|
||||||
|
err(EXIT_FAILURE, "handle_uart_sock(): fread()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_native_syscall_leave();
|
_native_syscall_leave();
|
||||||
|
|
||||||
_native_uart_conn = s;
|
_native_uart_conn = s;
|
||||||
@ -260,8 +291,18 @@ int _native_set_uart_fds(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void _native_init_uart0(char *stdiotype, char *ioparam)
|
void _native_init_uart0(char *stdiotype, char *ioparam, int replay)
|
||||||
{
|
{
|
||||||
|
_native_replay_enabled = replay;
|
||||||
|
|
||||||
|
if (_native_replay_enabled) {
|
||||||
|
char stdout_logname[255];
|
||||||
|
snprintf(stdout_logname, sizeof(stdout_logname), "/tmp/riot.stdout.%d", _native_pid);
|
||||||
|
if ((_native_replay_buffer = real_fopen(stdout_logname, "r+")) == NULL) {
|
||||||
|
err(EXIT_FAILURE, "_native_init_uart0: fdopen(_native_null_out_file)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (strcmp(stdiotype, "tcp") == 0) {
|
if (strcmp(stdiotype, "tcp") == 0) {
|
||||||
_native_uart_sock = init_tcp_socket(ioparam);
|
_native_uart_sock = init_tcp_socket(ioparam);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ void _native_handle_uart0_input(void);
|
|||||||
* @param stdiotype: "stdio", "tcp", "udp" io redirection
|
* @param stdiotype: "stdio", "tcp", "udp" io redirection
|
||||||
* @param ioparam: a string containing a port number if stdiotype is tcp
|
* @param ioparam: a string containing a port number if stdiotype is tcp
|
||||||
*/
|
*/
|
||||||
void _native_init_uart0(char *stdiotype, char *ioparam);
|
void _native_init_uart0(char *stdiotype, char *ioparam, int replay);
|
||||||
int _native_set_uart_fds(void);
|
int _native_set_uart_fds(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
#define _NATIVE_INTERNAL_H
|
#define _NATIVE_INTERNAL_H
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
/* enable signal handler register access on different platforms
|
/* enable signal handler register access on different platforms
|
||||||
* check here for more:
|
* check here for more:
|
||||||
* http://sourceforge.net/p/predef/wiki/OperatingSystems/
|
* http://sourceforge.net/p/predef/wiki/OperatingSystems/
|
||||||
@ -48,24 +49,31 @@ extern void _native_sig_leave_tramp(void);
|
|||||||
|
|
||||||
void _native_syscall_leave(void);
|
void _native_syscall_leave(void);
|
||||||
void _native_syscall_enter(void);
|
void _native_syscall_enter(void);
|
||||||
|
void _native_init_syscalls(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* external functions regularly wrapped in native for direct use
|
* external functions regularly wrapped in native for direct use
|
||||||
*/
|
*/
|
||||||
extern ssize_t (*real_read)(int fd, void *buf, size_t count);
|
extern ssize_t (*real_read)(int fd, void *buf, size_t count);
|
||||||
extern ssize_t (*real_write)(int fd, const void *buf, size_t count);
|
extern ssize_t (*real_write)(int fd, const void *buf, size_t count);
|
||||||
extern void* (*real_malloc)(size_t size);
|
extern size_t (*real_fread)(void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||||
|
extern void (*real_clearerr)(FILE *stream);
|
||||||
extern void (*real_free)(void *ptr);
|
extern void (*real_free)(void *ptr);
|
||||||
extern void* (*real_calloc)(size_t nmemb, size_t size);
|
extern void* (*real_calloc)(size_t nmemb, size_t size);
|
||||||
|
extern void* (*real_malloc)(size_t size);
|
||||||
extern void* (*real_realloc)(void *ptr, size_t size);
|
extern void* (*real_realloc)(void *ptr, size_t size);
|
||||||
extern int (*real_getpid)(void);
|
|
||||||
extern int (*real_pipe)(int[2]);
|
|
||||||
extern int (*real_close)(int);
|
extern int (*real_close)(int);
|
||||||
extern int (*real_fork)(void);
|
|
||||||
extern int (*real_dup2)(int, int);
|
extern int (*real_dup2)(int, int);
|
||||||
extern int (*real_unlink)(const char *);
|
|
||||||
extern int (*real_execve)(const char *, char *const[], char *const[]);
|
extern int (*real_execve)(const char *, char *const[], char *const[]);
|
||||||
|
extern int (*real_feof)(FILE *stream);
|
||||||
|
extern int (*real_ferror)(FILE *stream);
|
||||||
|
extern int (*real_fork)(void);
|
||||||
|
extern int (*real_getpid)(void);
|
||||||
extern int (*real_pause)(void);
|
extern int (*real_pause)(void);
|
||||||
|
extern int (*real_pipe)(int[2]);
|
||||||
|
extern int (*real_printf)(const char *format, ...);
|
||||||
|
extern int (*real_unlink)(const char *);
|
||||||
|
extern FILE* (*real_fopen)(const char *path, const char *mode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* data structures
|
* data structures
|
||||||
|
|||||||
@ -37,8 +37,6 @@
|
|||||||
#include "native_internal.h"
|
#include "native_internal.h"
|
||||||
#include "tap.h"
|
#include "tap.h"
|
||||||
|
|
||||||
int (*real_printf)(const char *format, ...);
|
|
||||||
int (*real_getpid)(void);
|
|
||||||
int _native_null_in_pipe[2];
|
int _native_null_in_pipe[2];
|
||||||
int _native_null_out_file;
|
int _native_null_out_file;
|
||||||
const char *_progname;
|
const char *_progname;
|
||||||
@ -55,7 +53,7 @@ const char *_native_unix_socket_path = NULL;
|
|||||||
void _native_null_in(char *stdiotype)
|
void _native_null_in(char *stdiotype)
|
||||||
{
|
{
|
||||||
if (real_pipe(_native_null_in_pipe) == -1) {
|
if (real_pipe(_native_null_in_pipe) == -1) {
|
||||||
err(1, "_native_null_in(): pipe()");
|
err(EXIT_FAILURE, "_native_null_in(): pipe()");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(stdiotype, "stdio") == 0) {
|
if (strcmp(stdiotype, "stdio") == 0) {
|
||||||
@ -161,7 +159,7 @@ void usage_exit(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MODULE_UART0
|
#ifdef MODULE_UART0
|
||||||
real_printf(" [-t <port>|-u [path]]");
|
real_printf(" [-t <port>|-u [path]] [-r]");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
real_printf(" [-i <id>] [-d] [-e|-E] [-o]\n");
|
real_printf(" [-i <id>] [-d] [-e|-E] [-o]\n");
|
||||||
@ -175,7 +173,9 @@ void usage_exit(void)
|
|||||||
real_printf("\
|
real_printf("\
|
||||||
-t <port> redirect stdio to TCP socket listening on <port>\n\
|
-t <port> redirect stdio to TCP socket listening on <port>\n\
|
||||||
-u <path> redirect stdio to UNIX socket (<path> if given,\n\
|
-u <path> redirect stdio to UNIX socket (<path> if given,\n\
|
||||||
/tmp/riot.tty.PID otherwise)\n");
|
/tmp/riot.tty.PID otherwise)\n\
|
||||||
|
-r replay missed output when (re-)attaching to socket\n\
|
||||||
|
(implies -o)\n");
|
||||||
#endif
|
#endif
|
||||||
real_printf("\
|
real_printf("\
|
||||||
-i <id> specify instance id (set by config module)\n\
|
-i <id> specify instance id (set by config module)\n\
|
||||||
@ -194,21 +194,7 @@ The order of command line arguments matters.\n");
|
|||||||
|
|
||||||
__attribute__((constructor)) static void startup(int argc, char **argv)
|
__attribute__((constructor)) static void startup(int argc, char **argv)
|
||||||
{
|
{
|
||||||
/* get system read/write/printf */
|
_native_init_syscalls();
|
||||||
*(void **)(&real_read) = dlsym(RTLD_NEXT, "read");
|
|
||||||
*(void **)(&real_write) = dlsym(RTLD_NEXT, "write");
|
|
||||||
*(void **)(&real_malloc) = dlsym(RTLD_NEXT, "malloc");
|
|
||||||
*(void **)(&real_realloc) = dlsym(RTLD_NEXT, "realloc");
|
|
||||||
*(void **)(&real_free) = dlsym(RTLD_NEXT, "free");
|
|
||||||
*(void **)(&real_printf) = dlsym(RTLD_NEXT, "printf");
|
|
||||||
*(void **)(&real_getpid) = dlsym(RTLD_NEXT, "getpid");
|
|
||||||
*(void **)(&real_pipe) = dlsym(RTLD_NEXT, "pipe");
|
|
||||||
*(void **)(&real_close) = dlsym(RTLD_NEXT, "close");
|
|
||||||
*(void **)(&real_fork) = dlsym(RTLD_NEXT, "fork");
|
|
||||||
*(void **)(&real_dup2) = dlsym(RTLD_NEXT, "dup2");
|
|
||||||
*(void **)(&real_unlink) = dlsym(RTLD_NEXT, "unlink");
|
|
||||||
*(void **)(&real_execve) = dlsym(RTLD_NEXT, "execve");
|
|
||||||
*(void **)(&real_pause) = dlsym(RTLD_NEXT, "pause");
|
|
||||||
|
|
||||||
_native_argv = argv;
|
_native_argv = argv;
|
||||||
_progname = argv[0];
|
_progname = argv[0];
|
||||||
@ -223,6 +209,7 @@ __attribute__((constructor)) static void startup(int argc, char **argv)
|
|||||||
char *stdiotype = "stdio";
|
char *stdiotype = "stdio";
|
||||||
#ifdef MODULE_UART0
|
#ifdef MODULE_UART0
|
||||||
char *ioparam = NULL;
|
char *ioparam = NULL;
|
||||||
|
int replay = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MODULE_NATIVENET
|
#ifdef MODULE_NATIVENET
|
||||||
@ -274,6 +261,10 @@ __attribute__((constructor)) static void startup(int argc, char **argv)
|
|||||||
stdouttype = "file";
|
stdouttype = "file";
|
||||||
}
|
}
|
||||||
#ifdef MODULE_UART0
|
#ifdef MODULE_UART0
|
||||||
|
else if (strcmp("-r", arg) == 0) {
|
||||||
|
stdouttype = "file";
|
||||||
|
replay = 1;
|
||||||
|
}
|
||||||
else if (strcmp("-t", arg) == 0) {
|
else if (strcmp("-t", arg) == 0) {
|
||||||
stdiotype = "tcp";
|
stdiotype = "tcp";
|
||||||
if (argp + 1 < argc) {
|
if (argp + 1 < argc) {
|
||||||
@ -314,7 +305,7 @@ __attribute__((constructor)) static void startup(int argc, char **argv)
|
|||||||
_native_null_in(stdiotype);
|
_native_null_in(stdiotype);
|
||||||
|
|
||||||
#ifdef MODULE_UART0
|
#ifdef MODULE_UART0
|
||||||
_native_init_uart0(stdiotype, ioparam);
|
_native_init_uart0(stdiotype, ioparam, replay);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
native_hwtimer_pre_init();
|
native_hwtimer_pre_init();
|
||||||
|
|||||||
@ -50,17 +50,24 @@ extern volatile tcb_t *sched_active_thread;
|
|||||||
|
|
||||||
ssize_t (*real_read)(int fd, void *buf, size_t count);
|
ssize_t (*real_read)(int fd, void *buf, size_t count);
|
||||||
ssize_t (*real_write)(int fd, const void *buf, size_t count);
|
ssize_t (*real_write)(int fd, const void *buf, size_t count);
|
||||||
void* (*real_malloc)(size_t size);
|
size_t (*real_fread)(void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||||
|
void (*real_clearerr)(FILE *stream);
|
||||||
void (*real_free)(void *ptr);
|
void (*real_free)(void *ptr);
|
||||||
|
void* (*real_malloc)(size_t size);
|
||||||
void* (*real_calloc)(size_t nmemb, size_t size);
|
void* (*real_calloc)(size_t nmemb, size_t size);
|
||||||
void* (*real_realloc)(void *ptr, size_t size);
|
void* (*real_realloc)(void *ptr, size_t size);
|
||||||
|
int (*real_printf)(const char *format, ...);
|
||||||
|
int (*real_getpid)(void);
|
||||||
int (*real_pipe)(int[2]);
|
int (*real_pipe)(int[2]);
|
||||||
int (*real_close)(int);
|
int (*real_close)(int);
|
||||||
int (*real_fork)(void);
|
|
||||||
int (*real_dup2)(int, int);
|
int (*real_dup2)(int, int);
|
||||||
int (*real_unlink)(const char *);
|
|
||||||
int (*real_execve)(const char *, char *const[], char *const[]);
|
int (*real_execve)(const char *, char *const[], char *const[]);
|
||||||
|
int (*real_fork)(void);
|
||||||
|
int (*real_feof)(FILE *stream);
|
||||||
|
int (*real_ferror)(FILE *stream);
|
||||||
int (*real_pause)(void);
|
int (*real_pause)(void);
|
||||||
|
int (*real_unlink)(const char *);
|
||||||
|
FILE* (*real_fopen)(const char *path, const char *mode);
|
||||||
|
|
||||||
void _native_syscall_enter(void)
|
void _native_syscall_enter(void)
|
||||||
{
|
{
|
||||||
@ -334,3 +341,29 @@ int _gettimeofday(struct timeval *tp, void *restrict tzp) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set up native internal syscall symbols
|
||||||
|
*/
|
||||||
|
void _native_init_syscalls(void)
|
||||||
|
{
|
||||||
|
*(void **)(&real_read) = dlsym(RTLD_NEXT, "read");
|
||||||
|
*(void **)(&real_write) = dlsym(RTLD_NEXT, "write");
|
||||||
|
*(void **)(&real_malloc) = dlsym(RTLD_NEXT, "malloc");
|
||||||
|
*(void **)(&real_realloc) = dlsym(RTLD_NEXT, "realloc");
|
||||||
|
*(void **)(&real_free) = dlsym(RTLD_NEXT, "free");
|
||||||
|
*(void **)(&real_printf) = dlsym(RTLD_NEXT, "printf");
|
||||||
|
*(void **)(&real_getpid) = dlsym(RTLD_NEXT, "getpid");
|
||||||
|
*(void **)(&real_pipe) = dlsym(RTLD_NEXT, "pipe");
|
||||||
|
*(void **)(&real_close) = dlsym(RTLD_NEXT, "close");
|
||||||
|
*(void **)(&real_fork) = dlsym(RTLD_NEXT, "fork");
|
||||||
|
*(void **)(&real_dup2) = dlsym(RTLD_NEXT, "dup2");
|
||||||
|
*(void **)(&real_unlink) = dlsym(RTLD_NEXT, "unlink");
|
||||||
|
*(void **)(&real_execve) = dlsym(RTLD_NEXT, "execve");
|
||||||
|
*(void **)(&real_pause) = dlsym(RTLD_NEXT, "pause");
|
||||||
|
*(void **)(&real_fopen) = dlsym(RTLD_NEXT, "fopen");
|
||||||
|
*(void **)(&real_fread) = dlsym(RTLD_NEXT, "fread");
|
||||||
|
*(void **)(&real_feof) = dlsym(RTLD_NEXT, "feof");
|
||||||
|
*(void **)(&real_ferror) = dlsym(RTLD_NEXT, "ferror");
|
||||||
|
*(void **)(&real_clearerr) = dlsym(RTLD_NEXT, "clearerr");
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user