From 01e26ce3a837d7b1a4c2168c8118505b4b9cf525 Mon Sep 17 00:00:00 2001 From: Daniel Beer Date: Tue, 30 Mar 2010 15:54:03 +1300 Subject: [PATCH] Merged parse.[ch] into util.[ch]. --- Makefile | 2 +- dis.c | 1 - main.c | 2 - parse.c | 428 ----------------------------------------------------- parse.h | 109 -------------- sim.c | 1 - util.c | 441 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- util.h | 93 +++++++++++- 8 files changed, 513 insertions(+), 564 deletions(-) delete mode 100644 parse.c delete mode 100644 parse.h diff --git a/Makefile b/Makefile index 63d5f61..e8dc5ef 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ install: mspdebug mspdebug.man .SUFFIXES: .c .o mspdebug: main.o fet.o rf2500.o dis.o uif.o ihex.o elf32.o stab.o util.o \ - bsl.o sim.o symmap.o gdb.o btree.o parse.o + bsl.o sim.o symmap.o gdb.o btree.o $(CC) $(LDFLAGS) -o $@ $^ -lusb $(READLINE_LIBS) .c.o: diff --git a/dis.c b/dis.c index ba73bc9..641fc64 100644 --- a/dis.c +++ b/dis.c @@ -23,7 +23,6 @@ #include "dis.h" #include "stab.h" #include "util.h" -#include "parse.h" /**********************************************************************/ /* Disassembler diff --git a/main.c b/main.c index 77e279e..8675fac 100644 --- a/main.c +++ b/main.c @@ -29,7 +29,6 @@ #include "stab.h" #include "util.h" #include "gdb.h" -#include "parse.h" static const struct device *msp430_dev; @@ -1000,7 +999,6 @@ int main(int argc, char **argv) } parse_init(); - ctrlc_init(); if (stab_init() < 0) return -1; diff --git a/parse.c b/parse.c deleted file mode 100644 index 55fa6dd..0000000 --- a/parse.c +++ /dev/null @@ -1,428 +0,0 @@ -/* MSPDebug - debugging tool for MSP430 MCUs - * Copyright (C) 2009, 2010 Daniel Beer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include - -#ifdef USE_READLINE -#include -#include -#endif - -#include "stab.h" -#include "parse.h" - -static struct option *option_list; - -void register_option(struct option *o) -{ - o->next = option_list; - option_list = o; -} - -static struct option *find_option(const char *name) -{ - struct option *o; - - for (o = option_list; o; o = o->next) - if (!strcasecmp(o->name, name)) - return o; - - return NULL; -} - -static int interactive_call; - -int is_interactive(void) -{ - return interactive_call; -} - -char *get_arg(char **text) -{ - char *start; - char *end; - - if (!text) - return NULL; - - start = *text; - while (*start && isspace(*start)) - start++; - - if (!*start) - return NULL; - - end = start; - while (*end && !isspace(*end)) - end++; - - if (*end) - while (*end && isspace(*end)) - *(end++) = 0; - - *text = end; - return start; -} - -const struct command *find_command(const char *name) -{ - int i; - - for (i = 0; all_commands[i].name; i++) - if (!strcasecmp(name, all_commands[i].name)) - return &all_commands[i]; - - return NULL; -} - -int process_command(char *arg, int interactive) -{ - const char *cmd_text; - int len = strlen(arg); - - while (len && isspace(arg[len - 1])) - len--; - arg[len] = 0; - - cmd_text = get_arg(&arg); - if (cmd_text) { - const struct command *cmd = find_command(cmd_text); - - if (cmd) { - int old = interactive_call; - int ret; - - interactive_call = interactive; - ret = cmd->func(&arg); - interactive_call = old; - return 0; - } - - fprintf(stderr, "unknown command: %s (try \"help\")\n", - cmd_text); - return -1; - } - - return 0; -} - -#ifndef USE_READLINE -#define LINE_BUF_SIZE 128 - -static char *readline(const char *prompt) -{ - char *buf = malloc(LINE_BUF_SIZE); - - if (!buf) { - perror("readline: can't allocate memory"); - return NULL; - } - - for (;;) { - printf("(mspdebug) "); - fflush(stdout); - - if (fgets(buf, LINE_BUF_SIZE, stdin)) - return buf; - - if (feof(stdin)) - break; - - printf("\n"); - } - - free(buf); - return NULL; -} - -#define add_history(x) -#endif - -void reader_loop(void) -{ - printf("\n"); - cmd_help(NULL); - - for (;;) { - char *buf = readline("(mspdebug) "); - - if (!buf) - break; - - add_history(buf); - process_command(buf, 1); - free(buf); - } - - printf("\n"); -} - -const char *type_text(option_type_t type) -{ - switch (type) { - case OPTION_BOOLEAN: - return "boolean"; - - case OPTION_NUMERIC: - return "numeric"; - - case OPTION_TEXT: - return "text"; - } - - return "unknown"; -} - -int cmd_help(char **arg) -{ - char *topic = get_arg(arg); - - if (topic) { - const struct command *cmd = find_command(topic); - const struct option *opt = find_option(topic); - - if (cmd) { - printf("COMMAND: %s\n", cmd->name); - fputs(cmd->help, stdout); - if (opt) - printf("\n"); - } - - if (opt) { - printf("OPTION: %s (%s)\n", opt->name, - type_text(opt->type)); - fputs(opt->help, stdout); - } - - if (!(cmd || opt)) { - fprintf(stderr, "help: unknown command: %s\n", topic); - return -1; - } - } else { - int i; - int max_len = 0; - int rows, cols; - int total = 0; - - for (i = 0; all_commands[i].name; i++) { - int len = strlen(all_commands[i].name); - - if (len > max_len) - max_len = len; - total++; - } - - max_len += 2; - cols = 72 / max_len; - rows = (total + cols - 1) / cols; - - printf("Available commands:\n"); - for (i = 0; i < rows; i++) { - int j; - - printf(" "); - for (j = 0; j < cols; j++) { - int k = j * rows + i; - const struct command *cmd = &all_commands[k]; - - if (k >= total) - break; - - printf("%s", cmd->name); - for (k = strlen(cmd->name); k < max_len; k++) - printf(" "); - } - - printf("\n"); - } - - printf("Type \"help \" for more information.\n"); - printf("Press Ctrl+D to quit.\n"); - } - - return 0; -} - -static char token_buf[64]; -static int token_len; -static int token_mult; -static int token_sum; - -static int token_add(void) -{ - int i; - u_int16_t value; - - if (!token_len) - return 0; - - token_buf[token_len] = 0; - token_len = 0; - - /* Is it a decimal? */ - i = 0; - while (token_buf[i] && isdigit(token_buf[i])) - i++; - if (!token_buf[i]) { - token_sum += token_mult * atoi(token_buf); - return 0; - } - - /* Is it hex? */ - if (token_buf[0] == '0' && tolower(token_buf[1]) == 'x') { - token_sum += token_mult * strtol(token_buf + 2, NULL, 16); - return 0; - } - - /* Look up the name in the symbol table */ - if (!stab_get(token_buf, &value)) { - token_sum += token_mult * value; - return 0; - } - - fprintf(stderr, "unknown token: %s\n", token_buf); - return -1; -} - -int addr_exp(const char *text, int *addr) -{ - token_len = 0; - token_mult = 1; - token_sum = 0; - - while (*text) { - if (isalnum(*text) || *text == '_' || *text == '$' || - *text == '.' || *text == ':') { - if (token_len + 1 < sizeof(token_buf)) - token_buf[token_len++] = *text; - } else { - if (token_add() < 0) - return -1; - if (*text == '+') - token_mult = 1; - if (*text == '-') - token_mult = -1; - } - - text++; - } - - if (token_add() < 0) - return -1; - - *addr = token_sum & 0xffff; - return 0; -} - -static void display_option(const struct option *o) -{ - printf("%32s = ", o->name); - - switch (o->type) { - case OPTION_BOOLEAN: - printf("%s", o->data.numeric ? "true" : "false"); - break; - - case OPTION_NUMERIC: - printf("0x%x (%d)", o->data.numeric, - o->data.numeric); - break; - - case OPTION_TEXT: - printf("%s", o->data.text); - break; - } - - printf("\n"); -} - -static int parse_option(struct option *o, const char *word) -{ - switch (o->type) { - case OPTION_BOOLEAN: - o->data.numeric = (isdigit(word[0]) && word[0] > '0') || - word[0] == 't' || word[0] == 'y' || - (word[0] == 'o' && word[1] == 'n'); - break; - - case OPTION_NUMERIC: - return addr_exp(word, &o->data.numeric); - - case OPTION_TEXT: - strncpy(o->data.text, word, sizeof(o->data.text)); - o->data.text[sizeof(o->data.text) - 1] = 0; - break; - } - - return 0; -} - -int cmd_opt(char **arg) -{ - const char *opt_text = get_arg(arg); - struct option *opt = NULL; - - if (opt_text) { - opt = find_option(opt_text); - if (!opt) { - fprintf(stderr, "opt: no such option: %s\n", - opt_text); - return -1; - } - } - - if (**arg) { - if (parse_option(opt, *arg) < 0) { - fprintf(stderr, "opt: can't parse option: %s\n", - *arg); - return -1; - } - } else if (opt_text) { - display_option(opt); - } else { - struct option *o; - - for (o = option_list; o; o = o->next) - display_option(o); - } - - return 0; -} - -static struct option option_color = { - .name = "color", - .type = OPTION_BOOLEAN, - .help = "Colorize disassembly output.\n" -}; - -int colorize(const char *text) -{ - if (!option_color.data.numeric) - return 0; - - return printf("\x1b[%s", text); -} - -void parse_init(void) -{ - register_option(&option_color); -} diff --git a/parse.h b/parse.h deleted file mode 100644 index 301089f..0000000 --- a/parse.h +++ /dev/null @@ -1,109 +0,0 @@ -/* MSPDebug - debugging tool for MSP430 MCUs - * Copyright (C) 2009, 2010 Daniel Beer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PARSE_H_ -#define PARSE_H_ - -typedef int (*command_func_t)(char **arg); - -struct command { - const char *name; - int (*func)(char **arg); - const char *help; -}; - -/* The global command table, defined in main.c */ -extern const struct command all_commands[]; - -/* Retrieve the next word from a pointer to the rest of a command - * argument buffer. Returns NULL if no more words. - */ -char *get_arg(char **text); - -/* Process a command, returning -1 on error or 0 if executed - * successfully. - * - * The interactive argument specifies whether or not the command - * should be executed in an interactive context. - */ -int process_command(char *arg, int interactive); - -/* Run the reader loop, exiting when the user presses Ctrl+D. - * - * Commands executed by the reader loop are executed in interactive - * context. - */ -void reader_loop(void); - -/* Help command. Displays a command list with no argument, or help - * for a particular command. - */ -int cmd_help(char **arg); - -/* Colourized output has been requested by the user. */ -int colorize(const char *text); - -/* Return non-zero if executing in an interactive context. */ -int is_interactive(void); - -/* Parse an address expression, storing the result in the integer - * pointed to. Returns 0 if parsed successfully, -1 if not. - */ -int addr_exp(const char *text, int *value); - -/* Options interface. Options may be declared by any module and - * registered with the parser. - * - * They can then be manipulated by the "set" command (function - * declared below. - */ - -typedef enum { - OPTION_BOOLEAN, - OPTION_NUMERIC, - OPTION_TEXT -} option_type_t; - -struct option { - const char *name; - option_type_t type; - const char *help; - - union { - char text[128]; - int numeric; - } data; - - struct option *next; -}; - -/* Add an option to the parser's list. Options can't be removed from - * the list once added. - */ -void register_option(struct option *o); - -/* Command function for settings options. With no arguments, displays - * a list of available options. - */ -int cmd_opt(char **arg); - -/* Initialise the parser, and register built-ins. */ -void parse_init(void); - -#endif - diff --git a/sim.c b/sim.c index 386ae57..7475164 100644 --- a/sim.c +++ b/sim.c @@ -24,7 +24,6 @@ #include "dis.h" #include "util.h" #include "stab.h" -#include "parse.h" #define MEM_SIZE 65536 diff --git a/util.c b/util.c index 47235fe..501d2e3 100644 --- a/util.c +++ b/util.c @@ -1,4 +1,4 @@ -/* MSPDebug - debugging tool for the eZ430 +/* MSPDebug - debugging tool for MSP430 MCUs * Copyright (C) 2009, 2010 Daniel Beer * * This program is free software; you can redistribute it and/or modify @@ -17,14 +17,436 @@ */ #include +#include +#include +#include +#include #include #include #include #include #include #include + +#ifdef USE_READLINE +#include +#include +#endif + +#include "stab.h" #include "util.h" +static struct option *option_list; + +void register_option(struct option *o) +{ + o->next = option_list; + option_list = o; +} + +static struct option *find_option(const char *name) +{ + struct option *o; + + for (o = option_list; o; o = o->next) + if (!strcasecmp(o->name, name)) + return o; + + return NULL; +} + +static int interactive_call; + +int is_interactive(void) +{ + return interactive_call; +} + +char *get_arg(char **text) +{ + char *start; + char *end; + + if (!text) + return NULL; + + start = *text; + while (*start && isspace(*start)) + start++; + + if (!*start) + return NULL; + + end = start; + while (*end && !isspace(*end)) + end++; + + if (*end) + while (*end && isspace(*end)) + *(end++) = 0; + + *text = end; + return start; +} + +const struct command *find_command(const char *name) +{ + int i; + + for (i = 0; all_commands[i].name; i++) + if (!strcasecmp(name, all_commands[i].name)) + return &all_commands[i]; + + return NULL; +} + +int process_command(char *arg, int interactive) +{ + const char *cmd_text; + int len = strlen(arg); + + while (len && isspace(arg[len - 1])) + len--; + arg[len] = 0; + + cmd_text = get_arg(&arg); + if (cmd_text) { + const struct command *cmd = find_command(cmd_text); + + if (cmd) { + int old = interactive_call; + int ret; + + interactive_call = interactive; + ret = cmd->func(&arg); + interactive_call = old; + return 0; + } + + fprintf(stderr, "unknown command: %s (try \"help\")\n", + cmd_text); + return -1; + } + + return 0; +} + +#ifndef USE_READLINE +#define LINE_BUF_SIZE 128 + +static char *readline(const char *prompt) +{ + char *buf = malloc(LINE_BUF_SIZE); + + if (!buf) { + perror("readline: can't allocate memory"); + return NULL; + } + + for (;;) { + printf("(mspdebug) "); + fflush(stdout); + + if (fgets(buf, LINE_BUF_SIZE, stdin)) + return buf; + + if (feof(stdin)) + break; + + printf("\n"); + } + + free(buf); + return NULL; +} + +#define add_history(x) +#endif + +void reader_loop(void) +{ + printf("\n"); + cmd_help(NULL); + + for (;;) { + char *buf = readline("(mspdebug) "); + + if (!buf) + break; + + add_history(buf); + process_command(buf, 1); + free(buf); + } + + printf("\n"); +} + +const char *type_text(option_type_t type) +{ + switch (type) { + case OPTION_BOOLEAN: + return "boolean"; + + case OPTION_NUMERIC: + return "numeric"; + + case OPTION_TEXT: + return "text"; + } + + return "unknown"; +} + +int cmd_help(char **arg) +{ + char *topic = get_arg(arg); + + if (topic) { + const struct command *cmd = find_command(topic); + const struct option *opt = find_option(topic); + + if (cmd) { + printf("COMMAND: %s\n", cmd->name); + fputs(cmd->help, stdout); + if (opt) + printf("\n"); + } + + if (opt) { + printf("OPTION: %s (%s)\n", opt->name, + type_text(opt->type)); + fputs(opt->help, stdout); + } + + if (!(cmd || opt)) { + fprintf(stderr, "help: unknown command: %s\n", topic); + return -1; + } + } else { + int i; + int max_len = 0; + int rows, cols; + int total = 0; + + for (i = 0; all_commands[i].name; i++) { + int len = strlen(all_commands[i].name); + + if (len > max_len) + max_len = len; + total++; + } + + max_len += 2; + cols = 72 / max_len; + rows = (total + cols - 1) / cols; + + printf("Available commands:\n"); + for (i = 0; i < rows; i++) { + int j; + + printf(" "); + for (j = 0; j < cols; j++) { + int k = j * rows + i; + const struct command *cmd = &all_commands[k]; + + if (k >= total) + break; + + printf("%s", cmd->name); + for (k = strlen(cmd->name); k < max_len; k++) + printf(" "); + } + + printf("\n"); + } + + printf("Type \"help \" for more information.\n"); + printf("Press Ctrl+D to quit.\n"); + } + + return 0; +} + +static char token_buf[64]; +static int token_len; +static int token_mult; +static int token_sum; + +static int token_add(void) +{ + int i; + u_int16_t value; + + if (!token_len) + return 0; + + token_buf[token_len] = 0; + token_len = 0; + + /* Is it a decimal? */ + i = 0; + while (token_buf[i] && isdigit(token_buf[i])) + i++; + if (!token_buf[i]) { + token_sum += token_mult * atoi(token_buf); + return 0; + } + + /* Is it hex? */ + if (token_buf[0] == '0' && tolower(token_buf[1]) == 'x') { + token_sum += token_mult * strtol(token_buf + 2, NULL, 16); + return 0; + } + + /* Look up the name in the symbol table */ + if (!stab_get(token_buf, &value)) { + token_sum += token_mult * value; + return 0; + } + + fprintf(stderr, "unknown token: %s\n", token_buf); + return -1; +} + +int addr_exp(const char *text, int *addr) +{ + token_len = 0; + token_mult = 1; + token_sum = 0; + + while (*text) { + if (isalnum(*text) || *text == '_' || *text == '$' || + *text == '.' || *text == ':') { + if (token_len + 1 < sizeof(token_buf)) + token_buf[token_len++] = *text; + } else { + if (token_add() < 0) + return -1; + if (*text == '+') + token_mult = 1; + if (*text == '-') + token_mult = -1; + } + + text++; + } + + if (token_add() < 0) + return -1; + + *addr = token_sum & 0xffff; + return 0; +} + +static void display_option(const struct option *o) +{ + printf("%32s = ", o->name); + + switch (o->type) { + case OPTION_BOOLEAN: + printf("%s", o->data.numeric ? "true" : "false"); + break; + + case OPTION_NUMERIC: + printf("0x%x (%d)", o->data.numeric, + o->data.numeric); + break; + + case OPTION_TEXT: + printf("%s", o->data.text); + break; + } + + printf("\n"); +} + +static int parse_option(struct option *o, const char *word) +{ + switch (o->type) { + case OPTION_BOOLEAN: + o->data.numeric = (isdigit(word[0]) && word[0] > '0') || + word[0] == 't' || word[0] == 'y' || + (word[0] == 'o' && word[1] == 'n'); + break; + + case OPTION_NUMERIC: + return addr_exp(word, &o->data.numeric); + + case OPTION_TEXT: + strncpy(o->data.text, word, sizeof(o->data.text)); + o->data.text[sizeof(o->data.text) - 1] = 0; + break; + } + + return 0; +} + +int cmd_opt(char **arg) +{ + const char *opt_text = get_arg(arg); + struct option *opt = NULL; + + if (opt_text) { + opt = find_option(opt_text); + if (!opt) { + fprintf(stderr, "opt: no such option: %s\n", + opt_text); + return -1; + } + } + + if (**arg) { + if (parse_option(opt, *arg) < 0) { + fprintf(stderr, "opt: can't parse option: %s\n", + *arg); + return -1; + } + } else if (opt_text) { + display_option(opt); + } else { + struct option *o; + + for (o = option_list; o; o = o->next) + display_option(o); + } + + return 0; +} + +static struct option option_color = { + .name = "color", + .type = OPTION_BOOLEAN, + .help = "Colorize disassembly output.\n" +}; + +int colorize(const char *text) +{ + if (!option_color.data.numeric) + return 0; + + return printf("\x1b[%s", text); +} + +static volatile int ctrlc_flag; + +static void sigint_handler(int signum) +{ + ctrlc_flag = 1; +} + + +void parse_init(void) +{ + const static struct sigaction siga = { + .sa_handler = sigint_handler, + .sa_flags = 0 + }; + + sigaction(SIGINT, &siga, NULL); + register_option(&option_color); +} + void hexdump(int addr, const u_int8_t *data, int len) { int offset = 0; @@ -177,23 +599,6 @@ int open_serial(const char *device, int rate) return fd; } -static volatile int ctrlc_flag; - -static void sigint_handler(int signum) -{ - ctrlc_flag = 1; -} - -void ctrlc_init(void) -{ - const static struct sigaction siga = { - .sa_handler = sigint_handler, - .sa_flags = 0 - }; - - sigaction(SIGINT, &siga, NULL); -} - void ctrlc_reset(void) { ctrlc_flag = 0; diff --git a/util.h b/util.h index a474b20..acb3739 100644 --- a/util.h +++ b/util.h @@ -1,4 +1,4 @@ -/* MSPDebug - debugging tool for the eZ430 +/* MSPDebug - debugging tool for MSP430 MCUs * Copyright (C) 2009, 2010 Daniel Beer * * This program is free software; you can redistribute it and/or modify @@ -16,11 +16,97 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef UTIL_H_ -#define UTIL_H_ +#ifndef PARSE_H_ +#define PARSE_H_ #include +typedef int (*command_func_t)(char **arg); + +struct command { + const char *name; + int (*func)(char **arg); + const char *help; +}; + +/* The global command table, defined in main.c */ +extern const struct command all_commands[]; + +/* Retrieve the next word from a pointer to the rest of a command + * argument buffer. Returns NULL if no more words. + */ +char *get_arg(char **text); + +/* Process a command, returning -1 on error or 0 if executed + * successfully. + * + * The interactive argument specifies whether or not the command + * should be executed in an interactive context. + */ +int process_command(char *arg, int interactive); + +/* Run the reader loop, exiting when the user presses Ctrl+D. + * + * Commands executed by the reader loop are executed in interactive + * context. + */ +void reader_loop(void); + +/* Help command. Displays a command list with no argument, or help + * for a particular command. + */ +int cmd_help(char **arg); + +/* Colourized output has been requested by the user. */ +int colorize(const char *text); + +/* Return non-zero if executing in an interactive context. */ +int is_interactive(void); + +/* Parse an address expression, storing the result in the integer + * pointed to. Returns 0 if parsed successfully, -1 if not. + */ +int addr_exp(const char *text, int *value); + +/* Options interface. Options may be declared by any module and + * registered with the parser. + * + * They can then be manipulated by the "set" command (function + * declared below. + */ + +typedef enum { + OPTION_BOOLEAN, + OPTION_NUMERIC, + OPTION_TEXT +} option_type_t; + +struct option { + const char *name; + option_type_t type; + const char *help; + + union { + char text[128]; + int numeric; + } data; + + struct option *next; +}; + +/* Add an option to the parser's list. Options can't be removed from + * the list once added. + */ +void register_option(struct option *o); + +/* Command function for settings options. With no arguments, displays + * a list of available options. + */ +int cmd_opt(char **arg); + +/* Initialise the parser, and register built-ins. */ +void parse_init(void); + void hexdump(int addr, const u_int8_t *data, int len); #define ARRAY_LEN(a) (sizeof(a) / sizeof((a)[0])) @@ -31,7 +117,6 @@ int open_serial(const char *device, int rate); int read_with_timeout(int fd, u_int8_t *data, int len); int write_all(int fd, const u_int8_t *data, int len); -void ctrlc_init(void); void ctrlc_reset(void); int ctrlc_check(void);