Skip to content
Snippets Groups Projects
Commit 12e55dda authored by Ludwig Knüpfer's avatar Ludwig Knüpfer
Browse files

Merge pull request #1445 from LudwigOrtmann/issue-476

native: uart reconnect buffer replay (+a little cleanup)
parents f2344a9b 3cda0369
No related branches found
No related tags found
No related merge requests found
...@@ -45,6 +45,9 @@ ...@@ -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) ...@@ -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 */
...@@ -197,7 +200,7 @@ void handle_uart_in(void) ...@@ -197,7 +200,7 @@ void handle_uart_in(void)
errx(EXIT_FAILURE, "handle_uart_in: unhandled situation!"); errx(EXIT_FAILURE, "handle_uart_in: unhandled situation!");
} }
} }
for(int pos = 0; pos < nread; pos++) { for (int pos = 0; pos < nread; pos++) {
uart0_handle_incoming(buf[pos]); uart0_handle_incoming(buf[pos]);
} }
uart0_notify_thread(); uart0_notify_thread();
...@@ -227,6 +230,34 @@ void handle_uart_sock(void) ...@@ -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) ...@@ -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); ...@@ -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 @@ ...@@ -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); ...@@ -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 @@ ...@@ -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; ...@@ -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) ...@@ -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) ...@@ -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"); ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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; ...@@ -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) { ...@@ -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");
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment