diff --git a/lib3270.cbp b/lib3270.cbp index 6310438..7fa41dd 100644 --- a/lib3270.cbp +++ b/lib3270.cbp @@ -157,6 +157,9 @@ + + @@ -209,9 +212,6 @@ - - @@ -245,6 +245,9 @@ + + diff --git a/src/lib3270/iocalls.c b/src/lib3270/iocalls.c index 6358587..b48e6ad 100644 --- a/src/lib3270/iocalls.c +++ b/src/lib3270/iocalls.c @@ -37,10 +37,10 @@ #include "utilc.h" #define MILLION 1000000L - -#if defined(_WIN32) - #define MAX_HA 256 -#endif +// +//#if defined(_WIN32) +// #define MAX_HA 256 +//#endif /*---[ Standard calls ]-------------------------------------------------------------------------------------*/ @@ -199,6 +199,7 @@ static void * internal_add_poll(H3270 *session, int fd, LIB3270_IO_FLAG flag, vo input_t *ip = (input_t *) lib3270_malloc(sizeof(input_t)); ip->session = session; + ip->enabled = 1; ip->fd = fd; ip->flag = flag; ip->userdata = userdata; @@ -285,276 +286,6 @@ LIB3270_EXPORT void * lib3270_add_poll_fd(H3270 *session, int fd, LIB3270_IO_FL return add_poll(session,fd,flag,call,userdata); } -/* Event dispatcher. */ -int lib3270_default_event_dispatcher(H3270 *hSession, int block) -{ -#if defined(_WIN32) - unsigned long long now; -// int i; - int maxSock; - DWORD tmo; -#else - int ns; - struct timeval now, twait, *tp; - int events; -#endif - - fd_set rfds, wfds, xfds; - - input_t *ip; - int processed_any = 0; - -retry: - - hSession->inputs_changed = 0; - - // If we've processed any input, then don't block again. - if(processed_any) - block = 0; - -#if defined(_WIN32) - - maxSock = 0; - - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&xfds); - - for (ip = hSession->inputs; ip != (input_t *)NULL; ip = ip->next) - { - if(ip->flag & LIB3270_IO_FLAG_READ) - { - FD_SET(ip->fd, &rfds); - maxSock = max(ip->fd,maxSock); - } - - if(ip->flag & LIB3270_IO_FLAG_WRITE) - { - FD_SET(ip->fd, &wfds); - maxSock = max(ip->fd,maxSock); - } - - if(ip->flag & LIB3270_IO_FLAG_EXCEPTION) - { - FD_SET(ip->fd, &xfds); - maxSock = max(ip->fd,maxSock); - } - } - - if (block) - { - if (hSession->timeouts != TN) - { - ms_ts(&now); - if (now > hSession->timeouts->ts) - tmo = 0; - else - tmo = hSession->timeouts->ts - now; - } - else - { - // Block for 1 second (at maximal) - tmo = 1000; - } - } - else - { - tmo = 1000; - } - - if(maxSock) - { - struct timeval tm; - - tm.tv_sec = 0; - tm.tv_usec = tmo; - - int ns = select(maxSock+1, &rfds, &wfds, &xfds, &tm); - - if (ns < 0 && errno != EINTR) - { - lib3270_popup_dialog( hSession, - LIB3270_NOTIFY_ERROR, - _( "Network error" ), - _( "Select() failed when processing for events." ), - lib3270_win32_strerror(WSAGetLastError())); - } - else - { - for (ip = hSession->inputs; ip != (input_t *) NULL; ip = ip->next) - { - if((ip->flag & LIB3270_IO_FLAG_READ) && FD_ISSET(ip->fd, &rfds)) - { - (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_READ,ip->userdata); - processed_any = True; - if (hSession->inputs_changed) - goto retry; - } - - if ((ip->flag & LIB3270_IO_FLAG_WRITE) && FD_ISSET(ip->fd, &wfds)) - { - (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_WRITE,ip->userdata); - processed_any = True; - if (hSession->inputs_changed) - goto retry; - } - - if ((ip->flag & LIB3270_IO_FLAG_EXCEPTION) && FD_ISSET(ip->fd, &xfds)) - { - (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_EXCEPTION,ip->userdata); - processed_any = True; - if (hSession->inputs_changed) - goto retry; - } - } - } - } - else if(block) - { - Sleep(tmo); - } - - -#else - - events = 0; - - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&xfds); - - for (ip = hSession->inputs; ip != (input_t *)NULL; ip = ip->next) - { - if(ip->flag & LIB3270_IO_FLAG_READ) - { - FD_SET(ip->fd, &rfds); - events++; - } - - if(ip->flag & LIB3270_IO_FLAG_WRITE) - { - FD_SET(ip->fd, &wfds); - events++; - } - - if(ip->flag & LIB3270_IO_FLAG_EXCEPTION) - { - FD_SET(ip->fd, &xfds); - events++; - } - } - - if (block) - { - if (hSession->timeouts != TN) - { - (void) gettimeofday(&now, (void *)NULL); - twait.tv_sec = hSession->timeouts->tv.tv_sec - now.tv_sec; - twait.tv_usec = hSession->timeouts->tv.tv_usec - now.tv_usec; - if (twait.tv_usec < 0L) { - twait.tv_sec--; - twait.tv_usec += MILLION; - } - if (twait.tv_sec < 0L) - twait.tv_sec = twait.tv_usec = 0L; - tp = &twait; - } - else - { - twait.tv_sec = 1; - twait.tv_usec = 0L; - tp = &twait; - } - } - else - { - twait.tv_sec = 1; - twait.tv_usec = 0L; - tp = &twait; - - if(!events) - return processed_any; - } - - ns = select(FD_SETSIZE, &rfds, &wfds, &xfds, tp); - - if (ns < 0 && errno != EINTR) - { - lib3270_popup_dialog( hSession, - LIB3270_NOTIFY_ERROR, - _( "Network error" ), - _( "Select() failed when processing for events." ), - "%s", - strerror(errno)); - } - else - { - for (ip = hSession->inputs; ip != (input_t *) NULL; ip = ip->next) - { - if((ip->flag & LIB3270_IO_FLAG_READ) && FD_ISSET(ip->fd, &rfds)) - { - (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_READ,ip->userdata); - processed_any = True; - if (hSession->inputs_changed) - goto retry; - } - - if((ip->flag & LIB3270_IO_FLAG_WRITE) && FD_ISSET(ip->fd, &wfds)) - { - (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_WRITE,ip->userdata); - processed_any = True; - if (hSession->inputs_changed) - goto retry; - } - - if((ip->flag & LIB3270_IO_FLAG_EXCEPTION) && FD_ISSET(ip->fd, &xfds)) - { - (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_EXCEPTION,ip->userdata); - processed_any = True; - if (hSession->inputs_changed) - goto retry; - } - } - } - -#endif - - // See what's expired. - if (hSession->timeouts != TN) - { -#if defined(_WIN32) - struct timeout *t; - ms_ts(&now); -#else - struct timeout *t; - (void) gettimeofday(&now, (void *)NULL); -#endif - - while ((t = hSession->timeouts) != TN) - { -#if defined(_WIN32) - if (t->ts <= now) -#else - if (t->tv.tv_sec < now.tv_sec ||(t->tv.tv_sec == now.tv_sec && t->tv.tv_usec < now.tv_usec)) -#endif - { - hSession->timeouts = t->next; - t->in_play = True; - (*t->proc)(t->session); - processed_any = True; - lib3270_free(t); - } else - break; - } - } - - if (hSession->inputs_changed) - goto retry; - - return processed_any; - -} - static int internal_wait(H3270 *hSession, int seconds) { time_t end = time(0) + seconds; diff --git a/src/lib3270/linux/event_dispatcher.c b/src/lib3270/linux/event_dispatcher.c new file mode 100644 index 0000000..95c6c68 --- /dev/null +++ b/src/lib3270/linux/event_dispatcher.c @@ -0,0 +1,204 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + /** + * @brief Implements the default event dispatcher for linux. + * + */ + +#include "../private.h" +#include +#include +// #include "../xioc.h" +// #include "telnetc.h" +// #include "utilc.h" + +#define MILLION 1000000L +#define TN (timeout_t *)NULL + +/*---[ Implement ]------------------------------------------------------------------------------------------*/ + +/** + * @brief lib3270's default event dispatcher. + * + * @param hSession TN3270 session to process. + * @param block If non zero, the method blocks waiting for event. + * + */ +int lib3270_default_event_dispatcher(H3270 *hSession, int block) +{ + int ns; + struct timeval now, twait, *tp; + int events; + + fd_set rfds, wfds, xfds; + + input_t *ip; + int processed_any = 0; + +retry: + + hSession->inputs_changed = 0; + + // If we've processed any input, then don't block again. + if(processed_any) + block = 0; + + events = 0; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&xfds); + + for (ip = hSession->inputs; ip != (input_t *)NULL; ip = (input_t *) ip->next) + { + if(!ip->enabled) + { + debug("Socket %d is disabled",ip->fd); + continue; + } + + if(ip->flag & LIB3270_IO_FLAG_READ) + { + FD_SET(ip->fd, &rfds); + events++; + } + + if(ip->flag & LIB3270_IO_FLAG_WRITE) + { + FD_SET(ip->fd, &wfds); + events++; + } + + if(ip->flag & LIB3270_IO_FLAG_EXCEPTION) + { + FD_SET(ip->fd, &xfds); + events++; + } + } + + if (block) + { + if (hSession->timeouts != TN) + { + (void) gettimeofday(&now, (void *)NULL); + twait.tv_sec = hSession->timeouts->tv.tv_sec - now.tv_sec; + twait.tv_usec = hSession->timeouts->tv.tv_usec - now.tv_usec; + if (twait.tv_usec < 0L) { + twait.tv_sec--; + twait.tv_usec += MILLION; + } + if (twait.tv_sec < 0L) + twait.tv_sec = twait.tv_usec = 0L; + tp = &twait; + } + else + { + twait.tv_sec = 1; + twait.tv_usec = 0L; + tp = &twait; + } + } + else + { + twait.tv_sec = 1; + twait.tv_usec = 0L; + tp = &twait; + + if(!events) + return processed_any; + } + + ns = select(FD_SETSIZE, &rfds, &wfds, &xfds, tp); + + if (ns < 0 && errno != EINTR) + { + lib3270_popup_dialog( hSession, + LIB3270_NOTIFY_ERROR, + _( "Network error" ), + _( "Select() failed when processing for events." ), + "%s", + strerror(errno)); + } + else + { + for (ip = hSession->inputs; ip != (input_t *) NULL; ip = (input_t *) ip->next) + { + if((ip->flag & LIB3270_IO_FLAG_READ) && FD_ISSET(ip->fd, &rfds)) + { + (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_READ,ip->userdata); + processed_any = True; + if (hSession->inputs_changed) + goto retry; + } + + if((ip->flag & LIB3270_IO_FLAG_WRITE) && FD_ISSET(ip->fd, &wfds)) + { + (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_WRITE,ip->userdata); + processed_any = True; + if (hSession->inputs_changed) + goto retry; + } + + if((ip->flag & LIB3270_IO_FLAG_EXCEPTION) && FD_ISSET(ip->fd, &xfds)) + { + (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_EXCEPTION,ip->userdata); + processed_any = True; + if (hSession->inputs_changed) + goto retry; + } + } + } + + // See what's expired. + if (hSession->timeouts != TN) + { + struct timeout *t; + (void) gettimeofday(&now, (void *)NULL); + + while ((t = hSession->timeouts) != TN) + { + if (t->tv.tv_sec < now.tv_sec ||(t->tv.tv_sec == now.tv_sec && t->tv.tv_usec < now.tv_usec)) + { + hSession->timeouts = t->next; + t->in_play = True; + (*t->proc)(t->session); + processed_any = True; + lib3270_free(t); + } else + break; + } + } + + if (hSession->inputs_changed) + goto retry; + + return processed_any; + +} diff --git a/src/lib3270/private.h b/src/lib3270/private.h index c5a0127..425ae5f 100644 --- a/src/lib3270/private.h +++ b/src/lib3270/private.h @@ -279,8 +279,9 @@ typedef struct timeout * @brief I/O events. * */ -typedef struct input +typedef struct _input_t { + unsigned char enabled; struct input * next; H3270 * session; int fd; diff --git a/src/lib3270/windows/event_dispatcher.c b/src/lib3270/windows/event_dispatcher.c new file mode 100644 index 0000000..f246466 --- /dev/null +++ b/src/lib3270/windows/event_dispatcher.c @@ -0,0 +1,218 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + /** + * @brief Implements the default event dispatcher for windows. + * + */ + +#include "../private.h" +#include +#include +//#include "xioc.h" +//#include "telnetc.h" +//#include "utilc.h" + +//#define MILLION 1000000L +// #define MAX_HA 256 +//#endif + +/*---[ Implement ]------------------------------------------------------------------------------------------*/ + +static void ms_ts(unsigned long long *u) +{ + FILETIME t; + + /* Get the system time, in 100ns units. */ + GetSystemTimeAsFileTime(&t); + memcpy(u, &t, sizeof(unsigned long long)); + + /* Divide by 10,000 to get ms. */ + *u /= 10000ULL; +} + +/** + * @brief lib3270's default event dispatcher. + * + * @param hSession TN3270 session to process. + * @param block If non zero, the method blocks waiting for event. + * + */ +int lib3270_default_event_dispatcher(H3270 *hSession, int block) +{ + unsigned long long now; + int maxSock; + DWORD tmo; + + fd_set rfds, wfds, xfds; + + input_t *ip; + int processed_any = 0; + +retry: + + hSession->inputs_changed = 0; + + // If we've processed any input, then don't block again. + if(processed_any) + block = 0; + + maxSock = 0; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&xfds); + + for (ip = hSession->inputs; ip != (input_t *)NULL; ip = ip->next) + { + if(!ip->enabled) + { + debug("Socket %d is disabled",ip->fd); + continue; + } + + if(ip->flag & LIB3270_IO_FLAG_READ) + { + FD_SET(ip->fd, &rfds); + maxSock = max(ip->fd,maxSock); + } + + if(ip->flag & LIB3270_IO_FLAG_WRITE) + { + FD_SET(ip->fd, &wfds); + maxSock = max(ip->fd,maxSock); + } + + if(ip->flag & LIB3270_IO_FLAG_EXCEPTION) + { + FD_SET(ip->fd, &xfds); + maxSock = max(ip->fd,maxSock); + } + } + + if (block) + { + if (hSession->timeouts != TN) + { + ms_ts(&now); + if (now > hSession->timeouts->ts) + tmo = 0; + else + tmo = hSession->timeouts->ts - now; + } + else + { + // Block for 1 second (at maximal) + tmo = 1000; + } + } + else + { + tmo = 1000; + } + + if(maxSock) + { + struct timeval tm; + + tm.tv_sec = 0; + tm.tv_usec = tmo; + + int ns = select(maxSock+1, &rfds, &wfds, &xfds, &tm); + + if (ns < 0 && errno != EINTR) + { + lib3270_popup_dialog( hSession, + LIB3270_NOTIFY_ERROR, + _( "Network error" ), + _( "Select() failed when processing for events." ), + lib3270_win32_strerror(WSAGetLastError())); + } + else + { + for (ip = hSession->inputs; ip != (input_t *) NULL; ip = ip->next) + { + if((ip->flag & LIB3270_IO_FLAG_READ) && FD_ISSET(ip->fd, &rfds)) + { + (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_READ,ip->userdata); + processed_any = True; + if (hSession->inputs_changed) + goto retry; + } + + if ((ip->flag & LIB3270_IO_FLAG_WRITE) && FD_ISSET(ip->fd, &wfds)) + { + (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_WRITE,ip->userdata); + processed_any = True; + if (hSession->inputs_changed) + goto retry; + } + + if ((ip->flag & LIB3270_IO_FLAG_EXCEPTION) && FD_ISSET(ip->fd, &xfds)) + { + (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_EXCEPTION,ip->userdata); + processed_any = True; + if (hSession->inputs_changed) + goto retry; + } + } + } + } + else if(block) + { + Sleep(tmo); + } + + // See what's expired. + if (hSession->timeouts != TN) + { + struct timeout *t; + ms_ts(&now); + + while ((t = hSession->timeouts) != TN) + { + if (t->ts <= now) + { + hSession->timeouts = t->next; + t->in_play = True; + (*t->proc)(t->session); + processed_any = True; + lib3270_free(t); + } else + break; + } + } + + if (hSession->inputs_changed) + goto retry; + + return processed_any; + +} + -- libgit2 0.21.2