diff --git a/nshlib/nsh.h b/nshlib/nsh.h index 96481a085..adb8d3aed 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -611,7 +611,9 @@ # define CONFIG_NSH_DISABLE_MKRD 1 #endif -/* Certain commands are only available if the procfs file system is enable */ +/* Certain commands/features are only available if the procfs file system is + * enabled. + */ #if !defined(CONFIG_FS_PROCFS) || defined(CONFIG_FS_PROCFS_EXCLUDE_NET) # undef CONFIG_NSH_DISABLE_IFCONFIG /* 'ifconfig' depends on network procfs */ @@ -621,6 +623,35 @@ # define CONFIG_NSH_DISABLE_IFUPDOWN 1 #endif +#define NSH_HAVE_CPULOAD 1 +#if !defined(CONFIG_FS_PROCFS) || !defined(CONFIG_FS_PROCFS_EXCLUDE_CPULOAD) || \ + !defined(CONFIG_SCHED_CPULOAD) || defined(CONFIG_NSH_DISABLE_PS) +# undef NSH_HAVE_CPULOAD +#endif + +/* Suppress unused file utilities */ + +#define NSH_HAVE_CATFILE 1 +#define NSH_HAVE_READFILE 1 + +#if CONFIG_NFILE_DESCRIPTORS <= 0 +# undef NSH_HAVE_CATFILE +# undef NSH_HAVE_READFILE +#endif + +/* nsh_catfile used by cat, ifconfig, ifup/down */ + +#if defined(CONFIG_NSH_DISABLE_CAT) && defined(CONFIG_NSH_DISABLE_IFCONFIG) && \ + defined(CONFIG_NSH_DISABLE_IFUPDOWN) +# undef NSH_HAVE_CATFILE +#endif + +/* nsh_readfile use by ps command (for load information) */ + +#if !defined(NSH_HAVE_CPULOAD) +# undef NSH_HAVE_READFILE +#endif + /**************************************************************************** * Public Types ****************************************************************************/ @@ -1136,9 +1167,34 @@ FAR const char *nsh_extmatch_getname(int index); * ****************************************************************************/ -#if CONFIG_NFILE_DESCRIPTORS > 0 +#ifdef NSH_HAVE_CATFILE int nsh_catfile(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, FAR const char *filepath); #endif +/**************************************************************************** + * Name: nsh_readfile + * + * Description: + * Read a small file into a buffer buffer. An error occurs if the file + * will not fit into the buffer. + * + * Input Paramters: + * vtbl - The console vtable + * filepath - The full path to the file to be read + * buffer - The user-provided buffer into which the file is read. + * buflen - The size of the user provided buffer + * + * Returned Value: + * Zero (OK) is returned on success; -1 (ERROR) is returned on any + * failure to read the fil into the buffer. + * + ****************************************************************************/ + +#ifdef NSH_HAVE_READFILE +static int nsh_readfile(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, + FAR const char *filepath, FAR char *buffer, + size_t buflen); +#endif + #endif /* __APPS_NSHLIB_NSH_H */ diff --git a/nshlib/nsh_fsutils.c b/nshlib/nsh_fsutils.c index 6219ec19f..17468ec7f 100644 --- a/nshlib/nsh_fsutils.c +++ b/nshlib/nsh_fsutils.c @@ -68,7 +68,7 @@ * ****************************************************************************/ -#if CONFIG_NFILE_DESCRIPTORS > 0 +#ifdef NSH_HAVE_CATFILE int nsh_catfile(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, FAR const char *filepath) { @@ -183,3 +183,106 @@ int nsh_catfile(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, } #endif +/**************************************************************************** + * Name: nsh_readfile + * + * Description: + * Read a small file into a buffer buffer. An error occurs if the file + * will not fit into the buffer. + * + * Input Paramters: + * vtbl - The console vtable + * filepath - The full path to the file to be read + * buffer - The user-provided buffer into which the file is read. + * buflen - The size of the user provided buffer + * + * Returned Value: + * Zero (OK) is returned on success; -1 (ERROR) is returned on any + * failure to read the fil into the buffer. + * + ****************************************************************************/ + +#ifdef NSH_HAVE_READFILE +static int nsh_readfile(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, + FAR const char *filepath, FAR char *buffer, + size_t buflen) +{ + FAR char *bufptr; + size_t remaining; + ssize_t nread; + ssize_t ntotal; + int fd; + int ret; + + /* Open the file */ + + fd = open(filepath, O_RDONLY); + if (fd < 0) + { + nsh_output(vtbl, g_fmtcmdfailed, cmd, "open", NSH_ERRNO); + return ERROR; + } + + /* Read until we hit the end of the file, until we have exhausted the + * buffer space, or until some irrecoverable error occurs + */ + + ntotal = 0; /* No bytes read yet */ + *buffer = '\0'; /* NUL terminate the empty buffer */ + bufptr = buffer; /* Working pointer */ + remaining = buflen - 1; /* Reserve one byte for a NUL terminator */ + ret = ERROR; /* Assume failure */ + + do + { + nread = read(fd, bufptr, remaining); + if (nread < 0) + { + /* Read error */ + + int errcode = errno; + DEBUGASSERT(errcode > 0); + + /* EINTR is not a read error. It simply means that a signal was + * received while waiting for the read to complete. + */ + + if (errcode != EINTR) + { + /* Fatal error */ + + nsh_output(vtbl, g_fmtcmdfailed, cmd, "read", NSH_ERRNO); + break; + } + } + else if (nread == 0) + { + /* End of file */ + + ret = OK; + break; + } + else + { + /* Successful read. Make sure that the buffer is null terminated */ + + DEBUGASSERT(nread <= remaining); + ntotal += nread; + buffer[ntotal] = '\0'; + + /* Bump up the read count and continuing reading to the end of + * file. + */ + + bufptr += nread; + remaining -= nread; + } + } + while (buflen > 0); + + /* Close the file and return. */ + + close(fd); + return ret; +} +#endif diff --git a/nshlib/nsh_netcmds.c b/nshlib/nsh_netcmds.c index 45114dfa7..2580165c7 100644 --- a/nshlib/nsh_netcmds.c +++ b/nshlib/nsh_netcmds.c @@ -283,7 +283,7 @@ errout: !defined(CONFIG_NSH_DISABLE_IFCONFIG) static inline void net_statistics(FAR struct nsh_vtbl_s *vtbl) { - (void)nsh_catfile(vtbl, "ifconfig", "/proc/net/stat"); + (void)nsh_catfile(vtbl, "ifconfig", CONFIG_NSH_PROC_MOUNTPOINT "/net/stat"); } #else # define net_statistics(vtbl) @@ -302,7 +302,7 @@ static int ifconfig_callback(FAR struct nsh_vtbl_s *vtbl, FAR char *devname) /* Construct the full path to the /proc/net entry for this device */ - snprintf(buffer, IFNAMSIZ + 12, "/proc/net/%s", devname); + snprintf(buffer, IFNAMSIZ + 12, CONFIG_NSH_PROC_MOUNTPOINT "/net/%s", devname); (void)nsh_catfile(vtbl, "ifconfig", buffer); return OK; @@ -591,7 +591,7 @@ static int nsh_foreach_netdev(nsh_netdev_callback_t callback, /* Open the /proc/net directory */ - dir = opendir("/proc/net"); + dir = opendir(CONFIG_NSH_PROC_MOUNTPOINT "/net"); if (dir == NULL) { nsh_output(vtbl, g_fmtcmdfailed, cmd, "opendir", NSH_ERRNO); diff --git a/nshlib/nsh_proccmds.c b/nshlib/nsh_proccmds.c index 2f5f5a2b5..ce4883f45 100644 --- a/nshlib/nsh_proccmds.c +++ b/nshlib/nsh_proccmds.c @@ -57,12 +57,6 @@ # define CONFIG_NSH_PROC_MOUNTPOINT "/proc" #endif -#undef HAVE_CPULOAD -#if defined(CONFIG_SCHED_CPULOAD) && defined(CONFIG_FS_PROCFS) && \ - !defined(CONFIG_FS_PROCFS_EXCLUDE_CPULOAD) -# define HAVE_CPULOAD 1 -#endif - /**************************************************************************** * Private Types ****************************************************************************/ @@ -73,10 +67,6 @@ typedef int (*exec_t)(void); -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Private Data ****************************************************************************/ @@ -116,108 +106,17 @@ static FAR const char *g_policynames[4] = }; #endif -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: readfile - ****************************************************************************/ - -#ifdef HAVE_CPULOAD -static int readfile(FAR const char *filename, FAR char *buffer, size_t buflen) -{ - FAR char *bufptr; - size_t remaining; - ssize_t nread; - ssize_t ntotal; - int fd; - int ret; - - /* Open the file */ - - fd = open(filename, O_RDONLY); - if (fd < 0) - { - int errcode = errno; - DEBUGASSERT(errcode > 0); - return -errcode; - } - - /* Read until we hit the end of the file, until we have exhausted the - * buffer space, or until some irrecoverable error occurs - */ - - ntotal = 0; /* No bytes read yet */ - *buffer = '\0'; /* NUL terminate the empty buffer */ - bufptr = buffer; /* Working pointer */ - remaining = buflen - 1; /* Reserve one byte for a NUL terminator */ - ret = -E2BIG; /* Assume result will not fit in the buffer */ - - do - { - nread = read(fd, bufptr, remaining); - if (nread < 0) - { - /* Read error */ - - int errcode = errno; - DEBUGASSERT(errcode > 0); - - /* EINTR is not a read error. It simply means that a signal was - * received while waiting for the read to complete. - */ - - if (errcode != EINTR) - { - /* Fatal error */ - - ret = -errcode; - break; - } - } - else if (nread == 0) - { - /* End of file */ - - ret = OK; - break; - } - else - { - /* Successful read. Make sure that the buffer is null terminated */ - - DEBUGASSERT(nread <= remaining); - ntotal += nread; - buffer[ntotal] = '\0'; - - /* Bump up the read count and continuing reading to the end of - * file. - */ - - bufptr += nread; - remaining -= nread; - } - } - while (buflen > 0); - - /* Close the file and return. */ - - close(fd); - return ret; -} -#endif - /**************************************************************************** * Name: loadavg ****************************************************************************/ -#ifdef HAVE_CPULOAD -static int loadavg(pid_t pid, FAR char *buffer, size_t buflen) +#ifdef NSH_HAVE_CPULOAD +static int loadavg(FAR struct nsh_vtbl_s *vtbl, , FAR const char *cmd, + pid_t pid, FAR char *buffer, size_t buflen) { char path[24]; @@ -228,7 +127,7 @@ static int loadavg(pid_t pid, FAR char *buffer, size_t buflen) /* Read the 'loadavg' pseudo-file into the user buffer */ - return readfile(path, buffer, buflen); + return nsh_readfile(vtbl, cmd, path, buffer, buflen); } #endif @@ -241,7 +140,7 @@ static void ps_task(FAR struct tcb_s *tcb, FAR void *arg) { FAR struct nsh_vtbl_s *vtbl = (FAR struct nsh_vtbl_s*)arg; FAR const char *policy; -#ifdef HAVE_CPULOAD +#ifdef NSH_HAVE_CPULOAD char buffer[8]; int ret; #endif @@ -257,10 +156,10 @@ static void ps_task(FAR struct tcb_s *tcb, FAR void *arg) tcb->flags & TCB_FLAG_CANCEL_PENDING ? 'P' : ' ', g_statenames[tcb->task_state]); -#ifdef HAVE_CPULOAD +#ifdef NSH_HAVE_CPULOAD /* Get the CPU load */ - ret = loadavg(tcb->pid, buffer, sizeof(buffer)); + ret = loadavg(vtbl, "ps", tcb->pid, buffer, sizeof(buffer)); if (ret < 0) { /* Make the buffer into an empty string */ @@ -344,7 +243,7 @@ int cmd_exec(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) #ifndef CONFIG_NSH_DISABLE_PS int cmd_ps(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) { -#ifdef HAVE_CPULOAD +#ifdef NSH_HAVE_CPULOAD nsh_output(vtbl, "PID PRI SCHD TYPE NP STATE CPU NAME\n"); #else nsh_output(vtbl, "PID PRI SCHD TYPE NP STATE NAME\n");