diff options
Diffstat (limited to 'nuttx/examples')
-rw-r--r-- | nuttx/examples/nsh/nsh.h | 2 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh_fscmds.c | 2 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh_serial.c | 92 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh_telnetd.c | 63 |
4 files changed, 151 insertions, 8 deletions
diff --git a/nuttx/examples/nsh/nsh.h b/nuttx/examples/nsh/nsh.h index ef03ddc9d..a7a04a908 100644 --- a/nuttx/examples/nsh/nsh.h +++ b/nuttx/examples/nsh/nsh.h @@ -177,6 +177,7 @@ #define nsh_clone(v) (v)->clone(v) #define nsh_release(v) (v)->release(v) +#define nsh_write(v,b,n) (v)->write(v,b,n) #define nsh_linebuffer(v) (v)->linebuffer(v) #define nsh_redirect(v,f,s) (v)->redirect(v,f,s) #define nsh_undirect(v,s) (v)->undirect(v,s) @@ -255,6 +256,7 @@ struct nsh_vtbl_s void (*addref)(FAR struct nsh_vtbl_s *vtbl); void (*release)(FAR struct nsh_vtbl_s *vtbl); #endif + ssize_t (*write)(FAR struct nsh_vtbl_s *vtbl, FAR const void *buffer, size_t nbytes); int (*output)(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...); FAR char *(*linebuffer)(FAR struct nsh_vtbl_s *vtbl); void (*redirect)(FAR struct nsh_vtbl_s *vtbl, int fd, FAR uint8_t *save); diff --git a/nuttx/examples/nsh/nsh_fscmds.c b/nuttx/examples/nsh/nsh_fscmds.c index eb43ed23c..40f894ec8 100644 --- a/nuttx/examples/nsh/nsh_fscmds.c +++ b/nuttx/examples/nsh/nsh_fscmds.c @@ -457,7 +457,7 @@ int cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) while (nbyteswritten < nbytesread) { - int n = write(1, buffer, nbytesread); + ssize_t n = nsh_write(vtbl, buffer, nbytesread); if (n < 0) { /* EINTR is not an error (but will stop stop the cat) */ diff --git a/nuttx/examples/nsh/nsh_serial.c b/nuttx/examples/nsh/nsh_serial.c index 1f76de533..0704cf080 100644 --- a/nuttx/examples/nsh/nsh_serial.c +++ b/nuttx/examples/nsh/nsh_serial.c @@ -1,7 +1,7 @@ /**************************************************************************** * examples/nsh/nsh_serial.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -45,6 +45,8 @@ #include <unistd.h> #include <string.h> #include <stdarg.h> +#include <errno.h> +#include <debug.h> #include "nsh.h" @@ -78,6 +80,7 @@ struct serialsave_s static FAR struct nsh_vtbl_s *nsh_consoleclone(FAR struct nsh_vtbl_s *vtbl); static void nsh_consolerelease(FAR struct nsh_vtbl_s *vtbl); #endif +static ssize_t nsh_consolewrite(FAR struct nsh_vtbl_s *vtbl, FAR const void *buffer, size_t nbytes); static int nsh_consoleoutput(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...); static FAR char *nsh_consolelinebuffer(FAR struct nsh_vtbl_s *vtbl); static void nsh_consoleredirect(FAR struct nsh_vtbl_s *vtbl, int fd, FAR uint8_t *save); @@ -109,6 +112,7 @@ static inline FAR struct serial_s *nsh_allocstruct(void) pstate->ss_vtbl.clone = nsh_consoleclone; pstate->ss_vtbl.release = nsh_consolerelease; #endif + pstate->ss_vtbl.write = nsh_consolewrite; pstate->ss_vtbl.output = nsh_consoleoutput; pstate->ss_vtbl.linebuffer = nsh_consolelinebuffer; pstate->ss_vtbl.redirect = nsh_consoleredirect; @@ -171,6 +175,41 @@ static void nsh_closeifnotclosed(struct serial_s *pstate) } /**************************************************************************** + * Name: nsh_consolewrite + * + * Description: + * write a buffer to the remote shell window. + * + * Currently only used by cat. + * + ****************************************************************************/ + +static ssize_t nsh_consolewrite(FAR struct nsh_vtbl_s *vtbl, FAR const void *buffer, size_t nbytes) +{ + FAR struct serial_s *pstate = (FAR struct serial_s *)vtbl; + ssize_t ret; + + /* The stream is open in a lazy fashion. This is done because the file + * descriptor may be opened on a different task than the stream. The + * actual open will then occur with the first output from the new task. + */ + + if (nsh_openifnotopen(pstate) != 0) + { + return (ssize_t)ERROR; + } + + /* Write the data to the output stream */ + + ret = fwrite(buffer, 1, nbytes, pstate->ss_stream); + if (ret < 0) + { + dbg("[%d] Failed to send buffer: %d\n", pstate->ss_fd, errno); + } + return ret; +} + +/**************************************************************************** * Name: nsh_consoleoutput * * Description: @@ -265,7 +304,29 @@ static void nsh_consolerelease(FAR struct nsh_vtbl_s *vtbl) * Name: nsh_consoleredirect * * Description: - * Set up for redirected output + * Set up for redirected output. This function is called from nsh_parse() + * in two different contexts: + * + * 1) Redirected background commands of the form: command > xyz.text & + * + * In this case: + * - vtbl: A newly allocated and initialized instance created by + * nsh_consoleclone, + * - fd:- The file descriptor of the redirected output + * - save: NULL + * + * nsh_consolerelease() will perform the clean-up when the clone is + * destroyed. + * + * 2) Redirected foreground commands of the form: command > xyz.txt + * + * In this case: + * - vtbl: The current state structure, + * - fd: The file descriptor of the redirected output + * - save: Where to save the re-directed registers. + * + * nsh_consoleundirect() will perform the clean-up after the redirected + * command completes. * ****************************************************************************/ @@ -274,18 +335,39 @@ static void nsh_consoleredirect(FAR struct nsh_vtbl_s *vtbl, int fd, FAR uint8_t FAR struct serial_s *pstate = (FAR struct serial_s *)vtbl; FAR struct serialsave_s *ssave = (FAR struct serialsave_s *)save; - (void)nsh_openifnotopen(pstate); - fflush(pstate->ss_stream); + /* Case 1: Redirected foreground commands */ + if (ssave) { + /* pstate->ss_stream and ss_fd refer refer to the + * currently opened output stream. If the console is open, flush + * any pending output. + */ + + if (pstate->ss_stream) + { + fflush(pstate->ss_stream); + } + + /* Save the current fd and stream values. These will be restored + * when nsh_consoleundirect() is called. + */ + ssave->ss_fd = pstate->ss_fd; ssave->ss_stream = pstate->ss_stream; } else { - fclose(pstate->ss_stream); + /* nsh_consoleclone() set pstate->ss_fd and ss_stream to refer + * to standard out. We just want to leave these alone and overwrite + * them with the fd for the re-directed stream. + */ } + /* In either case, set the fd of the new, re-directed output and nullify + * the output stream (it will be fdopen'ed if it is used). + */ + pstate->ss_fd = fd; pstate->ss_stream = NULL; } diff --git a/nuttx/examples/nsh/nsh_telnetd.c b/nuttx/examples/nsh/nsh_telnetd.c index 42eb5a9e9..9776124f6 100644 --- a/nuttx/examples/nsh/nsh_telnetd.c +++ b/nuttx/examples/nsh/nsh_telnetd.c @@ -1,7 +1,7 @@ /**************************************************************************** * examples/nsh/nsh_telnetd.c * - * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * This is a leverage of similar logic from uIP: @@ -147,6 +147,7 @@ static void tio_semtake(struct telnetio_s *tio); static FAR struct nsh_vtbl_s *nsh_telnetclone(FAR struct nsh_vtbl_s *vtbl); #endif static void nsh_telnetrelease(FAR struct nsh_vtbl_s *vtbl); +static ssize_t nsh_telnetwrite(FAR struct nsh_vtbl_s *vtbl, FAR const void *buffer, size_t nbytes); static int nsh_telnetoutput(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...); static int nsh_redirectoutput(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...); static FAR char *nsh_telnetlinebuffer(FAR struct nsh_vtbl_s *vtbl); @@ -195,6 +196,7 @@ static FAR struct telnetd_s *nsh_allocstruct(void) pstate->tn_vtbl.clone = nsh_telnetclone; pstate->tn_vtbl.release = nsh_telnetrelease; #endif + pstate->tn_vtbl.write = nsh_telnetwrite; pstate->tn_vtbl.output = nsh_telnetoutput; pstate->tn_vtbl.linebuffer = nsh_telnetlinebuffer; pstate->tn_vtbl.redirect = nsh_telnetredirect; @@ -538,6 +540,41 @@ static void *nsh_connection(void *arg) } /**************************************************************************** + * Name: nsh_telnetwrite + * + * Description: + * write a buffer to the remote shell window. + * + * Currently only used by cat. + * + ****************************************************************************/ + +static ssize_t nsh_telnetwrite(FAR struct nsh_vtbl_s *vtbl, FAR const void *buffer, size_t nbytes) +{ + struct telnetd_s *pstate = (struct telnetd_s *)vtbl; + struct telnetio_s *tio = pstate->u.tn; + ssize_t ret = nbytes; + + /* Flush anything already in the output buffer */ + + nsh_flush(pstate); + + /* Then write the user buffer */ + + nsh_telnetdump(&pstate->tn_vtbl, "Buffer output",(uint8_t*)buffer, nbytes); + + tio_semtake(tio); /* Only one call to send at a time */ + ret = send(tio->tio_sockfd, buffer, nbytes, 0); + if (ret < 0) + { + dbg("[%d] Failed to send buffer: %d\n", tio->tio_sockfd, errno); + } + + tio_semgive(tio); + return ret; +} + +/**************************************************************************** * Name: nsh_telnetoutput * * Description: @@ -704,7 +741,29 @@ static void nsh_telnetrelease(FAR struct nsh_vtbl_s *vtbl) * Name: nsh_telnetredirect * * Description: - * Set up for redirected output + * Set up for redirected output. This function is called from nsh_parse() + * in two different contexts: + * + * 1) Redirected background commands of the form: command > xyz.text & + * + * In this case: + * - vtbl: A newly allocated and initialized instance created by + * nsh_telnetclone, + * - fd:- The file descriptor of the redirected output + * - save: NULL + * + * nsh_telnetrelease() will perform the clean-up when the clone is + * destroyed. + * + * 2) Redirected foreground commands of the form: command > xyz.txt + * + * In this case: + * - vtbl: The current state structure, + * - fd: The file descriptor of the redirected output + * - save: Where to save the re-directed registers. + * + * nsh_telnetundirect() will perform the clean-up after the redirected + * command completes. * ****************************************************************************/ |