Browse Source

ktp: Callbacks for received stdout and stderr

Serj Kalichev 2 years ago
parent
commit
543ca36434
3 changed files with 131 additions and 61 deletions
  1. 40 48
      bin/klish/klish.c
  2. 81 11
      klish/ktp/ktp_session.c
  3. 10 2
      klish/ktp_session.h

+ 40 - 48
bin/klish/klish.c

@@ -22,14 +22,18 @@
 #include "private.h"
 
 
+static bool_t stdout_cb(ktp_session_t *ktp, const char *line, size_t len,
+	void *user_data);
+static bool_t stderr_cb(ktp_session_t *ktp, const char *line, size_t len,
+	void *user_data);
+
+
 int main(int argc, char **argv)
 {
 	int retval = -1;
 	struct options *opts = NULL;
 	int unix_sock = -1;
-	ktp_session_t *session = NULL;
-//	faux_msg_t *msg = NULL;
-//	faux_net_t *net = NULL;
+	ktp_session_t *ktp = NULL;
 
 	// Parse command line options
 	opts = opts_init();
@@ -44,60 +48,48 @@ int main(int argc, char **argv)
 		fprintf(stderr, "Error: Can't connect to server\n");
 		goto err;
 	}
-	session = ktp_session_new(unix_sock);
-	assert(session);
-	if (!session) {
+	ktp = ktp_session_new(unix_sock);
+	assert(ktp);
+	if (!ktp) {
 		fprintf(stderr, "Error: Can't create klish session\n");
 		goto err;
 	}
-/*
-	net = faux_net_new();
-	faux_net_set_fd(net, ktp_session_fd(session));
-*/
-	ktp_session_req_cmd(session, opts->line, NULL);
-
-/*
-	msg = faux_msg_new(KTP_MAGIC, KTP_MAJOR, KTP_MINOR);
-	faux_msg_set_cmd(msg, KTP_CMD);
-	if (opts->line)
-		faux_msg_add_param(msg, KTP_PARAM_LINE,
-			opts->line, strlen(opts->line));
-	faux_msg_debug(msg);
-	faux_msg_send(msg, net);
-	faux_msg_free(msg);
-
-	msg = faux_msg_recv(net);
-	if (msg) {
-		faux_msg_debug(msg);
-		if (KTP_STATUS_IS_ERROR(faux_msg_get_status(msg))) {
-			char *error = faux_msg_get_str_param_by_type(msg, KTP_PARAM_ERROR);
-			if (error) {
-				printf("Error: %s\n", error);
-				faux_str_free(error);
-			}
-		}
-		{
-			int retcode = -1;
-			uint8_t *retcode8bit = NULL;
-			if (faux_msg_get_param_by_type(msg, KTP_PARAM_RETCODE,
-				(void **)&retcode8bit, NULL)) {
-				retcode = (int)(*retcode8bit);
-				printf("Retcode: %d\n", retcode);
-			}
-		}
-		faux_msg_free(msg);
-	}
-
-	faux_net_free(net);
-*/
+	ktp_session_set_stdout_cb(ktp, stdout_cb, NULL);
+	ktp_session_set_stderr_cb(ktp, stderr_cb, NULL);
 
+	ktp_session_req_cmd(ktp, opts->line, NULL);
 
 	retval = 0;
-
 err:
-	ktp_session_free(session);
+	ktp_session_free(ktp);
 	ktp_disconnect(unix_sock);
 	opts_free(opts);
 
 	return retval;
 }
+
+
+static bool_t stdout_cb(ktp_session_t *ktp, const char *line, size_t len,
+	void *user_data)
+{
+	if (write(STDOUT_FILENO, line, len) < 0)
+		return BOOL_FALSE;
+
+	ktp = ktp;
+	user_data = user_data;
+
+	return BOOL_TRUE;
+}
+
+
+static bool_t stderr_cb(ktp_session_t *ktp, const char *line, size_t len,
+	void *user_data)
+{
+	if (write(STDERR_FILENO, line, len) < 0)
+		return BOOL_FALSE;
+
+	ktp = ktp;
+	user_data = user_data;
+
+	return BOOL_TRUE;
+}

+ 81 - 11
klish/ktp/ktp_session.c

@@ -30,6 +30,10 @@ struct ktp_session_s {
 	faux_hdr_t *hdr; // Service var: engine will receive header and then msg
 	bool_t done;
 	faux_eloop_t *eloop;
+	ktp_session_stdout_cb_fn stdout_cb;
+	void *stdout_udata;
+	ktp_session_stdout_cb_fn stderr_cb;
+	void *stderr_udata;
 };
 
 
@@ -75,6 +79,12 @@ ktp_session_t *ktp_session_new(int sock)
 	faux_eloop_add_fd(ktp->eloop, ktp_session_fd(ktp), POLLIN,
 		ktp_peer_ev, ktp->async);
 
+	// Callbacks
+	ktp->stdout_cb = NULL;
+	ktp->stdout_udata = NULL;
+	ktp->stderr_cb = NULL;
+	ktp->stderr_udata = NULL;
+
 	return ktp;
 }
 
@@ -114,6 +124,34 @@ bool_t ktp_session_set_done(ktp_session_t *ktp, bool_t done)
 }
 
 
+bool_t ktp_session_set_stdout_cb(ktp_session_t *ktp,
+	ktp_session_stdout_cb_fn stdout_cb, void *stdout_udata)
+{
+	assert(ktp);
+	if (!ktp)
+		return BOOL_FALSE;
+
+	ktp->stdout_cb = stdout_cb;
+	ktp->stdout_udata = stdout_udata;
+
+	return BOOL_TRUE;
+}
+
+
+bool_t ktp_session_set_stderr_cb(ktp_session_t *ktp,
+	ktp_session_stdout_cb_fn stderr_cb, void *stderr_udata)
+{
+	assert(ktp);
+	if (!ktp)
+		return BOOL_FALSE;
+
+	ktp->stderr_cb = stderr_cb;
+	ktp->stderr_udata = stderr_udata;
+
+	return BOOL_TRUE;
+}
+
+
 bool_t ktp_session_connected(ktp_session_t *ktp)
 {
 	assert(ktp);
@@ -167,6 +205,43 @@ static bool_t stop_loop_ev(faux_eloop_t *eloop, faux_eloop_type_e type,
 }
 
 
+static bool_t ktp_session_process_stdout(ktp_session_t *ktp, const faux_msg_t *msg)
+{
+	char *line = NULL;
+	unsigned int len = 0;
+
+	assert(ktp);
+	assert(msg);
+
+	if (!ktp->stdout_cb)
+		return BOOL_TRUE; // Just ignore stdout. It's not a bug
+
+	if (!faux_msg_get_param_by_type(msg, KTP_PARAM_LINE, (void **)&line, &len))
+		return BOOL_TRUE; // It's strange but not a bug
+
+	return ktp->stdout_cb(ktp, line, len, ktp->stdout_udata);
+}
+
+
+static bool_t ktp_session_process_stderr(ktp_session_t *ktp, const faux_msg_t *msg)
+{
+	char *line = NULL;
+	unsigned int len = 0;
+
+	assert(ktp);
+	assert(msg);
+
+	if (!ktp->stderr_cb)
+		return BOOL_TRUE; // Just ignore stdout. It's not a bug
+
+	if (!faux_msg_get_param_by_type(msg, KTP_PARAM_LINE,
+			(void **)&line, &len))
+		return BOOL_TRUE; // It's strange but not a bug
+
+	return ktp->stderr_cb(ktp, line, len, ktp->stderr_udata);
+}
+
+
 static bool_t ktp_session_dispatch(ktp_session_t *ktp, faux_msg_t *msg)
 {
 	uint16_t cmd = 0;
@@ -191,21 +266,16 @@ static bool_t ktp_session_dispatch(ktp_session_t *ktp, faux_msg_t *msg)
 		}
 		return BOOL_FALSE;
 		}
-//		ktpd_session_process_cmd(ktpd, msg);
+//		ktp_session_process_cmd(ktpd, msg);
 		break;
 	case KTP_STDOUT:
-		{
-		char *line = NULL;
-		unsigned int len = 0;
-		if (faux_msg_get_param_by_type(msg, KTP_PARAM_LINE,
-			(void **)&line, &len)) {
-			write(STDOUT_FILENO, line, len);
-		}
-		}
-//		ktpd_session_process_completion(ktpd, msg);
+		ktp_session_process_stdout(ktp, msg);
+		break;
+	case KTP_STDERR:
+		ktp_session_process_stderr(ktp, msg);
 		break;
 	case KTP_HELP:
-//		ktpd_session_process_help(ktpd, msg);
+//		ktp_session_process_help(ktpd, msg);
 		break;
 	default:
 		syslog(LOG_WARNING, "Unsupported command: 0x%04u\n", cmd);

+ 10 - 2
klish/ktp_session.h

@@ -14,8 +14,6 @@
 typedef struct ktpd_session_s ktpd_session_t;
 typedef struct ktp_session_s ktp_session_t;
 
-typedef bool_t (*ktpd_session_stall_cb_fn)(ktpd_session_t *session,
-	void *user_data);
 
 C_DECL_BEGIN
 
@@ -34,16 +32,26 @@ bool_t ktp_stall_cb(faux_async_t *async, size_t len, void *user_data);
 
 
 // Client KTP session
+typedef bool_t (*ktp_session_stdout_cb_fn)(ktp_session_t *ktp,
+	const char *line, size_t len, void *user_data);
+
 ktp_session_t *ktp_session_new(int sock);
 void ktp_session_free(ktp_session_t *session);
 bool_t ktp_session_done(const ktp_session_t *ktp);
 bool_t ktp_session_set_done(ktp_session_t *ktp, bool_t done);
+bool_t ktp_session_set_stdout_cb(ktp_session_t *ktp,
+	ktp_session_stdout_cb_fn stdout_cb, void *stdout_udata);
+bool_t ktp_session_set_stderr_cb(ktp_session_t *ktp,
+	ktp_session_stdout_cb_fn stderr_cb, void *stderr_udata);
 bool_t ktp_session_connected(ktp_session_t *session);
 int ktp_session_fd(const ktp_session_t *session);
 bool_t ktp_session_req_cmd(ktp_session_t *ktp, const char *line, int *retcode);
 
 
 // Server KTP session
+typedef bool_t (*ktpd_session_stall_cb_fn)(ktpd_session_t *session,
+	void *user_data);
+
 ktpd_session_t *ktpd_session_new(int sock, const kscheme_t *scheme,
 	const char *start_entry, faux_eloop_t *eloop);
 void ktpd_session_free(ktpd_session_t *session);