Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
authoreutarass2010-08-23 17:25:59 +0000
committereutarass2010-08-23 17:25:59 +0000
commit66118a191c9467e05e8ae8987291de5f98178fcd (patch)
tree4714c7cb7009305d10d45974b3a1da5acfd25287 /main
parent1eafff5edfad98b5d983daae4464b4289b8d9bef (diff)
downloadorg.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.c94
-rw-r--r--main/cmdline.h9
-rw-r--r--main/main_client.c31
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

Back to the top