diff options
author | Jiri Olsa <Jiri Olsa jolsa@redhat.com> | 2010-04-03 16:11:07 +0200 |
---|---|---|
committer | Jiri Olsa <Jiri Olsa jolsa@redhat.com> | 2010-04-03 16:11:07 +0200 |
commit | 7ba0df8974d8a7bba3949f38134eeb14de36ba0a (patch) | |
tree | 2d98dd73621df0c3e7e67d80015fc02f91b4c6b5 /src | |
parent | 3396568982553a6547b4dca79d1258504c45ac41 (diff) | |
download | tsnif-7ba0df8974d8a7bba3949f38134eeb14de36ba0a.tar.gz tsnif-7ba0df8974d8a7bba3949f38134eeb14de36ba0a.tar.xz tsnif-7ba0df8974d8a7bba3949f38134eeb14de36ba0a.zip |
adding time for replay, few other fixies
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 8 | ||||
-rw-r--r-- | src/fsm.c | 6 | ||||
-rw-r--r-- | src/intf.h | 2 | ||||
-rw-r--r-- | src/misc.c | 19 | ||||
-rw-r--r-- | src/misc.h | 6 | ||||
-rw-r--r-- | src/storage-mmap.c | 30 | ||||
-rw-r--r-- | src/storage-mmap.h | 4 | ||||
-rw-r--r-- | src/storage.h | 3 | ||||
-rw-r--r-- | src/trans-libnl.c | 16 | ||||
-rw-r--r-- | src/trans.h | 4 | ||||
-rw-r--r-- | src/tsnif-replay.c | 185 | ||||
-rw-r--r-- | src/tsnif.c | 26 |
12 files changed, 261 insertions, 48 deletions
diff --git a/src/Makefile b/src/Makefile index db1703d..57b564c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -7,6 +7,9 @@ INTF_OBJS= \ STORAGE_OBJS= \ src/storage-mmap.o +MISC_OBJS= \ + src/misc.o + INTF_LIB=-lnl @@ -15,14 +18,14 @@ TSNIF=tsnif TSNIF_OBJS= \ src/tsnif.o -$(TSNIF): $(TSNIF_OBJS) $(INTF_OBJS) $(STORAGE_OBJS) +$(TSNIF): $(TSNIF_OBJS) $(INTF_OBJS) $(STORAGE_OBJS) $(MISC_OBJS) $(QUIET_LD)$(CC) -o $@ $^ $(INTF_LIB) TSNIF_REPLAY=tsnif-replay TSNIF_REPLAY_OBJS= \ src/tsnif-replay.o -$(TSNIF_REPLAY): $(TSNIF_REPLAY_OBJS) $(STORAGE_OBJS) +$(TSNIF_REPLAY): $(TSNIF_REPLAY_OBJS) $(STORAGE_OBJS) $(MISC_OBJS) $(QUIET_LD)$(CC) -o $@ $^ @@ -52,6 +55,7 @@ $(TEST): $(TEST_OBJS) OBJS= \ $(INTF_OBJS) \ $(STORAGE_OBJS) \ + $(MISC_OBJS) \ $(TSNIF_OBJS) \ $(TSNIF_REPLAY_OBJS) \ $(TSNIFD_OBJS) \ @@ -47,9 +47,11 @@ static int process_data(struct tsnif_handle *h, if (!h->ops || !h->ops->cb_data) return -1; - data.ptr = msg->data.ptr; - data.len = msg->data.len; + data.ptr = msg->data.ptr; + data.len = msg->data.len; data.flags = msg->data.flags; + data.time = msg->data.time; + data.ws = msg->data.ws; return h->ops->cb_data(term, &data); } @@ -35,6 +35,8 @@ struct tsnif_data { void *ptr; int len; uint flags; + struct timespec time; + struct winsize ws; }; typedef int(*cb_data_t)(struct tsnif_term *term, struct tsnif_data *data); diff --git a/src/misc.c b/src/misc.c new file mode 100644 index 0000000..91d1266 --- /dev/null +++ b/src/misc.c @@ -0,0 +1,19 @@ + +#include <termios.h> +#include <unistd.h> + +int set_term(int set_init) +{ + struct termios new_settings; + static struct termios init_settings; + + if (set_init) + return tcsetattr(0, TCSANOW, &init_settings); + + tcgetattr(0, &init_settings); + new_settings = init_settings; + new_settings.c_lflag &= ~ICANON; + new_settings.c_lflag &= ~ECHO; + + return tcsetattr(0, TCSANOW, &new_settings); +} diff --git a/src/misc.h b/src/misc.h new file mode 100644 index 0000000..a0b6012 --- /dev/null +++ b/src/misc.h @@ -0,0 +1,6 @@ +#ifndef MISC_H +#define MISC_H + +int set_term(int set_init); + +#endif /* !MISC_H */ diff --git a/src/storage-mmap.c b/src/storage-mmap.c index f5e73ab..6fa4565 100644 --- a/src/storage-mmap.c +++ b/src/storage-mmap.c @@ -36,9 +36,13 @@ static int write_header(int fd, struct tsnif_storage_opts *opts) static int map_header(struct tsnif_storage_handle *h) { void *ptr; + int flags = PROT_READ; + + if (h->opts->flags & TSNIF_STORAGE_OPT_WRITE) + flags = PROT_WRITE; ptr = mmap(NULL, sysconf(_SC_PAGESIZE), - PROT_WRITE | PROT_READ, + flags, MAP_SHARED, h->fd, 0); if (MAP_FAILED == ptr) return -1; @@ -51,7 +55,7 @@ int tsnif_storage_init(struct tsnif_storage_handle *h, struct tsnif_storage_opts *opts, char *name) { int fd, create, err; - int flags = O_RDWR; + int flags = O_RDONLY; if (!opts) return -1; @@ -65,9 +69,9 @@ int tsnif_storage_init(struct tsnif_storage_handle *h, create = (opts->flags & TSNIF_STORAGE_OPT_WRITE); if (create) - flags |= O_CREAT | O_TRUNC; + flags |= O_CREAT | O_TRUNC | O_RDWR; - fd = open(name, flags, S_IRUSR | S_IWUSR); + fd = open(name, flags); if (fd < 0) { TSNIF_DEBUG("open failed for '%s': %s\n", name, strerror(errno)); @@ -165,7 +169,8 @@ static int map_chunk(struct tsnif_storage_handle *h, { void *ptr; off_t offset = 0; - int err; + int err, flags = PROT_READ; + TSNIF_DEBUG("what %d\n", what); @@ -231,10 +236,12 @@ static int map_chunk(struct tsnif_storage_handle *h, err = file_trunc(h, offset + h->opts->chunk_size); if (err) return err; + + flags = PROT_WRITE; } ptr = mmap(NULL, h->opts->chunk_size, - PROT_WRITE | PROT_READ, + flags, MAP_SHARED, h->fd, offset); if (MAP_FAILED == ptr) return -1; @@ -356,10 +363,13 @@ static int store_rec(struct tsnif_storage_handle *h, TSNIF_DEBUG("chunk data %p\n", chunk->current_data); TSNIF_DEBUG("chunk index %p\n", chunk->current_index); + TSNIF_DEBUG("time %ld\n", rec->time.tv_sec); mrec = chunk->current_data; - mrec->len = rec->len; + mrec->len = rec->len; mrec->flags = rec->flags; + mrec->time = rec->time; + mrec->ws = rec->ws; memcpy(mrec->data, rec->ptr, rec->len); #define RECLEN (sizeof(struct tsnif_storage_rec_mmap) + rec->len) @@ -414,9 +424,11 @@ static int read_rec(struct tsnif_storage_handle *h, offset = *(chunk->current_index - chunk->read_index); mrec = (void*) header + offset; - rec->ptr = mrec->data; - rec->len = mrec->len; + rec->ptr = mrec->data; + rec->len = mrec->len; rec->flags = mrec->flags; + rec->time = mrec->time; + rec->ws = mrec->ws; return 0; } diff --git a/src/storage-mmap.h b/src/storage-mmap.h index db45cb0..8b00934 100644 --- a/src/storage-mmap.h +++ b/src/storage-mmap.h @@ -2,6 +2,8 @@ #ifndef STORAGE_MMAP_H #define STORAGE_MMAP_H +#include <sys/ioctl.h> + struct tsnif_storage_header_mmap { struct tsnif_storage_header common; /* max size of the file */ @@ -15,6 +17,8 @@ struct tsnif_storage_header_mmap { struct tsnif_storage_rec_mmap { uint32_t len; uint32_t flags; + struct timespec time; + struct winsize ws; unsigned char data[]; }; diff --git a/src/storage.h b/src/storage.h index 54df8fa..2099059 100644 --- a/src/storage.h +++ b/src/storage.h @@ -3,6 +3,7 @@ #include <stdlib.h> #include <stdint.h> +#include <sys/ioctl.h> struct tsnif_storage_handle; struct tsnif_storage_opts; @@ -33,6 +34,8 @@ struct tsnif_storage_rec { void *ptr; int len; uint flags; + struct timespec time; + struct winsize ws; }; int tsnif_storage_init(struct tsnif_storage_handle *h, diff --git a/src/trans-libnl.c b/src/trans-libnl.c index d4b814b..c6e3b90 100644 --- a/src/trans-libnl.c +++ b/src/trans-libnl.c @@ -45,6 +45,22 @@ static int process_cb(struct trans_handle *h, struct trans_msg *m, m->data.len = nla_len(attrs[TSNIF_ATTR_DATA]); } + if (attrs[TSNIF_ATTR_TIME]) { + struct timespec *time; + + time = (struct timespec*) nla_data(attrs[TSNIF_ATTR_TIME]); + m->data.time = *(time); + TSNIF_DEBUG("time1 %ld %ld\n", time->tv_sec, time->tv_nsec); + TSNIF_DEBUG("time2 %ld\n", m->data.time.tv_sec); + } + + if (attrs[TSNIF_ATTR_WS]) { + struct winsize *ws; + + ws = (struct winsize*) nla_data(attrs[TSNIF_ATTR_WS]); + m->data.ws = *(ws); + } + if (attrs[TSNIF_ATTR_FLAGS]) m->data.flags = nla_get_u32(attrs[TSNIF_ATTR_FLAGS]); diff --git a/src/trans.h b/src/trans.h index 95b4457..e7c38bc 100644 --- a/src/trans.h +++ b/src/trans.h @@ -2,6 +2,8 @@ #ifndef TRANS_H #define TRANS_H +#include <sys/ioctl.h> + struct trans_handle; struct trans_msg; @@ -26,6 +28,8 @@ struct trans_msg { void *ptr; int len; uint flags; + struct timespec time; + struct winsize ws; } data; /* notify message */ int action; diff --git a/src/tsnif-replay.c b/src/tsnif-replay.c index 0f1455f..a0ec61e 100644 --- a/src/tsnif-replay.c +++ b/src/tsnif-replay.c @@ -1,13 +1,20 @@ #include <stdio.h> +#include <stdio_ext.h> #include <unistd.h> #include <getopt.h> +#include <sys/select.h> +#include <setjmp.h> +#include <string.h> +#include <signal.h> #include "storage.h" +#include "misc.h" +#include "intf.h" - +static int killed; static char *filename; -struct tsnif_storage_handle storage_handle; +static struct tsnif_storage_handle storage_handle; static struct tsnif_storage_opts storage_opts = { .flags = TSNIF_STORAGE_OPT_READ, }; @@ -20,6 +27,12 @@ static void usage() _exit(-1); } +static void sig_handler(int sig) +{ + printf("killed\n"); + killed = 1; +} + static int get_args(int argc, char **argv) { while (1) { @@ -59,9 +72,153 @@ static int get_args(int argc, char **argv) return 0; } +static struct timeval get_timeout(struct timespec *ts_new, + struct timespec *ts_old) +{ + static struct timeval tv; + + tv.tv_sec = ts_new->tv_sec - ts_old->tv_sec; + + TSNIF_DEBUG("time new %ld:%ld\n", ts_new->tv_sec, ts_new->tv_nsec); + TSNIF_DEBUG("time old %ld:%ld\n", ts_old->tv_sec, ts_old->tv_nsec); + + if (ts_new->tv_nsec >= ts_old->tv_nsec) + tv.tv_usec = (ts_new->tv_nsec - ts_old->tv_nsec) / 1000; + else { + tv.tv_usec = (ts_new->tv_nsec + (1000000000 - ts_old->tv_nsec)) / 1000; + if (tv.tv_sec) + tv.tv_sec--; + } + + TSNIF_DEBUG("time fin %ld %ld\n", tv.tv_sec, tv.tv_usec); + return tv; +} + +enum { + ACTION_NEXT, + ACTION_PREV, + ACTION_FIRST, + ACTION_TIMEOUT, + ACTION_STOP, + ACTION_RUN, + ACTION_QUIT, + ACTION_SLAVE, + ACTION_MASTER, +}; + +static int display_slave = 1; +static int display_master= 0; + +static int output(struct tsnif_storage_rec *rec) +{ + fwrite(rec->ptr, rec->len, 1, stdout); + fflush(NULL); + return 0; +} + +static int get_action(struct timeval *tv) +{ + int c, ret; + jmp_buf env; + fd_set rfds; + + setjmp(env); + + FD_ZERO(&rfds); + FD_SET(0, &rfds); + + ret = select(1, &rfds, NULL, NULL, tv); + + /* select failed - finish replay */ + if (-1 == ret) + return ACTION_QUIT; + + /* timeout - continue with next record */ + if (!ret) + return ACTION_NEXT; + + /* WTF??? */ + if (!FD_ISSET(0, &rfds)) + return ACTION_QUIT; + + /* we got user input */ + c = getchar(); + + if (c == '\033') { + __fpurge(stdin); + longjmp(env, 1); + } + + switch(c) { + case 'p' : return ACTION_PREV; + case 'n' : return ACTION_NEXT; + case 'f' : return ACTION_FIRST; + case 'q' : return ACTION_QUIT; + case 't' : return ACTION_TIMEOUT; + case 's' : return ACTION_SLAVE; + case 'm' : return ACTION_MASTER; + } + + longjmp(env, 1); + return -1; +} + +static int process(void) +{ + struct tsnif_storage_rec rec; + int err, action; + + err = tsnif_storage_read(&storage_handle, + TSNIF_STORAGE_READ_NEXT, &rec); + if (err < 0) + return err; + + do { + struct timespec ts_prev; + struct timeval tv; + + memset(&tv, 0x0, sizeof(tv)); + + if (err != TSNIF_STORAGE_READ_EOF) { + output(&rec); + + ts_prev = rec.time; + + err = tsnif_storage_read(&storage_handle, + TSNIF_STORAGE_READ_NEXT, &rec); + if (err < 0) + break; + + tv = get_timeout(&rec.time, &ts_prev); + } + + action = get_action(&tv); + switch(action) { + case ACTION_PREV: + err = tsnif_storage_read(&storage_handle, + TSNIF_STORAGE_READ_PREV, &rec); + if (err < 0) + return err; + break; + + case ACTION_SLAVE: + display_slave = !display_slave; + break; + + case ACTION_MASTER: + display_master = !display_master; + break; + } + + } while(action != ACTION_QUIT); + + return 0; +} + int main(int argc, char **argv) { - int err; + int err, ret; + jmp_buf env; if (get_args(argc, argv)) usage(); @@ -70,20 +227,18 @@ int main(int argc, char **argv) if (err) return -1; - do { - struct tsnif_storage_rec rec; - - err = tsnif_storage_read(&storage_handle, - TSNIF_STORAGE_READ_NEXT, &rec); + if ((ret = setjmp(env))) { + set_term(1); + tsnif_storage_close(&storage_handle); - if (err) - break; + printf("done err = %d\n", err); + return err; + } - fwrite(rec.ptr, rec.len, 1, stdout); - fflush(NULL); + set_term(0); + signal(SIGINT, sig_handler); - } while(1); + err = process(); - tsnif_storage_close(&storage_handle); - return 0; + longjmp(env, 1); } diff --git a/src/tsnif.c b/src/tsnif.c index 57731f2..aca8e56 100644 --- a/src/tsnif.c +++ b/src/tsnif.c @@ -11,7 +11,7 @@ #include "autoconf.h" #include "intf.h" #include "storage.h" - +#include "misc.h" static struct tsnif_handle handle; static struct tsnif_term term; @@ -46,9 +46,11 @@ static int display_pty(int flags) static int store_data(struct tsnif_data *data) { struct tsnif_storage_rec rec = { - .ptr = data->ptr, - .len = data->len, - .flags = data->flags, + .ptr = data->ptr, + .len = data->len, + .flags = data->flags, + .time = data->time, + .ws = data->ws, }; return tsnif_storage_write(&storage_handle, &rec); @@ -105,22 +107,6 @@ static void sig_handler(int sig) killed = 1; } -int set_term(int set_init) -{ - struct termios new_settings; - static struct termios init_settings; - - if (set_init) - return tcsetattr(0, TCSANOW, &init_settings); - - tcgetattr(0, &init_settings); - new_settings = init_settings; - new_settings.c_lflag &= ~ICANON; - new_settings.c_lflag &= ~ECHO; - - return tcsetattr(0, TCSANOW, &new_settings); -} - static int get_type(char *optarg) { int i; |