summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nuttx/drivers/mtd/mtd_partition.c182
-rw-r--r--nuttx/drivers/mtd/mtd_procfs.c44
-rw-r--r--nuttx/fs/procfs/fs_procfs.c12
-rw-r--r--nuttx/fs/procfs/fs_procfsproc.c32
-rw-r--r--nuttx/include/nuttx/fs/procfs.h22
5 files changed, 170 insertions, 122 deletions
diff --git a/nuttx/drivers/mtd/mtd_partition.c b/nuttx/drivers/mtd/mtd_partition.c
index 9fca44011..22041361c 100644
--- a/nuttx/drivers/mtd/mtd_partition.c
+++ b/nuttx/drivers/mtd/mtd_partition.c
@@ -540,10 +540,12 @@ static ssize_t part_procfs_read(FAR struct file *filep, FAR char *buffer,
size_t buflen)
{
FAR struct part_procfs_file_s *attr;
- ssize_t ret, total = 0, blkpererase;
FAR struct mtd_geometry_s geo;
+ ssize_t total = 0;
+ ssize_t blkpererase;
+ ssize_t ret;
#ifdef CONFIG_MTD_PARTITION_NAMES
- char partname[11];
+ char partname[11];
FAR const char *ptr;
uint8_t x;
#endif
@@ -555,113 +557,127 @@ static ssize_t part_procfs_read(FAR struct file *filep, FAR char *buffer,
attr = (FAR struct part_procfs_file_s *)filep->f_priv;
DEBUGASSERT(attr);
- /* Provide the requested data */
+ /* If we are at the end of the list, then return 0 signifying the
+ * end-of-file. This also handles the special case when there are
+ * no registered MTD partitions.
+ */
- if (attr->nextpart == g_pfirstpartition)
+ if (attr->nextpart)
{
+ /* Output a header before the first entry */
+
+ if (attr->nextpart == g_pfirstpartition)
+ {
#ifdef CONFIG_MTD_PARTITION_NAMES
- total = snprintf(buffer, buflen, "Name Start Size");
+ total = snprintf(buffer, buflen, "Name Start Size");
#else
- total = snprintf(buffer, buflen, " Start Size");
+ total = snprintf(buffer, buflen, " Start Size");
#endif
#ifndef CONFIG_FS_PROCFS_EXCLUDE_MTD
- total += snprintf(&buffer[total], buflen - total, " MTD\n");
+ total += snprintf(&buffer[total], buflen - total, " MTD\n");
#else
- total += snprintf(&buffer[total], buflen - total, "\n");
+ total += snprintf(&buffer[total], buflen - total, "\n");
#endif
- }
+ }
- while (attr->nextpart)
- {
- /* Get the geometry of the FLASH device */
+ /* Provide the requested data */
- ret = attr->nextpart->parent->ioctl(attr->nextpart->parent, MTDIOC_GEOMETRY,
- (unsigned long)((uintptr_t)&geo));
- if (ret < 0)
- {
- fdbg("ERROR: mtd->ioctl failed: %d\n", ret);
- return 0;
- }
+ do
+ {
+ /* Get the geometry of the FLASH device */
+
+ ret = attr->nextpart->parent->ioctl(attr->nextpart->parent,
+ MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&geo));
+ if (ret < 0)
+ {
+ fdbg("ERROR: mtd->ioctl failed: %d\n", ret);
+ return 0;
+ }
- /* Get the number of blocks per erase. There must be an even number of
- * blocks in one erase blocks.
- */
+ /* Get the number of blocks per erase. There must be an even number
+ * of blocks in one erase blocks.
+ */
- blkpererase = geo.erasesize / geo.blocksize;
+ blkpererase = geo.erasesize / geo.blocksize;
- /* Copy data from the next known partition */
+ /* Copy data from the next known partition */
#ifdef CONFIG_MTD_PARTITION_NAMES
- if (attr->nextpart->name == NULL)
- {
- strcpy(partname, "(noname) ");
- }
- else
- {
- ptr = attr->nextpart->name;
- for (x = 0; x < sizeof(partname) - 1; x++)
- {
- /* Test for end of partition name */
-
- if (*ptr == ',' || *ptr == '\0')
- {
- /* Perform space fill for alignment */
-
- partname[x] = ' ';
- }
- else
- {
- /* Copy next byte of partition name */
-
- partname[x] = *ptr++;
- }
- }
+ if (attr->nextpart->name == NULL)
+ {
+ strcpy(partname, "(noname) ");
+ }
+ else
+ {
+ ptr = attr->nextpart->name;
+ for (x = 0; x < sizeof(partname) - 1; x++)
+ {
+ /* Test for end of partition name */
+
+ if (*ptr == ',' || *ptr == '\0')
+ {
+ /* Perform space fill for alignment */
+
+ partname[x] = ' ';
+ }
+ else
+ {
+ /* Copy next byte of partition name */
+
+ partname[x] = *ptr++;
+ }
+ }
- partname[x] = '\0';
- }
+ partname[x] = '\0';
+ }
- /* Terminate the partition name and add to output buffer */
+ /* Terminate the partition name and add to output buffer */
- ret = snprintf(&buffer[total], buflen - total, "%s%7d %7d",
- partname, attr->nextpart->firstblock / blkpererase,
- attr->nextpart->neraseblocks);
+ ret = snprintf(&buffer[total], buflen - total, "%s%7d %7d",
+ partname, attr->nextpart->firstblock / blkpererase,
+ attr->nextpart->neraseblocks);
#else
- ret = snprintf(&buffer[total], buflen - total, "%7d %7d",
- attr->nextpart->firstblock / blkpererase,
- attr->nextpart->neraseblocks);
+ ret = snprintf(&buffer[total], buflen - total, "%7d %7d",
+ attr->nextpart->firstblock / blkpererase,
+ attr->nextpart->neraseblocks);
#endif
#ifndef CONFIG_FS_PROCFS_EXCLUDE_MTD
- if (ret + total < buflen)
- {
- ret += snprintf(&buffer[total + ret], buflen - (total + ret),
- " %s\n", attr->nextpart->parent->name);
- }
+ if (ret + total < buflen)
+ {
+ ret += snprintf(&buffer[total + ret], buflen - (total + ret),
+ " %s\n", attr->nextpart->parent->name);
+ }
#else
- if (ret + total < buflen)
- {
- ret += snprintf(&buffer[total + ret], buflen - (total + ret), "\n");
- }
+ if (ret + total < buflen)
+ {
+ ret += snprintf(&buffer[total + ret], buflen - (total + ret),
+ "\n");
+ }
#endif
- if (ret + total < buflen)
- {
- /* It fit in the buffer totally. Advance total and move to
- * next partition.
- */
- total += ret;
- attr->nextpart = attr->nextpart->pnext;
- }
- else
- {
- /* This one didn't fit completely. Truncate the partial
- * entry and break the loop.
- */
- buffer[total] = '\0';
- break;
- }
- }
+ if (ret + total < buflen)
+ {
+ /* It fit in the buffer totally. Advance total and move to
+ * next partition.
+ */
+
+ total += ret;
+ attr->nextpart = attr->nextpart->pnext;
+ }
+ else
+ {
+ /* This one didn't fit completely. Truncate the partial
+ * entry and break the loop.
+ */
+
+ buffer[total] = '\0';
+ break;
+ }
+ }
+ while (attr->nextpart);
+ }
/* Update the file offset */
diff --git a/nuttx/drivers/mtd/mtd_procfs.c b/nuttx/drivers/mtd/mtd_procfs.c
index 2a2ba32a2..e1596003e 100644
--- a/nuttx/drivers/mtd/mtd_procfs.c
+++ b/nuttx/drivers/mtd/mtd_procfs.c
@@ -199,7 +199,8 @@ static ssize_t mtd_read(FAR struct file *filep, FAR char *buffer,
size_t buflen)
{
FAR struct mtd_file_s *priv;
- ssize_t total = 0, ret;
+ ssize_t total = 0;
+ ssize_t ret;
fvdbg("buffer=%p buflen=%d\n", buffer, (int)buflen);
@@ -208,28 +209,39 @@ static ssize_t mtd_read(FAR struct file *filep, FAR char *buffer,
priv = (FAR struct mtd_file_s *)filep->f_priv;
DEBUGASSERT(priv);
- /* Provide the requested data */
-
- if (priv->pnextmtd == g_pfirstmtd)
- {
- total = snprintf(buffer, buflen, "Num Device\n");
- }
+ /* If we are at the end of the list, then return 0 signifying the
+ * end-of-file. This also handles the special case when there are
+ * no registered MTD devices.
+ */
- while (priv->pnextmtd)
+ if (priv->pnextmtd)
{
- ret = snprintf(&buffer[total], buflen - total, "%-5d%s\n",
- priv->pnextmtd->mtdno, priv->pnextmtd->name);
+ /* Output a header before the first entry */
- if (ret + total < buflen)
+ if (priv->pnextmtd == g_pfirstmtd)
{
- total += ret;
- priv->pnextmtd = priv->pnextmtd->pnext;
+ total = snprintf(buffer, buflen, "Num Device\n");
}
- else
+
+ /* The provide the requested data */
+
+ do
{
- buffer[total] = '\0';
- break;
+ ret = snprintf(&buffer[total], buflen - total, "%-5d%s\n",
+ priv->pnextmtd->mtdno, priv->pnextmtd->name);
+
+ if (ret + total < buflen)
+ {
+ total += ret;
+ priv->pnextmtd = priv->pnextmtd->pnext;
+ }
+ else
+ {
+ buffer[total] = '\0';
+ break;
+ }
}
+ while (priv->pnextmtd);
}
/* Update the file offset */
diff --git a/nuttx/fs/procfs/fs_procfs.c b/nuttx/fs/procfs/fs_procfs.c
index 2bd091bb6..a44d00f93 100644
--- a/nuttx/fs/procfs/fs_procfs.c
+++ b/nuttx/fs/procfs/fs_procfs.c
@@ -384,6 +384,7 @@ static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
FAR struct fs_dirent_s *dir)
{
FAR struct procfs_level0_s *level0;
+ FAR struct procfs_dir_priv_s *dirpriv;
FAR void *priv = NULL;
irqstate_t flags;
@@ -448,7 +449,10 @@ static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
if (match(g_procfsentries[x].pathpattern, relpath))
{
- /* Match found! Call the handler's opendir routine */
+ /* Match found! Call the handler's opendir routine. If successful,
+ * this opendir routine will create an entry derived from struct
+ * procfs_dir_priv_s as dir->u.procfs.
+ */
DEBUGASSERT(g_procfsentries[x].ops && g_procfsentries[x].ops->opendir);
ret = g_procfsentries[x].ops->opendir(relpath, dir);
@@ -459,8 +463,8 @@ static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
/* Set the procfs_entry handler */
- level0 = (FAR struct procfs_level0_s *) dir->u.procfs;
- level0->procfsentry = &g_procfsentries[x];
+ dirpriv = (FAR struct procfs_dir_priv_s *)dir->u.procfs;
+ dirpriv->procfsentry = &g_procfsentries[x];
}
return ret;
@@ -684,7 +688,7 @@ static int procfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
#endif /* CONFIG_FS_PROCFS_EXCLUDE_PROCESS */
}
- /* Are we reading in intermediate subdirectory? */
+ /* Are we reading an intermediate subdirectory? */
else if (priv->level == 1 && priv->procfsentry == NULL)
{
diff --git a/nuttx/fs/procfs/fs_procfsproc.c b/nuttx/fs/procfs/fs_procfsproc.c
index d646c6758..172a19fb6 100644
--- a/nuttx/fs/procfs/fs_procfsproc.c
+++ b/nuttx/fs/procfs/fs_procfsproc.c
@@ -708,7 +708,6 @@ static int process_dup(FAR const struct file *oldp, FAR struct file *newp)
static int process_opendir(FAR const char *relpath, FAR struct fs_dirent_s *dir)
{
FAR struct tcb_s *tcb;
- FAR void *priv = NULL;
irqstate_t flags;
fvdbg("relpath: \"%s\"\n", relpath ? relpath : "NULL");
@@ -784,14 +783,15 @@ static int process_opendir(FAR const char *relpath, FAR struct fs_dirent_s *dir)
return -ENOMEM;
}
- level1->base.level = 1;
- level1->base.nentries = PROCFS_NATTRS;
- level1->base.index = 0;
- level1->pid = pid;
+ /* Note that the index and procentry pointer were implicitly nullified
+ * by kzalloc(). Only the remaining, non-zero entries need be initialized.
+ */
- priv = (FAR void *)level1;
+ level1->base.level = 1;
+ level1->base.nentries = PROCFS_NATTRS;
+ level1->pid = pid;
- dir->u.procfs = priv;
+ dir->u.procfs = (FAR void *)level1;
return OK;
}
@@ -969,12 +969,28 @@ static int process_stat(const char *relpath, struct stat *buf)
buf->st_mode = S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR;
}
+
+ /* Verify that the process ID is followed by valid path segment delimiter */
+
+ else if (*ptr != '/')
+ {
+ /* We are required to return -ENOENT all all invalid paths */
+
+ fdbg("ERROR: Bad delimiter '%c' in relpath '%s'\n", *ptr, relpath);
+ return -ENOENT;
+ }
else
{
/* Otherwise, the second segment of the relpath should be a well
* known attribute of the task/thread.
*/
+ /* Skip over the path segment delimiter */
+
+ ptr++;
+
+ /* Lookup the well-known attribute string. */
+
ret = process_findattr(ptr);
if (ret < 0)
{
@@ -982,7 +998,7 @@ static int process_stat(const char *relpath, struct stat *buf)
return -ENOENT;
}
- /* It's a read-only file name */
+ /* If the attribute exists, it is the name for a read-only file. */
buf->st_mode = S_IFREG|S_IROTH|S_IRGRP|S_IRUSR;
}
diff --git a/nuttx/include/nuttx/fs/procfs.h b/nuttx/include/nuttx/fs/procfs.h
index cc3e49a40..ed7c56f18 100644
--- a/nuttx/include/nuttx/fs/procfs.h
+++ b/nuttx/include/nuttx/fs/procfs.h
@@ -52,9 +52,9 @@
struct procfs_operations
{
- /* The mountpoint open method differs from the driver open method
- * because it receives (1) the inode that contains the mountpoint
- * private data, (2) the relative path into the mountpoint, and (3)
+ /* The procfs open method differs from the driver open method
+ * because it receives (1) the inode that contains the procfs
+ * private data, (2) the relative path into the procfs, and (3)
* information to manage privileges.
*/
@@ -74,7 +74,7 @@ struct procfs_operations
* are extended methods needed to deal with the unique needs of mounted
* file systems.
*
- * Additional open-file-specific mountpoint operations:
+ * Additional open-file-specific procfs operations:
*/
int (*dup)(FAR const struct file *oldp, FAR struct file *newp);
@@ -99,8 +99,8 @@ struct procfs_operations
struct procfs_entry_s
{
- FAR const char *pathpattern;
- const struct procfs_operations *ops;
+ FAR const char *pathpattern;
+ FAR const struct procfs_operations *ops;
};
/* Specifies the common elements for an open file in the procfs
@@ -110,17 +110,17 @@ struct procfs_entry_s
struct procfs_file_s
{
- const struct procfs_entry_s *pProcfsEntry;
+ FAR const struct procfs_entry_s *procfsentry;
};
/* The generic proc/ pseudo directory structure */
struct procfs_dir_priv_s
{
- uint8_t level; /* Directory level. Currently 0 or 1 */
- uint16_t index; /* Index to the next directory entry */
- uint16_t nentries; /* Number of directory entries */
- struct procfs_entry_s *pProcfsEntry; /* Pointer to procfs handler entry */
+ uint8_t level; /* Directory level. Currently 0 or 1 */
+ uint16_t index; /* Index to the next directory entry */
+ uint16_t nentries; /* Number of directory entries */
+ FAR const struct procfs_entry_s *procfsentry; /* Pointer to procfs handler entry */
};
/****************************************************************************