diff options
author | eutarass | 2010-08-23 17:25:59 +0000 |
---|---|---|
committer | eutarass | 2010-08-23 17:25:59 +0000 |
commit | 66118a191c9467e05e8ae8987291de5f98178fcd (patch) | |
tree | 4714c7cb7009305d10d45974b3a1da5acfd25287 /main | |
parent | 1eafff5edfad98b5d983daae4464b4289b8d9bef (diff) | |
download | org.eclipse.tcf.agent-66118a191c9467e05e8ae8987291de5f98178fcd.tar.gz org.eclipse.tcf.agent-66118a191c9467e05e8ae8987291de5f98178fcd.tar.xz org.eclipse.tcf.agent-66118a191c9467e05e8ae8987291de5f98178fcd.zip |
Bug 321939: [tcf][agent] It's impossible to script the client and make decision based on the output
Diffstat (limited to 'main')
-rw-r--r-- | main/cmdline.c | 94 | ||||
-rw-r--r-- | main/cmdline.h | 9 | ||||
-rw-r--r-- | main/main_client.c | 31 |
3 files changed, 112 insertions, 22 deletions
diff --git a/main/cmdline.c b/main/cmdline.c index 892cf5b2..2d61e785 100644 --- a/main/cmdline.c +++ b/main/cmdline.c @@ -45,13 +45,17 @@ struct cmd { static Channel * chan; static Protocol * proto; static FILE * infile; -static int interactive_flag; +static int mode_flag; +static int keep_alive_flag = 0; static int cmdline_suspended; static int cmdline_pending; +static int last_error = 0; +static char * host_name = NULL; +static char * single_command = NULL; static char * cmdline_string; static pthread_mutex_t cmdline_mutex; static pthread_cond_t cmdline_signal; -static pthread_t interactive_thread; +static pthread_t command_thread; static struct cmd * cmds = NULL; static size_t cmd_count = 0; @@ -62,7 +66,7 @@ static size_t connect_hnd_count = 0; static PluginCallBack * disconnect_hnds = NULL; static size_t disconnect_hnd_count = 0; -static void cmd_done(void); +static void cmd_done(int error); static void destroy_cmdline_handler() { size_t i; @@ -73,10 +77,13 @@ static void destroy_cmdline_handler() { loc_free(cmds); loc_free(connect_hnds); loc_free(disconnect_hnds); + if (host_name) loc_free(host_name); + if (single_command) loc_free(single_command); } static void channel_connected(Channel * c) { - if (c == chan) cmd_done(); + /* We are now connected, so there is no error (0)*/ + if (c == chan) cmd_done(0); } static void channel_disconnected(Channel * c) { @@ -96,7 +103,7 @@ static void display_tcf_reply(Channel * c, void * client_data, int error) { if (error) { printf("Reply error %d: %s\n", error, errno_to_str(error)); - cmd_done(); + cmd_done(error); return; } for (;;) { @@ -111,7 +118,7 @@ static void display_tcf_reply(Channel * c, void * client_data, int error) { * and receive the message when it's displayed */ fflush(0); - cmd_done(); + cmd_done(error); } #define maxargs 20 @@ -124,7 +131,7 @@ static int cmd_tcf(char *s) { if (c == NULL) { printf("Error: Channel not connected, use 'connect' command\n"); - return 0; + return -1; } ind = 0; args[ind] = strtok(s, " \t"); @@ -133,7 +140,7 @@ static int cmd_tcf(char *s) { } if (args[0] == NULL || args[1] == NULL) { printf("Error: Expected at least service and command name arguments\n"); - return 0; + return -1; } protocol_send_command(c, args[0], args[1], display_tcf_reply, c); for (i = 2; i < ind; i++) { @@ -196,7 +203,7 @@ static int cmd_peerinfo(char * s) { ps = peer_server_find(s); if (ps == NULL) { fprintf(stderr, "Error: Cannot find id: %s\n", s); - return 0; + return -1; } printf(" ID: %s\n", ps->id); for (i = 0; i < ps->ind; i++) { @@ -212,7 +219,7 @@ static void connect_callback(void * args, int error, Channel * c) { if (error) { fprintf(stderr, "Error: Cannot connect: %s\n", errno_to_str(error)); - cmd_done(); + cmd_done(error); } else { size_t i = 0; @@ -233,7 +240,7 @@ static int cmd_connect(char * s) { ps = channel_peer_from_url(s); if (ps == NULL) { fprintf(stderr, "Error: Cannot parse peer identifer: %s\n", s); - return 0; + return -1; } channel_connect(ps, connect_callback, ps); @@ -244,6 +251,7 @@ static void event_cmd_line(void * arg) { char * s = (char *)arg; int len; int delayed = 0; + int error = 0; size_t cp; if (cmdline_suspended) { @@ -259,6 +267,7 @@ static void event_cmd_line(void * arg) { s += len; while (*s && isspace((int)*s)) s++; delayed = cmds[cp].hnd(s); + if (delayed != 1 || delayed != 0) error = delayed; break; } } @@ -268,10 +277,11 @@ static void event_cmd_line(void * arg) { for (cp = 0; cp < cmd_count; ++cp) { fprintf(stderr, " %-10s - %s\n", cmds[cp].cmd, cmds[cp].help); } + error = 1; } } loc_free(arg); - if (!delayed) cmd_done(); + if (delayed != 1) cmd_done(error); } void cmdline_suspend(void) { @@ -296,7 +306,8 @@ static void cmd_done_event(void * arg) { check_error(pthread_mutex_unlock(&cmdline_mutex)); } -static void cmd_done(void) { +static void cmd_done(int error) { + last_error = error; post_event(cmd_done_event, NULL); } @@ -311,7 +322,7 @@ static void * interactive_handler(void * x) { check_error(pthread_cond_wait(&cmdline_signal, &cmdline_mutex)); continue; } - if (interactive_flag) { + if (mode_flag == 1) { printf("> "); fflush(stdout); } @@ -330,6 +341,38 @@ static void * interactive_handler(void * x) { return NULL; } +static void * single_command_handler(void * x) { + const char * connect_string = "connect "; + + check_error(pthread_mutex_lock(&cmdline_mutex)); + + post_event(event_cmd_line, loc_strdup2(connect_string, host_name)); + cmdline_pending = 1; + check_error(pthread_cond_wait(&cmdline_signal, &cmdline_mutex)); + if (last_error) { + destroy_cmdline_handler(); + exit(last_error); + } + + post_event(event_cmd_line, loc_strdup(single_command)); + cmdline_pending = 1; + check_error(pthread_cond_wait(&cmdline_signal, &cmdline_mutex)); + if (last_error) { + destroy_cmdline_handler(); + exit(last_error); + } + + check_error(pthread_mutex_unlock(&cmdline_mutex)); + + destroy_cmdline_handler(); + + if (!keep_alive_flag) { + exit(0); + } + + return NULL; +} + void open_script_file(const char * script_name) { if (script_name == NULL || (infile = fopen(script_name, "r")) == NULL) { if (script_name == NULL) script_name = "<null>"; @@ -338,6 +381,17 @@ void open_script_file(const char * script_name) { } } +void set_single_command(int keep_alive, const char * host, const char * command) { + if (host == NULL || command == NULL) { + fprintf(stderr, "Error: Cannot send single command\n"); + exit(1); + } + + keep_alive_flag = keep_alive; + host_name = loc_strdup(host); + single_command = loc_strdup(command); +} + static int add_cmdline_cmd(const char * cmd_name, const char * cmd_desc, int (*hnd)(char *)) { size_t i; @@ -392,7 +446,7 @@ static int add_disconnect_callback(PluginCallBack hnd) { } #endif /* ENABLE_Plugins */ -void ini_cmdline_handler(int interactive, Protocol * protocol) { +void ini_cmdline_handler(int mode, Protocol * protocol) { proto = protocol; #if ENABLE_Plugins @@ -416,12 +470,16 @@ void ini_cmdline_handler(int interactive, Protocol * protocol) { add_cmdline_cmd("peerinfo", "show info about a peer", cmd_peerinfo); add_cmdline_cmd("connect", "connect a peer", cmd_connect); - interactive_flag = interactive; + mode_flag = mode; if (infile == NULL) infile = stdin; check_error(pthread_mutex_init(&cmdline_mutex, NULL)); check_error(pthread_cond_init(&cmdline_signal, NULL)); - /* Create thread to read cmd line */ - check_error(pthread_create(&interactive_thread, &pthread_create_attr, interactive_handler, 0)); + + /* Create thread to read cmd line in interactive and script mode*/ + if (mode == 0 || mode == 1) + check_error(pthread_create(&command_thread, &pthread_create_attr, interactive_handler, 0)); + else + check_error(pthread_create(&command_thread, &pthread_create_attr, single_command_handler, 0)); } #endif /* ENABLE_Cmdline */ diff --git a/main/cmdline.h b/main/cmdline.h index d886f6fb..29789bd6 100644 --- a/main/cmdline.h +++ b/main/cmdline.h @@ -25,7 +25,14 @@ extern void cmdline_suspend(void); extern void cmdline_resume(void); -extern void ini_cmdline_handler(int interactive, Protocol * proto); +/* + * Mode can be either : + * 0 = Non interactive script mode + * 1 = Interactive mode + * 2 = Single command mode + */ +extern void ini_cmdline_handler(int mode, Protocol * proto); +extern void set_single_command(int keep_alive, const char * host, const char * command); extern void open_script_file(const char * script_name); #else /* ENABLE_Cmdline */ diff --git a/main/main_client.c b/main/main_client.c index 4731a9d6..afd01d28 100644 --- a/main/main_client.c +++ b/main/main_client.c @@ -53,7 +53,10 @@ int main(int argc, char ** argv) { #endif int c; int ind; - int interactive = 1; + int keep_alive = 0; + int mode = 1; /* interactive */ + const char * host_name = "localhost"; + const char * command = NULL; const char * log_name = "-"; const char * script_name = NULL; @@ -82,9 +85,15 @@ int main(int argc, char ** argv) { s++; while ((c = *s++) != '\0') { switch (c) { + case 'd': + keep_alive = 1; + break; + case 'l': case 'L': case 'S': + case 'h': + case 'c': if (*s == '\0') { if (++ind >= argc) { fprintf(stderr, "%s: error: no argument given to option '%c'\n", progname, c); @@ -103,7 +112,17 @@ int main(int argc, char ** argv) { case 'S': script_name = s; - interactive = 0; + mode = 0; + break; + + case 'h': + host_name = s; + break; + + case 'c': + /* TODO: allow multiple -c options */ + command = s; + mode = 2; break; default: @@ -120,6 +139,11 @@ int main(int argc, char ** argv) { } } + if (script_name != NULL && command != NULL) { + fprintf(stderr, "%s: error: illegal option -S and -c are mutually exclusive\n", progname); + exit(1); + } + open_log_file(log_name); #endif @@ -130,7 +154,8 @@ int main(int argc, char ** argv) { #if ENABLE_Cmdline if (script_name != NULL) open_script_file(script_name); - ini_cmdline_handler(interactive, proto); + if (command != NULL) set_single_command(keep_alive, host_name, command); + ini_cmdline_handler(mode, proto); #else if (script_name != NULL) fprintf(stderr, "Warning: This version does not support script file as input.\n"); #endif |