summaryrefslogtreecommitdiff
path: root/nuttx/examples/nsh/nsh_telnetd.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-09-01 15:56:03 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-09-01 15:56:03 +0000
commitd1b7c771f5845e1eae16513be3cbb7e0a0b45612 (patch)
tree368b91eb1135c6ebd10845fcdd727dc0e2065f2c /nuttx/examples/nsh/nsh_telnetd.c
parentbe49f2a7430aa0dd9c0c09002af15bb2618cadb0 (diff)
downloadpx4-nuttx-d1b7c771f5845e1eae16513be3cbb7e0a0b45612.tar.gz
px4-nuttx-d1b7c771f5845e1eae16513be3cbb7e0a0b45612.tar.bz2
px4-nuttx-d1b7c771f5845e1eae16513be3cbb7e0a0b45612.zip
Need separate output buffers for each thread
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@860 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/examples/nsh/nsh_telnetd.c')
-rw-r--r--nuttx/examples/nsh/nsh_telnetd.c106
1 files changed, 30 insertions, 76 deletions
diff --git a/nuttx/examples/nsh/nsh_telnetd.c b/nuttx/examples/nsh/nsh_telnetd.c
index 9699aa651..052970877 100644
--- a/nuttx/examples/nsh/nsh_telnetd.c
+++ b/nuttx/examples/nsh/nsh_telnetd.c
@@ -91,13 +91,10 @@
struct telnetio_s
{
sem_t tio_sem;
- pid_t tio_holder;
int tio_sockfd;
- uint16 tio_sndlen;
uint8 tio_bufndx;
uint8 tio_state;
- uint8 tio_semnest;
- char tio_buffer[CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE];
+ char tio_inbuffer[CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE];
};
struct redirect_s
@@ -119,12 +116,14 @@ struct telnetsave_s
struct telnetd_s
{
struct nsh_vtbl_s tn_vtbl;
+ uint16 tn_sndlen;
boolean tn_redirected;
union
{
struct telnetio_s *tn;
struct redirect_s rd;
} u;
+ char tn_outbuffer[CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE];
char tn_cmd[CONFIG_EXAMPLES_NSH_LINELEN];
};
@@ -132,6 +131,7 @@ struct telnetd_s
* Private Function Prototypes
****************************************************************************/
+static void tio_semtake(struct telnetio_s *tio);
static FAR struct nsh_vtbl_s *nsh_telnetclone(FAR struct nsh_vtbl_s *vtbl);
static void nsh_telnetrelease(FAR struct nsh_vtbl_s *vtbl);
static int nsh_telnetoutput(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...);
@@ -151,33 +151,15 @@ static void nsh_telnetexit(FAR struct nsh_vtbl_s *vtbl);
static void tio_semtake(struct telnetio_s *tio)
{
- pid_t my_pid = getpid();
+ /* Take the semaphore (perhaps waiting) */
- /* Does this task already have the semaphore? */
-
- if (tio->tio_holder == my_pid)
+ while (sem_wait(&tio->tio_sem) != 0)
{
- /* Yes, just increment the number of references that the task holds */
-
- tio->tio_semnest++;
- }
- else
- {
- /* No, Take the semaphore (perhaps waiting) */
-
- while (sem_wait(&tio->tio_sem) != 0)
- {
- /* The only case that an error should occur here is if the wait was
- * awakened by a signal.
- */
+ /* The only case that an error should occur here is if the wait was
+ * awakened by a signal.
+ */
- ASSERT(errno == EINTR);
- }
-
- /* Stake the claim and return */
-
- tio->tio_holder = my_pid;
- tio->tio_semnest = 1;
+ ASSERT(errno == EINTR);
}
}
@@ -185,31 +167,7 @@ static void tio_semtake(struct telnetio_s *tio)
* Name: tio_semgive
****************************************************************************/
-static void tio_semgive(struct telnetio_s *tio)
-{
- pid_t my_pid = getpid();
-
- /* I better be holding at least one count on the semaphore */
-
- ASSERT(tio->tio_holder == my_pid);
-
- /* Do I hold multiple references to the semphore */
-
- if (tio->tio_semnest > 1)
- {
- /* Yes, just release one count and return */
-
- tio->tio_semnest--;
- }
- else
- {
- /* Nope, this is the last reference I have */
-
- tio->tio_holder = -1;
- tio->tio_semnest = 0;
- ASSERT(sem_post(&tio->tio_sem) == 0);
- }
-}
+#define tio_semgive(tio) ASSERT(sem_post(&tio->tio_sem) == 0)
/****************************************************************************
* Name: nsh_dumpbuffer
@@ -393,10 +351,12 @@ static void nsh_sendopt(struct telnetd_s *pstate, uint8 option, uint8 value)
optbuf[3] = 0;
nsh_dumpbuffer("Send optbuf", optbuf, 4);
+ tio_semtake(tio); /* Only one call to send at a time */
if (send(tio->tio_sockfd, optbuf, 4, 0) < 0)
{
dbg("[%d] Failed to send TELNET_IAC: %d\n", tio->tio_sockfd, errno);
}
+ tio_semgive(tio);
}
/****************************************************************************
@@ -411,17 +371,17 @@ static void nsh_flush(FAR struct telnetd_s *pstate)
{
struct telnetio_s *tio = pstate->u.tn;
- tio_semtake(tio);
- if (tio->tio_sndlen > 0)
+ if (pstate->tn_sndlen > 0)
{
- nsh_dumpbuffer("Shell output", tio->tio_buffer, tio->tio_sndlen);
- if (send(tio->tio_sockfd, tio->tio_buffer, tio->tio_sndlen, 0) < 0)
+ nsh_dumpbuffer("Shell output", pstate->tn_outbuffer, pstate->tn_sndlen);
+ tio_semtake(tio); /* Only one call to send at a time */
+ if (send(tio->tio_sockfd, pstate->tn_outbuffer, pstate->tn_sndlen, 0) < 0)
{
dbg("[%d] Failed to send response: %d\n", tio->tio_sockfd, errno);
}
+ tio_semgive(tio);
}
- tio->tio_sndlen = 0;
- tio_semgive(tio);
+ pstate->tn_sndlen = 0;
}
/****************************************************************************
@@ -435,10 +395,9 @@ static void nsh_flush(FAR struct telnetd_s *pstate)
static int nsh_receive(struct telnetd_s *pstate, size_t len)
{
struct telnetio_s *tio = pstate->u.tn;
- char *ptr = tio->tio_buffer;
+ char *ptr = tio->tio_inbuffer;
uint8 ch;
- tio_semtake(tio);
while (len > 0)
{
ch = *ptr++;
@@ -520,7 +479,6 @@ static int nsh_receive(struct telnetd_s *pstate, size_t len)
break;
}
}
- tio_semgive(tio);
return OK;
}
@@ -569,13 +527,13 @@ static void *nsh_connection(void *arg)
/* Read a buffer of data from the TELNET client */
- ret = recv(tio->tio_sockfd, tio->tio_buffer, CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE, 0);
+ ret = recv(tio->tio_sockfd, tio->tio_inbuffer, CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE, 0);
if (ret > 0)
{
/* Process the received TELNET data */
- nsh_dumpbuffer("Received buffer", tio->tio_buffer, ret);
+ nsh_dumpbuffer("Received buffer", tio->tio_inbuffer, ret);
ret = nsh_receive(pstate, ret);
}
}
@@ -618,19 +576,16 @@ static void *nsh_connection(void *arg)
static int nsh_telnetoutput(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...)
{
struct telnetd_s *pstate = (struct telnetd_s *)vtbl;
- struct telnetio_s *tio = pstate->u.tn;
- int nbytes = tio->tio_sndlen;
+ int nbytes = pstate->tn_sndlen;
int len;
va_list ap;
- tio_semtake(tio);
-
/* Put the new info into the buffer. Here we are counting on the fact that
* no output strings will exceed CONFIG_EXAMPLES_NSH_LINELEN!
*/
va_start(ap, fmt);
- vsnprintf(&tio->tio_buffer[nbytes],
+ vsnprintf(&pstate->tn_outbuffer[nbytes],
(CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE - 1) - nbytes, fmt, ap);
va_end(ap);
@@ -638,26 +593,25 @@ static int nsh_telnetoutput(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...)
* buffered data
*/
- len = strlen(&tio->tio_buffer[nbytes]);
+ len = strlen(&pstate->tn_outbuffer[nbytes]);
nbytes += len;
/* Expand any terminating \n to \r\n */
if (nbytes < (CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE - 2) &&
- tio->tio_buffer[nbytes-1] == '\n')
+ pstate->tn_outbuffer[nbytes-1] == '\n')
{
- tio->tio_buffer[nbytes-1] = ISO_cr;
- tio->tio_buffer[nbytes] = ISO_nl;
- tio->tio_buffer[nbytes+1] = '\0';
+ pstate->tn_outbuffer[nbytes-1] = ISO_cr;
+ pstate->tn_outbuffer[nbytes] = ISO_nl;
+ pstate->tn_outbuffer[nbytes+1] = '\0';
nbytes++;
}
- tio->tio_sndlen = nbytes;
+ pstate->tn_sndlen = nbytes;
/* Flush to the network if the buffer does not have room for one more
* maximum length string.
*/
- tio_semgive(tio);
if (nbytes > CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE - CONFIG_EXAMPLES_NSH_LINELEN)
{
nsh_flush(pstate);