mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 00:14:22 +08:00
drivers/telnet: Remove io work thread
The thread isn't really needed but complicate the workflow Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
committed by
Masayuki Ishikawa
parent
c3b6d35290
commit
0fa17f32f2
@@ -127,7 +127,6 @@ CONFIG_SYSTEM_NSH=y
|
|||||||
CONFIG_SYSTEM_NSH_PROGNAME="init"
|
CONFIG_SYSTEM_NSH_PROGNAME="init"
|
||||||
CONFIG_SYSTEM_PING=y
|
CONFIG_SYSTEM_PING=y
|
||||||
CONFIG_SYSTEM_TELNETD=y
|
CONFIG_SYSTEM_TELNETD=y
|
||||||
CONFIG_TELNET_IOTHREAD_STACKSIZE=2048
|
|
||||||
CONFIG_TESTING_GETPRIME=y
|
CONFIG_TESTING_GETPRIME=y
|
||||||
CONFIG_TLS_TASK_NELEM=4
|
CONFIG_TLS_TASK_NELEM=4
|
||||||
CONFIG_UART1_SERIAL_CONSOLE=y
|
CONFIG_UART1_SERIAL_CONSOLE=y
|
||||||
|
|||||||
@@ -128,7 +128,6 @@ CONFIG_SYSTEM_NSH=y
|
|||||||
CONFIG_SYSTEM_NSH_PROGNAME="init"
|
CONFIG_SYSTEM_NSH_PROGNAME="init"
|
||||||
CONFIG_SYSTEM_PING=y
|
CONFIG_SYSTEM_PING=y
|
||||||
CONFIG_SYSTEM_TELNETD=y
|
CONFIG_SYSTEM_TELNETD=y
|
||||||
CONFIG_TELNET_IOTHREAD_STACKSIZE=2048
|
|
||||||
CONFIG_TESTING_GETPRIME=y
|
CONFIG_TESTING_GETPRIME=y
|
||||||
CONFIG_TESTING_SMP=y
|
CONFIG_TESTING_SMP=y
|
||||||
CONFIG_TLS_TASK_NELEM=4
|
CONFIG_TLS_TASK_NELEM=4
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ CONFIG_SYSTEM_NSH=y
|
|||||||
CONFIG_SYSTEM_PING=y
|
CONFIG_SYSTEM_PING=y
|
||||||
CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048
|
CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048
|
||||||
CONFIG_TELNET_CHARACTER_MODE=y
|
CONFIG_TELNET_CHARACTER_MODE=y
|
||||||
CONFIG_TELNET_IOTHREAD_STACKSIZE=2048
|
|
||||||
CONFIG_TLS_TASK_NELEM=4
|
CONFIG_TLS_TASK_NELEM=4
|
||||||
CONFIG_UART0_SERIAL_CONSOLE=y
|
CONFIG_UART0_SERIAL_CONSOLE=y
|
||||||
CONFIG_WIRELESS=y
|
CONFIG_WIRELESS=y
|
||||||
|
|||||||
@@ -127,7 +127,6 @@ CONFIG_SYSTEM_NSH=y
|
|||||||
CONFIG_SYSTEM_PING=y
|
CONFIG_SYSTEM_PING=y
|
||||||
CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048
|
CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048
|
||||||
CONFIG_TELNET_CHARACTER_MODE=y
|
CONFIG_TELNET_CHARACTER_MODE=y
|
||||||
CONFIG_TELNET_IOTHREAD_STACKSIZE=2048
|
|
||||||
CONFIG_TLS_TASK_NELEM=4
|
CONFIG_TLS_TASK_NELEM=4
|
||||||
CONFIG_UART0_SERIAL_CONSOLE=y
|
CONFIG_UART0_SERIAL_CONSOLE=y
|
||||||
CONFIG_WIRELESS=y
|
CONFIG_WIRELESS=y
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ CONFIG_SYSTEM_PING=y
|
|||||||
CONFIG_SYSTEM_STACKMONITOR=y
|
CONFIG_SYSTEM_STACKMONITOR=y
|
||||||
CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048
|
CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048
|
||||||
CONFIG_TELNET_CHARACTER_MODE=y
|
CONFIG_TELNET_CHARACTER_MODE=y
|
||||||
CONFIG_TELNET_IOTHREAD_STACKSIZE=2048
|
|
||||||
CONFIG_TLS_TASK_NELEM=4
|
CONFIG_TLS_TASK_NELEM=4
|
||||||
CONFIG_UART0_SERIAL_CONSOLE=y
|
CONFIG_UART0_SERIAL_CONSOLE=y
|
||||||
CONFIG_WIRELESS=y
|
CONFIG_WIRELESS=y
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ CONFIG_SYSTEM_PING=y
|
|||||||
CONFIG_SYSTEM_STACKMONITOR=y
|
CONFIG_SYSTEM_STACKMONITOR=y
|
||||||
CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048
|
CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048
|
||||||
CONFIG_TELNET_CHARACTER_MODE=y
|
CONFIG_TELNET_CHARACTER_MODE=y
|
||||||
CONFIG_TELNET_IOTHREAD_STACKSIZE=2048
|
|
||||||
CONFIG_TLS_TASK_NELEM=4
|
CONFIG_TLS_TASK_NELEM=4
|
||||||
CONFIG_UART0_SERIAL_CONSOLE=y
|
CONFIG_UART0_SERIAL_CONSOLE=y
|
||||||
CONFIG_WIRELESS=y
|
CONFIG_WIRELESS=y
|
||||||
|
|||||||
@@ -106,7 +106,6 @@ CONFIG_SYSTEM_NTPC=y
|
|||||||
CONFIG_SYSTEM_PING=y
|
CONFIG_SYSTEM_PING=y
|
||||||
CONFIG_SYSTEM_SYSTEM=y
|
CONFIG_SYSTEM_SYSTEM=y
|
||||||
CONFIG_SYSTEM_TASKSET=y
|
CONFIG_SYSTEM_TASKSET=y
|
||||||
CONFIG_TELNET_IOTHREAD_STACKSIZE=1280
|
|
||||||
CONFIG_TESTING_GETPRIME=y
|
CONFIG_TESTING_GETPRIME=y
|
||||||
CONFIG_TESTING_OSTEST=y
|
CONFIG_TESTING_OSTEST=y
|
||||||
CONFIG_TESTING_SMP=y
|
CONFIG_TESTING_SMP=y
|
||||||
|
|||||||
@@ -82,14 +82,6 @@ config TELNET_CHARACTER_MODE
|
|||||||
will echo a character which telnet client sent. By default, it works
|
will echo a character which telnet client sent. By default, it works
|
||||||
in line mode.
|
in line mode.
|
||||||
|
|
||||||
config TELNET_IOTHREAD_PRIORITY
|
|
||||||
int "I/O thread priority"
|
|
||||||
default 100
|
|
||||||
|
|
||||||
config TELNET_IOTHREAD_STACKSIZE
|
|
||||||
int "I/O thread stack size"
|
|
||||||
default 1024
|
|
||||||
|
|
||||||
config TELNET_SUPPORT_NAWS
|
config TELNET_SUPPORT_NAWS
|
||||||
bool "Support NAWS (Negotiate About Window Size)"
|
bool "Support NAWS (Negotiate About Window Size)"
|
||||||
default n
|
default n
|
||||||
|
|||||||
+20
-233
@@ -59,14 +59,6 @@
|
|||||||
# define CONFIG_TELNET_MAXLCLIENTS 8
|
# define CONFIG_TELNET_MAXLCLIENTS 8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_TELNET_IOTHREAD_PRIORITY
|
|
||||||
# define CONFIG_TELNET_IOTHREAD_PRIORITY 100
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CONFIG_TELNET_IOTHREAD_STACKSIZE
|
|
||||||
# define CONFIG_TELNET_IOTHREAD_STACKSIZE 1024
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef HAVE_SIGNALS
|
#undef HAVE_SIGNALS
|
||||||
#if defined(CONFIG_TTY_SIGINT) || defined(CONFIG_TTY_SIGTSTP)
|
#if defined(CONFIG_TTY_SIGINT) || defined(CONFIG_TTY_SIGTSTP)
|
||||||
# define HAVE_SIGNALS
|
# define HAVE_SIGNALS
|
||||||
@@ -120,8 +112,6 @@ enum telnet_state_e
|
|||||||
|
|
||||||
struct telnet_dev_s
|
struct telnet_dev_s
|
||||||
{
|
{
|
||||||
sem_t td_exclsem; /* Enforces mutually exclusive access */
|
|
||||||
sem_t td_iosem; /* I/O thread will notify that data is available */
|
|
||||||
uint8_t td_state; /* (See telnet_state_e) */
|
uint8_t td_state; /* (See telnet_state_e) */
|
||||||
uint8_t td_crefs; /* The number of open references to the session */
|
uint8_t td_crefs; /* The number of open references to the session */
|
||||||
uint8_t td_minor; /* Minor device number */
|
uint8_t td_minor; /* Minor device number */
|
||||||
@@ -135,7 +125,6 @@ struct telnet_dev_s
|
|||||||
#ifdef HAVE_SIGNALS
|
#ifdef HAVE_SIGNALS
|
||||||
pid_t td_pid;
|
pid_t td_pid;
|
||||||
#endif
|
#endif
|
||||||
struct pollfd td_fds;
|
|
||||||
FAR struct socket td_psock; /* A clone of the internal socket structure */
|
FAR struct socket td_psock; /* A clone of the internal socket structure */
|
||||||
char td_rxbuffer[CONFIG_TELNET_RXBUFFER_SIZE];
|
char td_rxbuffer[CONFIG_TELNET_RXBUFFER_SIZE];
|
||||||
char td_txbuffer[CONFIG_TELNET_TXBUFFER_SIZE];
|
char td_txbuffer[CONFIG_TELNET_TXBUFFER_SIZE];
|
||||||
@@ -162,7 +151,6 @@ static bool telnet_putchar(FAR struct telnet_dev_s *priv, uint8_t ch,
|
|||||||
int *nwritten);
|
int *nwritten);
|
||||||
static void telnet_sendopt(FAR struct telnet_dev_s *priv, uint8_t option,
|
static void telnet_sendopt(FAR struct telnet_dev_s *priv, uint8_t option,
|
||||||
uint8_t value);
|
uint8_t value);
|
||||||
static int telnet_io_main(int argc, FAR char** argv);
|
|
||||||
|
|
||||||
/* Telnet character driver methods */
|
/* Telnet character driver methods */
|
||||||
|
|
||||||
@@ -227,9 +215,7 @@ static const struct file_operations g_factory_fops =
|
|||||||
* characters received via Telenet (via Ctrl-C SIGINT, in particular).
|
* characters received via Telenet (via Ctrl-C SIGINT, in particular).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static pid_t g_telnet_io_kthread = INVALID_PROCESS_ID;
|
|
||||||
static struct telnet_dev_s *g_telnet_clients[CONFIG_TELNET_MAXLCLIENTS];
|
static struct telnet_dev_s *g_telnet_clients[CONFIG_TELNET_MAXLCLIENTS];
|
||||||
static sem_t g_iosem = SEM_INITIALIZER(0);
|
|
||||||
static sem_t g_clients_sem = SEM_INITIALIZER(1);
|
static sem_t g_clients_sem = SEM_INITIALIZER(1);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -644,7 +630,7 @@ static int telnet_open(FAR struct file *filep)
|
|||||||
|
|
||||||
/* Get exclusive access to the device structures */
|
/* Get exclusive access to the device structures */
|
||||||
|
|
||||||
ret = nxsem_wait(&priv->td_exclsem);
|
ret = nxsem_wait(&g_clients_sem);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nerr("ERROR: nxsem_wait failed: %d\n", ret);
|
nerr("ERROR: nxsem_wait failed: %d\n", ret);
|
||||||
@@ -671,7 +657,7 @@ static int telnet_open(FAR struct file *filep)
|
|||||||
ret = OK;
|
ret = OK;
|
||||||
|
|
||||||
errout_with_sem:
|
errout_with_sem:
|
||||||
nxsem_post(&priv->td_exclsem);
|
nxsem_post(&g_clients_sem);
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
return ret;
|
return ret;
|
||||||
@@ -693,11 +679,11 @@ static int telnet_close(FAR struct file *filep)
|
|||||||
|
|
||||||
/* Get exclusive access to the device structures */
|
/* Get exclusive access to the device structures */
|
||||||
|
|
||||||
ret = nxsem_wait(&priv->td_exclsem);
|
ret = nxsem_wait(&g_clients_sem);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nerr("ERROR: nxsem_wait failed: %d\n", ret);
|
nerr("ERROR: nxsem_wait failed: %d\n", ret);
|
||||||
goto errout;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decrement the references to the driver. If the reference count will
|
/* Decrement the references to the driver. If the reference count will
|
||||||
@@ -709,7 +695,6 @@ static int telnet_close(FAR struct file *filep)
|
|||||||
/* Just decrement the reference count and release the semaphore */
|
/* Just decrement the reference count and release the semaphore */
|
||||||
|
|
||||||
priv->td_crefs--;
|
priv->td_crefs--;
|
||||||
nxsem_post(&priv->td_exclsem);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -748,9 +733,6 @@ static int telnet_close(FAR struct file *filep)
|
|||||||
kmm_free(devpath);
|
kmm_free(devpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove ourself from the clients list */
|
|
||||||
|
|
||||||
nxsem_wait(&g_clients_sem);
|
|
||||||
for (i = 0; i < CONFIG_TELNET_MAXLCLIENTS; i++)
|
for (i = 0; i < CONFIG_TELNET_MAXLCLIENTS; i++)
|
||||||
{
|
{
|
||||||
if (g_telnet_clients[i] == priv)
|
if (g_telnet_clients[i] == priv)
|
||||||
@@ -760,40 +742,13 @@ static int telnet_close(FAR struct file *filep)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the socket is still polling */
|
|
||||||
|
|
||||||
if (priv->td_fds.events)
|
|
||||||
{
|
|
||||||
/* Tear down the poll */
|
|
||||||
|
|
||||||
psock_poll(&priv->td_psock, &priv->td_fds, FALSE);
|
|
||||||
priv->td_fds.events = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
nxsem_post(&g_clients_sem);
|
|
||||||
|
|
||||||
/* Notify the I/O thread that a client was removed */
|
|
||||||
|
|
||||||
nxsem_post(&g_iosem);
|
|
||||||
|
|
||||||
/* Close the socket */
|
/* Close the socket */
|
||||||
|
|
||||||
psock_close(&priv->td_psock);
|
psock_close(&priv->td_psock);
|
||||||
|
|
||||||
/* Release the driver memory. What if there are threads waiting on
|
|
||||||
* td_exclsem? They will never be awakened! How could this happen?
|
|
||||||
* crefs == 1 so there are no other open references to the driver.
|
|
||||||
* But this could have if someone were trying to re-open the driver
|
|
||||||
* after every other thread has closed it. That really should not
|
|
||||||
* happen in the intended usage model.
|
|
||||||
*/
|
|
||||||
|
|
||||||
DEBUGASSERT(priv->td_exclsem.semcount == 0);
|
|
||||||
nxsem_destroy(&priv->td_exclsem);
|
|
||||||
kmm_free(priv);
|
kmm_free(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
errout:
|
nxsem_post(&g_clients_sem);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -807,7 +762,6 @@ static ssize_t telnet_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
FAR struct inode *inode = filep->f_inode;
|
FAR struct inode *inode = filep->f_inode;
|
||||||
FAR struct telnet_dev_s *priv = inode->i_private;
|
FAR struct telnet_dev_s *priv = inode->i_private;
|
||||||
ssize_t nread = 0;
|
ssize_t nread = 0;
|
||||||
int ret;
|
|
||||||
|
|
||||||
ninfo("len: %zd\n", len);
|
ninfo("len: %zd\n", len);
|
||||||
|
|
||||||
@@ -824,54 +778,32 @@ static ssize_t telnet_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
|
|
||||||
if (priv->td_pending == 0)
|
if (priv->td_pending == 0)
|
||||||
{
|
{
|
||||||
/* poll fds.revents contains last poll status in case of error */
|
nread = psock_recv(&priv->td_psock,
|
||||||
|
priv->td_rxbuffer,
|
||||||
if ((priv->td_fds.revents & (POLLHUP | POLLERR)) != 0)
|
CONFIG_TELNET_RXBUFFER_SIZE,
|
||||||
|
0);
|
||||||
|
if (nread <= 0)
|
||||||
{
|
{
|
||||||
return -EPIPE;
|
return nread;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filep->f_oflags & O_NONBLOCK)
|
priv->td_pending = nread;
|
||||||
{
|
|
||||||
return -EAGAIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait for new data, interrupt, or thread cancellation */
|
|
||||||
|
|
||||||
ret = nxsem_wait(&priv->td_iosem);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
nerr("ERROR: nxsem_wait failed: %d\n", ret);
|
|
||||||
return (ssize_t)ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Take exclusive access to data buffer */
|
|
||||||
|
|
||||||
ret = nxsem_wait(&priv->td_exclsem);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
nerr("ERROR: nxsem_wait failed: %d\n", ret);
|
|
||||||
return (ssize_t)ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process the buffered telnet data */
|
/* Process the buffered telnet data */
|
||||||
|
|
||||||
src = &priv->td_rxbuffer[priv->td_offset];
|
src = &priv->td_rxbuffer[priv->td_offset];
|
||||||
nread = telnet_receive(priv, src, priv->td_pending, buffer, len);
|
nread = telnet_receive(priv, src, priv->td_pending, buffer, len);
|
||||||
|
|
||||||
nxsem_post(&priv->td_exclsem);
|
|
||||||
}
|
}
|
||||||
while (nread == 0);
|
while (nread == 0);
|
||||||
|
|
||||||
/* Notify the I/O thread the rxbuffer is available */
|
#ifdef HAVE_SIGNALS
|
||||||
|
/* Check if any of the received characters is a
|
||||||
|
* control that should generate a signal.
|
||||||
|
*/
|
||||||
|
|
||||||
if (nread > 0)
|
telnet_check_ctrlchar(priv, buffer, nread);
|
||||||
{
|
#endif
|
||||||
nxsem_post(&g_iosem);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returned Value:
|
/* Returned Value:
|
||||||
*
|
*
|
||||||
@@ -893,8 +825,8 @@ static ssize_t telnet_write(FAR struct file *filep, FAR const char *buffer,
|
|||||||
FAR struct inode *inode = filep->f_inode;
|
FAR struct inode *inode = filep->f_inode;
|
||||||
FAR struct telnet_dev_s *priv = inode->i_private;
|
FAR struct telnet_dev_s *priv = inode->i_private;
|
||||||
FAR const char *src = buffer;
|
FAR const char *src = buffer;
|
||||||
|
ssize_t ret = 0;
|
||||||
ssize_t nsent;
|
ssize_t nsent;
|
||||||
ssize_t ret;
|
|
||||||
int ncopied;
|
int ncopied;
|
||||||
char ch;
|
char ch;
|
||||||
bool eol;
|
bool eol;
|
||||||
@@ -990,17 +922,6 @@ static int telnet_session(FAR struct telnet_session_s *session)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the allocated driver instance */
|
|
||||||
|
|
||||||
nxsem_init(&priv->td_exclsem, 0, 1);
|
|
||||||
nxsem_init(&priv->td_iosem, 0, 0);
|
|
||||||
|
|
||||||
/* td_iosem is used for signaling and, hence, must not participate in
|
|
||||||
* priority inheritance.
|
|
||||||
*/
|
|
||||||
|
|
||||||
nxsem_set_protocol(&priv->td_iosem, SEM_PRIO_NONE);
|
|
||||||
|
|
||||||
priv->td_state = STATE_NORMAL;
|
priv->td_state = STATE_NORMAL;
|
||||||
priv->td_crefs = 0;
|
priv->td_crefs = 0;
|
||||||
priv->td_minor = 0;
|
priv->td_minor = 0;
|
||||||
@@ -1091,32 +1012,10 @@ static int telnet_session(FAR struct telnet_session_s *session)
|
|||||||
telnet_sendopt(priv, TELNET_WILL, TELNET_ECHO);
|
telnet_sendopt(priv, TELNET_WILL, TELNET_ECHO);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Has the I/O thread been started? */
|
|
||||||
|
|
||||||
if (g_telnet_io_kthread == INVALID_PROCESS_ID)
|
|
||||||
{
|
|
||||||
/* g_iosem is used for signaling and, hence, must not participate in
|
|
||||||
* priority inheritance.
|
|
||||||
*/
|
|
||||||
|
|
||||||
nxsem_set_protocol(&g_iosem, SEM_PRIO_NONE);
|
|
||||||
|
|
||||||
/* Start the I/O thread */
|
|
||||||
|
|
||||||
ret = kthread_create("telnet_io", CONFIG_TELNET_IOTHREAD_PRIORITY,
|
|
||||||
CONFIG_TELNET_IOTHREAD_STACKSIZE, telnet_io_main,
|
|
||||||
NULL);
|
|
||||||
if (ret > 0)
|
|
||||||
{
|
|
||||||
g_telnet_io_kthread = ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save ourself in the list of Telnet client threads */
|
/* Save ourself in the list of Telnet client threads */
|
||||||
|
|
||||||
g_telnet_clients[priv->td_minor] = priv;
|
g_telnet_clients[priv->td_minor] = priv;
|
||||||
nxsem_post(&g_clients_sem);
|
nxsem_post(&g_clients_sem);
|
||||||
nxsem_post(&g_iosem);
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
@@ -1197,11 +1096,10 @@ static int telnet_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = -ENOTTY;
|
ret = psock_ioctl(&priv->td_psock, cmd, arg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNUSED(priv); /* Avoid warning if not used */
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1245,117 +1143,6 @@ static int telnet_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
|||||||
return psock_poll(&priv->td_psock, fds, setup);
|
return psock_poll(&priv->td_psock, fds, setup);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: telnet_io_main
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static int telnet_io_main(int argc, FAR char** argv)
|
|
||||||
{
|
|
||||||
FAR struct telnet_dev_s *priv;
|
|
||||||
FAR char *buffer;
|
|
||||||
int i;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
nxsem_reset(&g_iosem, 0);
|
|
||||||
|
|
||||||
/* Poll each client in the g_telnet_clients[] array. */
|
|
||||||
|
|
||||||
nxsem_wait(&g_clients_sem);
|
|
||||||
for (i = 0; i < CONFIG_TELNET_MAXLCLIENTS; i++)
|
|
||||||
{
|
|
||||||
priv = g_telnet_clients[i];
|
|
||||||
if (priv != NULL &&
|
|
||||||
!(priv->td_fds.revents & (POLLHUP | POLLERR)) &&
|
|
||||||
(CONFIG_TELNET_RXBUFFER_SIZE -
|
|
||||||
priv->td_pending - priv->td_offset) > 0)
|
|
||||||
{
|
|
||||||
priv->td_fds.sem = &g_iosem;
|
|
||||||
priv->td_fds.events = POLLIN | POLLHUP | POLLERR;
|
|
||||||
priv->td_fds.revents = 0;
|
|
||||||
|
|
||||||
psock_poll(&priv->td_psock, &priv->td_fds, TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nxsem_post(&g_clients_sem);
|
|
||||||
|
|
||||||
/* Wait for any Telnet connect/disconnect events
|
|
||||||
* to include/remove client sockets from polling
|
|
||||||
*/
|
|
||||||
|
|
||||||
nxsem_wait(&g_iosem);
|
|
||||||
|
|
||||||
/* Revisit each client in the g_telnet_clients[] array */
|
|
||||||
|
|
||||||
nxsem_wait(&g_clients_sem);
|
|
||||||
for (i = 0; i < CONFIG_TELNET_MAXLCLIENTS; i++)
|
|
||||||
{
|
|
||||||
priv = g_telnet_clients[i];
|
|
||||||
|
|
||||||
/* If poll was setup previously (events != 0) */
|
|
||||||
|
|
||||||
if (priv != NULL && priv->td_fds.events)
|
|
||||||
{
|
|
||||||
/* Check for a pending poll() */
|
|
||||||
|
|
||||||
if (priv->td_fds.revents & POLLIN)
|
|
||||||
{
|
|
||||||
if (priv->td_pending < CONFIG_TELNET_RXBUFFER_SIZE)
|
|
||||||
{
|
|
||||||
/* Take exclusive access to data buffer */
|
|
||||||
|
|
||||||
nxsem_wait(&priv->td_exclsem);
|
|
||||||
buffer = priv->td_rxbuffer + priv->td_pending +
|
|
||||||
priv->td_offset;
|
|
||||||
|
|
||||||
ret = psock_recv(&priv->td_psock, buffer,
|
|
||||||
CONFIG_TELNET_RXBUFFER_SIZE -
|
|
||||||
priv->td_pending - priv->td_offset,
|
|
||||||
0);
|
|
||||||
|
|
||||||
priv->td_pending += ret;
|
|
||||||
nxsem_post(&priv->td_exclsem);
|
|
||||||
|
|
||||||
/* Notify the client thread that data is available */
|
|
||||||
|
|
||||||
nxsem_post(&priv->td_iosem);
|
|
||||||
|
|
||||||
#ifdef HAVE_SIGNALS
|
|
||||||
/* Check if any of the received characters is a
|
|
||||||
* control that should generate a signal.
|
|
||||||
*/
|
|
||||||
|
|
||||||
telnet_check_ctrlchar(priv, buffer, ret);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Tear it down */
|
|
||||||
|
|
||||||
psock_poll(&priv->td_psock, &priv->td_fds, FALSE);
|
|
||||||
priv->td_fds.events = 0;
|
|
||||||
|
|
||||||
/* POLLHUP (or POLLERR) indicates that this session has
|
|
||||||
* terminated.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (priv->td_fds.revents & (POLLHUP | POLLERR))
|
|
||||||
{
|
|
||||||
/* notify the client thread */
|
|
||||||
|
|
||||||
nxsem_post(&priv->td_iosem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nxsem_post(&g_clients_sem);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: factory_ioctl
|
* Name: factory_ioctl
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|||||||
Reference in New Issue
Block a user