in nshlib/nsh_proccmds.c [248:584]
static int ps_callback(FAR struct nsh_vtbl_s *vtbl, FAR const char *dirpath,
FAR struct dirent *entryp, FAR void *pvarg)
{
UNUSED(pvarg);
struct nsh_taskstatus_s status;
FAR char *filepath;
FAR char *line;
FAR char *nextline;
int ret;
int i;
#if CONFIG_MM_BACKTRACE >= 0 && !defined(CONFIG_NSH_DISABLE_PSHEAPUSAGE)
unsigned long heap_size = 0;
#endif
#if !defined(CONFIG_NSH_DISABLE_PSSTACKUSAGE)
unsigned long stack_size = 0;
#ifdef CONFIG_STACK_COLORATION
unsigned long stack_used = 0;
unsigned long stack_filled = 0;
#endif
#endif
/* Task/thread entries in the /proc directory will all be (1) directories
* with (2) all numeric names.
*/
if (!DIRENT_ISDIRECTORY(entryp->d_type))
{
/* Not a directory... skip this entry */
return OK;
}
/* Check each character in the name */
for (i = 0; i < NAME_MAX && entryp->d_name[i] != '\0'; i++)
{
if (!isdigit(entryp->d_name[i]))
{
/* Name contains something other than a numeric character */
return OK;
}
}
/* Set all pointers to the empty string. */
status.td_type = "";
status.td_groupid = "";
#ifdef CONFIG_SMP
status.td_cpu = "";
#endif
status.td_state = "";
status.td_event = "";
status.td_flags = "";
status.td_priority = "";
status.td_policy = "";
status.td_sigmask = "";
/* Read the task status */
filepath = NULL;
ret = asprintf(&filepath, "%s/%s/status", dirpath, entryp->d_name);
if (ret < 0 || filepath == NULL)
{
nsh_error(vtbl, g_fmtcmdfailed, "ps", "asprintf", NSH_ERRNO);
}
else
{
ret = nsh_readfile(vtbl, "ps", filepath, vtbl->iobuffer, IOBUFFERSIZE);
free(filepath);
if (ret >= 0)
{
/* Parse the task status. */
nextline = vtbl->iobuffer;
do
{
/* Find the beginning of the next line and NUL-terminate the
* current line.
*/
line = nextline;
for (nextline++;
*nextline != '\n' && *nextline != '\0';
nextline++);
if (*nextline == '\n')
{
*nextline++ = '\0';
}
else
{
nextline = NULL;
}
/* Parse the current line */
nsh_parse_statusline(line, &status);
}
while (nextline != NULL);
}
}
/* Finally, print the status information */
nsh_output(vtbl,
"%5s %5s "
#ifdef CONFIG_SMP
"%3s "
#endif
"%3s %-8s %-7s %3s %-8s %-9s %-8s ",
entryp->d_name, status.td_groupid,
#ifdef CONFIG_SMP
status.td_cpu,
#endif
status.td_priority, status.td_policy, status.td_type,
status.td_flags, status.td_state, status.td_event,
status.td_sigmask);
#if CONFIG_MM_BACKTRACE >= 0 && !defined(CONFIG_NSH_DISABLE_PSHEAPUSAGE)
/* Get the Heap AllocSize */
filepath = NULL;
ret = asprintf(&filepath, "%s/%s/heap", dirpath, entryp->d_name);
if (ret < 0 || filepath == NULL)
{
nsh_error(vtbl, g_fmtcmdfailed, "ps", "asprintf", NSH_ERRNO);
vtbl->iobuffer[0] = '\0';
}
else
{
ret = nsh_readfile(vtbl, "ps", filepath, vtbl->iobuffer,
IOBUFFERSIZE);
free(filepath);
if (ret >= 0)
{
nextline = vtbl->iobuffer;
do
{
/* Find the beginning of the next line and NUL-terminate the
* current line.
*/
line = nextline;
for (nextline++;
*nextline != '\n' && *nextline != '\0';
nextline++);
if (*nextline == '\n')
{
*nextline++ = '\0';
}
else
{
nextline = NULL;
}
/* Parse the current line
*
* Format:
*
* 111111111122222222223
* 123456789012345678901234567890
* AllocSize: xxxx
* AllocBlks: xxxx
*/
if (strncmp(line, g_heapsize, strlen(g_heapsize)) == 0)
{
heap_size = strtoul(&line[12], NULL, 0);
break;
}
}
while (nextline != NULL);
}
}
#endif
#if !defined(CONFIG_NSH_DISABLE_PSSTACKUSAGE)
/* Get the StackSize and StackUsed */
filepath = NULL;
ret = asprintf(&filepath, "%s/%s/stack", dirpath, entryp->d_name);
if (ret < 0 || filepath == NULL)
{
nsh_error(vtbl, g_fmtcmdfailed, "ps", "asprintf", NSH_ERRNO);
vtbl->iobuffer[0] = '\0';
}
else
{
ret = nsh_readfile(vtbl, "ps", filepath, vtbl->iobuffer,
IOBUFFERSIZE);
free(filepath);
if (ret >= 0)
{
nextline = vtbl->iobuffer;
do
{
/* Find the beginning of the next line and NUL-terminate the
* current line.
*/
line = nextline;
for (nextline++;
*nextline != '\n' && *nextline != '\0';
nextline++);
if (*nextline == '\n')
{
*nextline++ = '\0';
}
else
{
nextline = NULL;
}
/* Parse the current line
*
* Format:
*
* 111111111122222222223
* 123456789012345678901234567890
* StackBase: xxxxxxxxxx
* StackSize: xxxx
* StackUsed: xxxx
*/
if (strncmp(line, g_stacksize, strlen(g_stacksize)) == 0)
{
stack_size = strtoul(&line[12], NULL, 0);
}
#ifdef CONFIG_STACK_COLORATION
else if (strncmp(line, g_stackused, strlen(g_stackused)) == 0)
{
stack_used = strtoul(&line[12], NULL, 0);
}
#endif
}
while (nextline != NULL);
}
}
#ifdef CONFIG_STACK_COLORATION
if (stack_size > 0 && stack_used > 0)
{
/* Use fixed-point math with one decimal place */
stack_filled = 10 * 100 * stack_used / stack_size;
}
#endif
#endif
#ifdef NSH_HAVE_CPULOAD
/* Get the CPU load */
filepath = NULL;
ret = asprintf(&filepath, "%s/%s/loadavg", dirpath, entryp->d_name);
if (ret < 0 || filepath == NULL)
{
nsh_error(vtbl, g_fmtcmdfailed, "ps", "asprintf", NSH_ERRNO);
vtbl->iobuffer[0] = '\0';
}
else
{
ret = nsh_readfile(vtbl, "ps", filepath, vtbl->iobuffer, IOBUFFERSIZE);
free(filepath);
if (ret < 0)
{
vtbl->iobuffer[0] = '\0';
}
}
#endif
#if defined(PS_SHOW_HEAPSIZE) || defined (PS_SHOW_STACKSIZE) || \
defined (PS_SHOW_STACKUSAGE) || defined (NSH_HAVE_CPULOAD)
nsh_output(vtbl,
#ifdef PS_SHOW_HEAPSIZE
"%08lu "
#endif
#ifdef PS_SHOW_STACKSIZE
"%06lu "
#endif
#ifdef PS_SHOW_STACKUSAGE
"%06lu "
"%3lu.%lu%%%c "
#endif
#ifdef NSH_HAVE_CPULOAD
"%6s "
#endif
#if CONFIG_MM_BACKTRACE >= 0 && !defined(CONFIG_NSH_DISABLE_PSHEAPUSAGE)
, heap_size
#endif
#if !defined(CONFIG_NSH_DISABLE_PSSTACKUSAGE)
, stack_size
#endif
#ifdef PS_SHOW_STACKUSAGE
, stack_used,
stack_filled / 10,
stack_filled % 10,
(stack_filled >= 10 * 80 ? '!' : ' ')
#endif
#ifdef NSH_HAVE_CPULOAD
, nsh_trimspaces(vtbl->iobuffer)
#endif
);
#endif
/* Read the task/thread command line */
filepath = NULL;
ret = asprintf(&filepath, "%s/%s/cmdline", dirpath, entryp->d_name);
if (ret < 0 || filepath == NULL)
{
nsh_error(vtbl, g_fmtcmdfailed, "ps", "asprintf", NSH_ERRNO);
return ERROR;
}
ret = nsh_readfile(vtbl, "ps", filepath, vtbl->iobuffer, IOBUFFERSIZE);
free(filepath);
if (ret < 0)
{
return ERROR;
}
nsh_output(vtbl, "%s\n", nsh_trimspaces(vtbl->iobuffer));
return OK;
}