From 0668e0fac6edd49e03e6371756acc3c7a2e02274 Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Tue, 4 Aug 2020 11:08:37 -0300 Subject: [PATCH] Fixing issues on non GUI (local) sessions. --- client/src/core/constants.cc | 2 +- client/src/host/init.cc | 14 +++++++++++--- client/src/host/properties.cc | 2 +- client/src/include/lib3270/ipc.h | 5 ++++- client/src/session/local/actions.cc | 33 +++++++++++++++++++++------------ client/src/session/local/attribute.cc | 39 ++++++++++++++++++++------------------- client/src/session/local/get.cc | 15 ++++++++------- client/src/session/local/init.cc | 5 +++-- client/src/session/local/private.h | 9 ++++++--- client/src/session/local/set.cc | 6 +++--- client/src/session/local/wait.cc | 16 ++++++++-------- client/src/session/remote/private.h | 2 +- client/src/session/remote/properties.cc | 4 ++-- client/src/session/tools.cc | 2 ++ client/src/testprogram/testprogram.cc | 70 +++++++++++++++++++++++++++++++++++++++++++++------------------------- 15 files changed, 136 insertions(+), 88 deletions(-) diff --git a/client/src/core/constants.cc b/client/src/core/constants.cc index fc6b20c..3b4ed75 100644 --- a/client/src/core/constants.cc +++ b/client/src/core/constants.cc @@ -104,7 +104,7 @@ TN3270_PUBLIC const char * toCharString(const TN3270::ProgramMessage programMess "", "X System", "X Wait", - "Connected" + "Connected", "X Not Connected", "Awaiting first", "X -f", diff --git a/client/src/host/init.cc b/client/src/host/init.cc index 8d22fd7..8c4bf49 100644 --- a/client/src/host/init.cc +++ b/client/src/host/init.cc @@ -42,15 +42,23 @@ TN3270::Host::Host(const char *id, const char *charset) { - debug("Creating host id=\"", id); + if(!id) + id = ""; + + debug("Creating host id=\"", id, "\""); this->timeout = 5; this->session = Session::getInstance(id, charset); + debug("Create host with session ",this->session); + } TN3270::Host::~Host() { - delete this->session; - this->session = nullptr; + debug("Deleting host session ",this->session); + if(this->session) { + delete this->session; + this->session = nullptr; + } } diff --git a/client/src/host/properties.cc b/client/src/host/properties.cc index 2526566..4896319 100644 --- a/client/src/host/properties.cc +++ b/client/src/host/properties.cc @@ -60,7 +60,7 @@ std::vector TN3270::Host::getAttributes() const { void TN3270::Host::setTimeout(time_t timeout) noexcept { this->timeout = timeout; - this->session->setWaitMode(timeout != 0); + this->session->setTimeout(timeout); } diff --git a/client/src/include/lib3270/ipc.h b/client/src/include/lib3270/ipc.h index 0c16a22..9f18180 100644 --- a/client/src/include/lib3270/ipc.h +++ b/client/src/include/lib3270/ipc.h @@ -569,7 +569,7 @@ virtual void setHostURL(const char *url) = 0; virtual void setUnlockDelay(unsigned short delay = 350) = 0; - virtual void setWaitMode(bool mode) = 0; + virtual void setTimeout(time_t timeout = 0) = 0; virtual void setLockOnOperatorError(bool lock = true) = 0; virtual unsigned short getScreenWidth() const = 0; @@ -668,6 +668,9 @@ int overflow(int c) override; public: + Host(const Host &src) = delete; + Host(const Host *src) = delete; + Host(const char *id, const char *charset = nullptr); ~Host(); diff --git a/client/src/session/local/actions.cc b/client/src/session/local/actions.cc index f98cb29..0414c12 100644 --- a/client/src/session/local/actions.cc +++ b/client/src/session/local/actions.cc @@ -50,56 +50,63 @@ } bool Local::Action::activatable() const noexcept { - std::lock_guard lock(this->session->sync); + std::lock_guard lock(this->session->sync); debug(__FUNCTION__,"(",(void *) descriptor,")"); return lib3270_action_is_activatable(this->descriptor,this->session->hSession); } void Local::Action::activate() { - std::lock_guard lock(this->session->sync); + std::lock_guard lock(this->session->sync); chkResponse(lib3270_action_activate(this->descriptor,this->session->hSession)); } void Local::Action::wait(time_t seconds) { - std::lock_guard lock(this->session->sync); + std::lock_guard lock(this->session->sync); chkResponse(lib3270_wait_for_ready(this->session->hSession,seconds)); } TN3270::Action * Local::Session::getAction(const LIB3270_ACTION *descriptor) { - std::lock_guard lock(sync); + std::lock_guard lock(sync); return new Local::Action(this, descriptor); } void Local::Session::action(const char *action_name) { - std::lock_guard lock(sync); + std::lock_guard lock(sync); chkResponse(lib3270_action_activate_by_name(action_name,hSession)); + if(this->timeout) + chkResponse(lib3270_wait_for_ready(hSession,this->timeout)); } void Local::Session::connect(const char *url, time_t seconds) { - std::lock_guard lock(sync); - chkResponse(lib3270_connect_url(hSession,url,seconds)); + std::lock_guard lock(sync); + chkResponse(lib3270_connect_url(hSession,url,seconds ? seconds : this->timeout)); + } void Local::Session::disconnect() { - std::lock_guard lock(sync); + std::lock_guard lock(sync); chkResponse(lib3270_disconnect(hSession)); } void Local::Session::pfkey(unsigned short value) { - std::lock_guard lock(sync); + std::lock_guard lock(sync); chkResponse(lib3270_pfkey(hSession,value)); + if(this->timeout) + chkResponse(lib3270_wait_for_ready(hSession,this->timeout)); } void Local::Session::pakey(unsigned short value) { - std::lock_guard lock(sync); + std::lock_guard lock(sync); chkResponse(lib3270_pakey(hSession,value)); + if(this->timeout) + chkResponse(lib3270_wait_for_ready(hSession,this->timeout)); } @@ -142,14 +149,16 @@ throw std::system_error(EINVAL, std::system_category()); } - std::lock_guard lock(sync); + std::lock_guard lock(sync); chkResponse(actions[(size_t) action](hSession)); + if(this->timeout) + chkResponse(lib3270_wait_for_ready(hSession,this->timeout)); } void Local::Session::print(LIB3270_CONTENT_OPTION option) { - std::lock_guard lock(sync); + std::lock_guard lock(sync); switch(option) { case LIB3270_CONTENT_ALL: diff --git a/client/src/session/local/attribute.cc b/client/src/session/local/attribute.cc index e4bf5b6..69bf38f 100644 --- a/client/src/session/local/attribute.cc +++ b/client/src/session/local/attribute.cc @@ -345,7 +345,7 @@ Attribute Local::Session::getAttribute(const char *name) const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); // Check for integer properties. { @@ -415,7 +415,7 @@ void Local::Session::getAttributes(std::vector & attributes) const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); // Add integer properties. { @@ -465,37 +465,37 @@ } unsigned short Local::Session::getScreenWidth() const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); return (unsigned short) lib3270_get_width(hSession); } unsigned short Local::Session::getScreenHeight() const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); return (unsigned short) lib3270_get_height(hSession); } unsigned short Local::Session::getScreenLength() const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); return (unsigned short) lib3270_get_length(hSession); } void Local::Session::setUnlockDelay(unsigned short delay) { - std::lock_guard lock(sync); + std::lock_guard lock(sync); chkResponse(lib3270_set_unlock_delay(hSession,delay)); } - void Local::Session::setWaitMode(bool mode) { - std::lock_guard lock(sync); - chkResponse(ENOTSUP); + void Local::Session::setTimeout(time_t timeout) { + std::lock_guard lock(sync); + this->timeout = timeout; } void Local::Session::setLockOnOperatorError(bool lock) { - std::lock_guard guard(sync); + std::lock_guard guard(sync); chkResponse(lib3270_set_lock_on_operator_error(hSession,lock ? 1 : 0)); } unsigned short Local::Session::setCursor(int addr) { - std::lock_guard lock(sync); + std::lock_guard lock(sync); int rc = lib3270_set_cursor_address(hSession,addr); if(rc < 0) @@ -506,7 +506,7 @@ } unsigned short Local::Session::setCursor(unsigned short row, unsigned short col) { - std::lock_guard lock(sync); + std::lock_guard lock(sync); int rc = lib3270_set_cursor_position(hSession,row,col); if(rc < 0) @@ -517,7 +517,7 @@ } unsigned short Local::Session::getCursorAddress() { - std::lock_guard lock(sync); + std::lock_guard lock(sync); int rc = lib3270_get_cursor_address(hSession); @@ -529,35 +529,36 @@ std::string Local::Session::getVersion() const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); return lib3270_get_version(); } std::string Local::Session::getRevision() const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); return lib3270_get_revision(); } std::string Local::Session::getAssociatedLUName() const { - std::lock_guard lock(const_cast(this)->sync); - return lib3270_get_associated_luname(hSession); + std::lock_guard lock(const_cast(this)->sync); + const char * luname = lib3270_get_associated_luname(hSession); + return string(luname ? luname : ""); } std::string Local::Session::getHostURL() const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); return lib3270_get_url(hSession); } void Local::Session::setHostURL(const char *url) { - std::lock_guard lock(sync); + std::lock_guard lock(sync); chkResponse(lib3270_set_url(hSession, url)); } diff --git a/client/src/session/local/get.cc b/client/src/session/local/get.cc index fa1f5bf..33d1dc4 100644 --- a/client/src/session/local/get.cc +++ b/client/src/session/local/get.cc @@ -44,7 +44,7 @@ std::string Local::Session::get() const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); lib3270_auto_cleanup text = lib3270_get_string_at_address(hSession, 0, -1, '\n'); @@ -57,7 +57,7 @@ std::string Local::Session::get(int baddr, int len, char lf) const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); lib3270_auto_cleanup text = lib3270_get_string_at_address(hSession, baddr, len, lf); @@ -70,7 +70,7 @@ std::string Local::Session::get(unsigned int row, unsigned int col, int len, char lf) const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); lib3270_auto_cleanup text = lib3270_get_string_at(hSession, row, col, len, lf); @@ -84,27 +84,28 @@ ProgramMessage Local::Session::getProgramMessage() const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); return (ProgramMessage) lib3270_get_program_message(this->hSession); } ConnectionState Local::Session::getConnectionState() const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); return (ConnectionState) lib3270_get_connection_state(this->hSession); } SSLState Local::Session::getSSLState() const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); return (TN3270::SSLState) lib3270_get_ssl_state(hSession); } LIB3270_KEYBOARD_LOCK_STATE Local::Session::getKeyboardLockState() const { - std::lock_guard lock(const_cast(this)->sync); + + std::lock_guard lock(const_cast(this)->sync); return lib3270_get_keyboard_lock_state(hSession); } diff --git a/client/src/session/local/init.cc b/client/src/session/local/init.cc index 9603f7d..a457c35 100644 --- a/client/src/session/local/init.cc +++ b/client/src/session/local/init.cc @@ -61,9 +61,10 @@ Local::Session::Session(const char *charset) : Abstract::Session() { - std::lock_guard lock(sync); + std::lock_guard lock(sync); this->hSession = lib3270_session_new(""); + this->timeout = 5; lib3270_set_user_data(this->hSession,(void *) this); @@ -99,7 +100,7 @@ Local::Session::~Session() { - std::lock_guard lock(sync); + std::lock_guard lock(sync); lib3270_session_free(this->hSession); this->hSession = nullptr; diff --git a/client/src/session/local/private.h b/client/src/session/local/private.h index 41df8b3..bc2c406 100644 --- a/client/src/session/local/private.h +++ b/client/src/session/local/private.h @@ -77,11 +77,14 @@ friend class Action; + /// @brief Timeout for automatic waits. + time_t timeout; + /// @brief Handle of the related instance of lib3270 H3270 * hSession; - /// @brief Mutex to serialize access to lib3270 - std::mutex sync; + /// @brief Recursive mutex to serialize access to lib3270 + std::recursive_mutex sync; /// @brief Popup Handler. static int popupHandler(H3270 *session, const LIB3270_POPUP *popup, unsigned char wait); @@ -152,7 +155,7 @@ unsigned short getScreenHeight() const override; unsigned short getScreenLength() const override; void setUnlockDelay(unsigned short delay) override; - void setWaitMode(bool mode) override; + void setTimeout(time_t timeout) override; void setLockOnOperatorError(bool lock) override; void setCharSet(const char *charset = NULL) override; unsigned short setCursor(int addr) override; diff --git a/client/src/session/local/set.cc b/client/src/session/local/set.cc index 020bed0..af1604f 100644 --- a/client/src/session/local/set.cc +++ b/client/src/session/local/set.cc @@ -44,7 +44,7 @@ void Local::Session::set(const std::string &str) { - std::lock_guard lock(this->sync); + std::lock_guard lock(this->sync); int rc = lib3270_set_field(hSession,str.c_str(),str.length()); if(rc < 0) @@ -54,7 +54,7 @@ void Local::Session::set(int baddr, const std::string &str) { - std::lock_guard lock(this->sync); + std::lock_guard lock(this->sync); int rc = lib3270_set_string_at_address(hSession,baddr,(unsigned char *) str.c_str(),str.length()); if(rc < 0) @@ -64,7 +64,7 @@ void Local::Session::set(int row, int col, const std::string &str) { - std::lock_guard lock(this->sync); + std::lock_guard lock(this->sync); int rc = lib3270_set_string_at(hSession,row,col,(unsigned char *) str.c_str(),str.length()); if(rc < 0) diff --git a/client/src/session/local/wait.cc b/client/src/session/local/wait.cc index 07954b0..ac6f2b6 100644 --- a/client/src/session/local/wait.cc +++ b/client/src/session/local/wait.cc @@ -45,53 +45,53 @@ void Local::Session::wait(time_t seconds) const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); chkResponse(lib3270_wait(this->hSession, seconds)); } void Local::Session::waitForReady(time_t timeout) const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); chkResponse(lib3270_wait_for_ready(this->hSession, timeout)); } void Local::Session::waitForConnectionState(ConnectionState state, time_t timeout) const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); chkResponse(lib3270_wait_for_cstate(this->hSession, (LIB3270_CSTATE) state, timeout)); } LIB3270_KEYBOARD_LOCK_STATE Local::Session::waitForKeyboardUnlock(time_t timeout) const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); return lib3270_wait_for_keyboard_unlock(this->hSession, timeout); } void Local::Session::waitForChange(time_t seconds) const { - std::lock_guard lock(const_cast(this)->sync); + std::lock_guard lock(const_cast(this)->sync); chkResponse(lib3270_wait_for_update(this->hSession, seconds)); } void Local::Session::wait(const char *text, int seconds) { - std::lock_guard lock(sync); + std::lock_guard lock(sync); chkResponse(lib3270_wait_for_string(hSession,convertToHost(text,-1).c_str(),seconds)); } void Local::Session::wait(unsigned short row, unsigned short col, const char *text, int seconds) { - std::lock_guard lock(sync); + std::lock_guard lock(sync); chkResponse(lib3270_wait_for_string_at(hSession,row,col,convertToHost(text,-1).c_str(),seconds)); } void Local::Session::wait(int addr, const char *text, int seconds) { - std::lock_guard lock(sync); + std::lock_guard lock(sync); chkResponse(lib3270_wait_for_string_at_address(hSession,addr,convertToHost(text,-1).c_str(),seconds)); } diff --git a/client/src/session/remote/private.h b/client/src/session/remote/private.h index 97bc1d5..746991e 100644 --- a/client/src/session/remote/private.h +++ b/client/src/session/remote/private.h @@ -160,7 +160,7 @@ unsigned short getScreenHeight() const override; unsigned short getScreenLength() const override; void setUnlockDelay(unsigned short delay) override; - void setWaitMode(bool mode) override; + void setTimeout(time_t timeout) override; void setLockOnOperatorError(bool lock) override; void setCharSet(const char *charset = NULL) override; unsigned short setCursor(int addr) override; diff --git a/client/src/session/remote/properties.cc b/client/src/session/remote/properties.cc index 1762132..e8b7fa7 100644 --- a/client/src/session/remote/properties.cc +++ b/client/src/session/remote/properties.cc @@ -160,12 +160,12 @@ } - void IPC::Session::setWaitMode(bool mode) { + void IPC::Session::setTimeout(time_t timeout) { int32_t rc; Request(*this,"setWaitMode") - .push(mode) + .push(timeout != 0) .call() .pop(rc); diff --git a/client/src/session/tools.cc b/client/src/session/tools.cc index ced1a9e..db1a6f4 100644 --- a/client/src/session/tools.cc +++ b/client/src/session/tools.cc @@ -44,6 +44,8 @@ void chkResponse(int rc) { + debug("rc=",rc); + if(rc == 0) return; diff --git a/client/src/testprogram/testprogram.cc b/client/src/testprogram/testprogram.cc index 5569ae1..174169b 100644 --- a/client/src/testprogram/testprogram.cc +++ b/client/src/testprogram/testprogram.cc @@ -98,7 +98,7 @@ */ // Test Attributes - static void testAttributes(const char *session) { + static void testAttributes(const char *session, const char *url) { TN3270::Host host{session}; @@ -122,7 +122,7 @@ } // Performance test. - static void testPerformance(const char *session) { + static void testPerformance(const char *session, const char *url) { try { @@ -165,30 +165,22 @@ } // test host object - static void testHost(const char *session) { + static void testHost(const char *session, const char *url) { try { TN3270::Host host{session}; - host.setTimeout(10); - - host.connect(); - host.push(TN3270::ENTER); - - host.toString(14,1,75,0); - - // host.disconnect(); - - /* cout << "Version: " << host["version"] << "\tRevision: " << host["Revision"] << "\tConnected: " << host["Connected"] << std::endl; - host.setUnlockDelay(0); - host.connect(nullptr); + host.setUnlockDelay(0); // Disable the 350ms delay on screen changes. + host.setTimeout(10); // Set the default timeout. + host["crlget"] = false; // Disable CRL get to speed up the connection. + host.connect(url); cout << "Wait for unlock returns " << host.getKeyboardLockState() << std::endl @@ -203,28 +195,30 @@ } host.setCursor(10,10); - - host.wait(10); - +// host.wait(10); // host.input("test@0another line"); + cout << "Sending ENTER" << endl; host.push(TN3270::ENTER); - host.wait(10); + cout << "ENTER returns" << endl; + + host.wait(2); cout << host << endl; cout << endl << "[" << host.toString((unsigned int) 1, (unsigned int) 3,7) << "]" << endl; cout << endl << "[" << host.toString((int) 15, (int) 10) << "]" << endl; + cout << "Sending PF3" << endl; host.pfkey(3); - host.wait(10); + cout << "PF3 returns" << endl; cout << host << endl; - host.wait(10); + cout << "Disconnecting" << endl; host.disconnect(); - */ + cout << "Test complete" << endl; } catch(const std::exception &e) { @@ -237,10 +231,13 @@ int main(int argc, char **argv) { const char * session = ":A"; + const char * url = nullptr; static struct option options[] = { { "session", required_argument, 0, 's' }, + { "url", required_argument, 0, 'U' }, { "perftest", no_argument, 0, 'P' }, + { "info", no_argument, 0, 'I' }, { 0, 0, 0, 0} }; @@ -252,19 +249,42 @@ switch(opt) { case 's': session = optarg; + cout << "Session: " << session << endl; + break; + + case 'U': + url = optarg; + cout << "URL: " << session << endl; break; case 'P': - testPerformance(session); + testPerformance(session,url); + return 0; + + case 'I': + testHost(session,url); return 0; } } - cout << "Session: " << session << endl; + /* + + host.setTimeout(10); + + host.connect(); + host.push(TN3270::ENTER); + + host.toString(14,1,75,0); + + // host.disconnect(); + */ + + + // cout << "Session: " << session << endl; - testHost(session); + //testHost(session); // testPerformance(session); -- libgit2 0.21.2