xiaoxiang781216 commented on code in PR #20460:
URL: https://github.com/apache/nuttx/pull/20460#discussion_r4249696793
##########
fs/procfs/fs_procfsutil.c:
##########
@@ -45,6 +51,116 @@
#define LINEBUF_SIZE 128
+/* Largest representable positive off_t, derived from the actual off_t width.
+ * The windowed stream uses it to keep the returned byte count and the
+ * advanced file position representable.
+ */
+
+#define PROCFS_OFF_MAX \
Review Comment:
OFF_MAX
##########
fs/procfs/fs_procfsutil.c:
##########
@@ -45,6 +51,116 @@
#define LINEBUF_SIZE 128
+/* Largest representable positive off_t, derived from the actual off_t width.
+ * The windowed stream uses it to keep the returned byte count and the
+ * advanced file position representable.
+ */
+
+#define PROCFS_OFF_MAX \
+ ((off_t)(((uintmax_t)1 << (sizeof(off_t) * CHAR_BIT - 1)) - 1))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Private windowed output stream state used by procfs_format_read(). */
+
+struct procfs_format_stream_s
+{
+ struct lib_outstream_s common; /* Common stream state; nput is the logical
+ * count of all bytes offered so far */
+ FAR char *buffer; /* User receive buffer */
+ size_t buflen; /* Representable copy capacity of buffer */
+ size_t copied; /* Bytes copied to buffer so far */
+ off_t skip; /* Bytes still to skip before the window */
+ int err; /* First sticky negative errno, or zero */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: procfs_format_puts
+ *
+ * Description:
+ * Consume one renderer output block through the window: bytes before the
+ * requested file position reduce the remaining skip, bytes intersecting
+ * the user buffer are copied, and bytes beyond it are discarded. A block
+ * whose length cannot be represented in the logical count records a
+ * sticky deferred -EOVERFLOW.
+ *
+ ****************************************************************************/
+
+static ssize_t procfs_format_puts(FAR struct lib_outstream_s *self,
+ FAR const void *buf, size_t len)
+{
+ FAR struct procfs_format_stream_s *stream =
+ (FAR struct procfs_format_stream_s *)self;
+ FAR const char *src = buf;
+ size_t chunk;
+
+ if (stream->err < 0 || len == 0)
+ {
+ return (ssize_t)len;
Review Comment:
remove the cast
##########
fs/procfs/fs_procfsutil.c:
##########
@@ -45,6 +51,116 @@
#define LINEBUF_SIZE 128
+/* Largest representable positive off_t, derived from the actual off_t width.
+ * The windowed stream uses it to keep the returned byte count and the
+ * advanced file position representable.
+ */
+
+#define PROCFS_OFF_MAX \
+ ((off_t)(((uintmax_t)1 << (sizeof(off_t) * CHAR_BIT - 1)) - 1))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Private windowed output stream state used by procfs_format_read(). */
+
+struct procfs_format_stream_s
+{
+ struct lib_outstream_s common; /* Common stream state; nput is the logical
+ * count of all bytes offered so far */
+ FAR char *buffer; /* User receive buffer */
+ size_t buflen; /* Representable copy capacity of buffer */
+ size_t copied; /* Bytes copied to buffer so far */
+ off_t skip; /* Bytes still to skip before the window */
+ int err; /* First sticky negative errno, or zero */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: procfs_format_puts
+ *
+ * Description:
+ * Consume one renderer output block through the window: bytes before the
+ * requested file position reduce the remaining skip, bytes intersecting
+ * the user buffer are copied, and bytes beyond it are discarded. A block
+ * whose length cannot be represented in the logical count records a
+ * sticky deferred -EOVERFLOW.
+ *
+ ****************************************************************************/
+
+static ssize_t procfs_format_puts(FAR struct lib_outstream_s *self,
+ FAR const void *buf, size_t len)
+{
+ FAR struct procfs_format_stream_s *stream =
+ (FAR struct procfs_format_stream_s *)self;
+ FAR const char *src = buf;
+ size_t chunk;
+
+ if (stream->err < 0 || len == 0)
+ {
+ return (ssize_t)len;
+ }
+
+ /* Reject a block whose length cannot be represented in the logical count
+ * before it changes the count or the buffer.
+ */
+
+ if (len > (size_t)(PROCFS_OFF_MAX - stream->common.nput))
+ {
+ stream->err = -EOVERFLOW;
+ return (ssize_t)len;
Review Comment:
remove too
##########
fs/procfs/fs_procfsutil.c:
##########
@@ -45,6 +51,116 @@
#define LINEBUF_SIZE 128
+/* Largest representable positive off_t, derived from the actual off_t width.
+ * The windowed stream uses it to keep the returned byte count and the
+ * advanced file position representable.
+ */
+
+#define PROCFS_OFF_MAX \
+ ((off_t)(((uintmax_t)1 << (sizeof(off_t) * CHAR_BIT - 1)) - 1))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Private windowed output stream state used by procfs_format_read(). */
+
+struct procfs_format_stream_s
+{
+ struct lib_outstream_s common; /* Common stream state; nput is the logical
+ * count of all bytes offered so far */
+ FAR char *buffer; /* User receive buffer */
+ size_t buflen; /* Representable copy capacity of buffer */
+ size_t copied; /* Bytes copied to buffer so far */
+ off_t skip; /* Bytes still to skip before the window */
+ int err; /* First sticky negative errno, or zero */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: procfs_format_puts
+ *
+ * Description:
+ * Consume one renderer output block through the window: bytes before the
+ * requested file position reduce the remaining skip, bytes intersecting
+ * the user buffer are copied, and bytes beyond it are discarded. A block
+ * whose length cannot be represented in the logical count records a
+ * sticky deferred -EOVERFLOW.
+ *
+ ****************************************************************************/
+
+static ssize_t procfs_format_puts(FAR struct lib_outstream_s *self,
+ FAR const void *buf, size_t len)
+{
+ FAR struct procfs_format_stream_s *stream =
+ (FAR struct procfs_format_stream_s *)self;
+ FAR const char *src = buf;
+ size_t chunk;
+
+ if (stream->err < 0 || len == 0)
+ {
+ return (ssize_t)len;
+ }
+
+ /* Reject a block whose length cannot be represented in the logical count
+ * before it changes the count or the buffer.
+ */
+
+ if (len > (size_t)(PROCFS_OFF_MAX - stream->common.nput))
+ {
+ stream->err = -EOVERFLOW;
+ return (ssize_t)len;
+ }
+
+ stream->common.nput += (off_t)len;
Review Comment:
remove too
##########
fs/procfs/fs_procfsutil.c:
##########
@@ -45,6 +51,116 @@
#define LINEBUF_SIZE 128
+/* Largest representable positive off_t, derived from the actual off_t width.
+ * The windowed stream uses it to keep the returned byte count and the
+ * advanced file position representable.
+ */
+
+#define PROCFS_OFF_MAX \
+ ((off_t)(((uintmax_t)1 << (sizeof(off_t) * CHAR_BIT - 1)) - 1))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Private windowed output stream state used by procfs_format_read(). */
+
+struct procfs_format_stream_s
+{
+ struct lib_outstream_s common; /* Common stream state; nput is the logical
+ * count of all bytes offered so far */
+ FAR char *buffer; /* User receive buffer */
+ size_t buflen; /* Representable copy capacity of buffer */
+ size_t copied; /* Bytes copied to buffer so far */
+ off_t skip; /* Bytes still to skip before the window */
+ int err; /* First sticky negative errno, or zero */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: procfs_format_puts
+ *
+ * Description:
+ * Consume one renderer output block through the window: bytes before the
+ * requested file position reduce the remaining skip, bytes intersecting
+ * the user buffer are copied, and bytes beyond it are discarded. A block
+ * whose length cannot be represented in the logical count records a
+ * sticky deferred -EOVERFLOW.
+ *
+ ****************************************************************************/
+
+static ssize_t procfs_format_puts(FAR struct lib_outstream_s *self,
+ FAR const void *buf, size_t len)
+{
+ FAR struct procfs_format_stream_s *stream =
+ (FAR struct procfs_format_stream_s *)self;
+ FAR const char *src = buf;
+ size_t chunk;
+
+ if (stream->err < 0 || len == 0)
+ {
+ return (ssize_t)len;
+ }
+
+ /* Reject a block whose length cannot be represented in the logical count
+ * before it changes the count or the buffer.
+ */
+
+ if (len > (size_t)(PROCFS_OFF_MAX - stream->common.nput))
+ {
+ stream->err = -EOVERFLOW;
+ return (ssize_t)len;
+ }
+
+ stream->common.nput += (off_t)len;
+
+ /* Region 1: bytes before the requested file position */
+
+ if (stream->skip > 0)
+ {
+ if (len <= (size_t)stream->skip)
Review Comment:
remove all unnessassy cast
##########
fs/procfs/fs_procfsutil.c:
##########
@@ -212,4 +329,119 @@ void procfs_sprintf(FAR char *buf, size_t size, FAR off_t
*offset,
*offset -= copysize;
}
+/****************************************************************************
+ * Name: procfs_format_read
+ *
+ * Description:
+ * Read one window of the formatted text of a procfs file. The renderer
+ * is replayed from the beginning on a private, stack allocated stream:
+ * bytes before the current file position are skipped, bytes intersecting
+ * the caller's receive buffer are copied, bytes beyond it are discarded,
+ * and the file position advances only by the bytes actually copied.
+ * See the full contract in include/nuttx/fs/procfs.h.
+ *
+ * Input Parameters:
+ * filep - The file structure describing the open procfs file
+ * buffer - The address of the user's receive buffer
+ * buflen - The size (in bytes) of the user's receive buffer
+ * format - The renderer callback that formats the complete conceptual
+ * text of the node
+ * arg - The opaque context passed to the renderer
+ *
+ * Returned Value:
+ * The number of bytes actually transferred into the user's receive
+ * buffer, zero at end of file or for a zero length request, or a negated
+ * errno value on failure.
+ *
+ ****************************************************************************/
+
+ssize_t procfs_format_read(FAR struct file *filep, FAR char *buffer,
+ size_t buflen, procfs_format_t format,
+ FAR void *arg)
+{
+ struct procfs_format_stream_s stream;
+ size_t limit;
+ int ret;
+
+ DEBUGASSERT(filep != NULL && format != NULL);
+
+ /* A zero length request returns zero without invoking the renderer */
+
+ if (buflen == 0)
+ {
+ return 0;
+ }
+
+ DEBUGASSERT(buffer != NULL);
+
+ /* A negative file position is invalid; the renderer is not invoked */
+
+ if (filep->f_pos < 0)
+ {
+ return -EINVAL;
+ }
+
+ /* Bound the copy capacity by the largest positive ssize_t return and by
+ * the room left before the file position would exceed the largest
+ * positive off_t. A user buffer larger than this bound yields a short
+ * read plus a deferred overflow, replayed at the boundary on later reads.
+ */
+
+ limit = MIN(buflen, (size_t)SSIZE_MAX);
+ if (filep->f_pos > PROCFS_OFF_MAX - (off_t)limit)
Review Comment:
ditto
##########
fs/procfs/fs_procfsuptime.c:
##########
@@ -44,22 +44,13 @@
#include <nuttx/kmalloc.h>
#include <nuttx/fs/fs.h>
#include <nuttx/fs/procfs.h>
+#include <nuttx/streams.h>
#include "fs_heap.h"
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS)
#ifndef CONFIG_FS_PROCFS_EXCLUDE_UPTIME
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* Determines the size of an intermediate buffer that must be large enough
- * to handle the longest line generated by this logic.
- */
-
-#define UPTIME_LINELEN 16
Review Comment:
what's benefit switching from procfs_snprintf/procfs_memcpy to
procfs_format_read
##########
fs/procfs/fs_procfsutil.c:
##########
@@ -45,6 +51,116 @@
#define LINEBUF_SIZE 128
+/* Largest representable positive off_t, derived from the actual off_t width.
+ * The windowed stream uses it to keep the returned byte count and the
+ * advanced file position representable.
+ */
+
+#define PROCFS_OFF_MAX \
+ ((off_t)(((uintmax_t)1 << (sizeof(off_t) * CHAR_BIT - 1)) - 1))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Private windowed output stream state used by procfs_format_read(). */
+
+struct procfs_format_stream_s
+{
+ struct lib_outstream_s common; /* Common stream state; nput is the logical
+ * count of all bytes offered so far */
+ FAR char *buffer; /* User receive buffer */
+ size_t buflen; /* Representable copy capacity of buffer */
+ size_t copied; /* Bytes copied to buffer so far */
+ off_t skip; /* Bytes still to skip before the window */
+ int err; /* First sticky negative errno, or zero */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: procfs_format_puts
+ *
+ * Description:
+ * Consume one renderer output block through the window: bytes before the
+ * requested file position reduce the remaining skip, bytes intersecting
+ * the user buffer are copied, and bytes beyond it are discarded. A block
+ * whose length cannot be represented in the logical count records a
+ * sticky deferred -EOVERFLOW.
+ *
+ ****************************************************************************/
+
+static ssize_t procfs_format_puts(FAR struct lib_outstream_s *self,
+ FAR const void *buf, size_t len)
+{
+ FAR struct procfs_format_stream_s *stream =
+ (FAR struct procfs_format_stream_s *)self;
+ FAR const char *src = buf;
+ size_t chunk;
+
+ if (stream->err < 0 || len == 0)
+ {
+ return (ssize_t)len;
+ }
+
+ /* Reject a block whose length cannot be represented in the logical count
+ * before it changes the count or the buffer.
+ */
+
+ if (len > (size_t)(PROCFS_OFF_MAX - stream->common.nput))
+ {
+ stream->err = -EOVERFLOW;
+ return (ssize_t)len;
+ }
+
+ stream->common.nput += (off_t)len;
+
+ /* Region 1: bytes before the requested file position */
+
+ if (stream->skip > 0)
+ {
+ if (len <= (size_t)stream->skip)
+ {
+ stream->skip -= (off_t)len;
+ return (ssize_t)len;
+ }
+
+ len -= (size_t)stream->skip;
+ src += (size_t)stream->skip;
+ stream->skip = 0;
+ }
+
+ /* Region 2: bytes intersecting the user buffer */
+
+ chunk = MIN(len, stream->buflen - stream->copied);
+
+ if (chunk > 0)
+ {
+ memcpy(stream->buffer + stream->copied, src, chunk);
+ stream->copied += chunk;
+ }
+
+ /* Region 3: bytes beyond the buffer are discarded. The read entry point
+ * already clamped buflen so the copied count and advanced file position
+ * stay representable, so no per-byte overflow check is needed here.
+ */
+
+ return (ssize_t)len;
+}
+
+/****************************************************************************
+ * Name: procfs_format_putc
+ ****************************************************************************/
+
+static void procfs_format_putc(FAR struct lib_outstream_s *self, int ch)
+{
+ char value = (char)ch;
Review Comment:
remove too
##########
boards/arm/stm32g4/b-g431b-esc1/configs/cansock/defconfig:
##########
@@ -28,6 +28,7 @@ CONFIG_CANUTILS_LIBCANUTILS=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_FS_PROCFS=y
+CONFIG_FS_PROCFS_EXCLUDE_CPUINFO=y
Review Comment:
but why
##########
fs/procfs/fs_procfsuptime.c:
##########
@@ -180,94 +175,82 @@ static int uptime_close(FAR struct file *filep)
}
/****************************************************************************
- * Name: uptime_read
+ * Name: uptime_format
+ *
+ * Description:
+ * Render the up time text from the sample taken by the first read.
+ * Replayed from the beginning on every subsequent read by
+ * procfs_format_read().
+ *
+ * Input Parameters:
+ * stream - The generic output stream that receives the text
+ * arg - The open file private up time snapshot
+ *
+ * Returned Value:
+ * OK on completion
+ *
****************************************************************************/
-static ssize_t uptime_read(FAR struct file *filep, FAR char *buffer,
- size_t buflen)
+static int uptime_format(FAR struct lib_outstream_s *stream, FAR void *arg)
{
- FAR struct uptime_file_s *attr;
- size_t linesize;
- off_t offset;
- ssize_t ret;
- clock_t ticktime;
+ FAR struct uptime_file_s *attr = arg;
#if defined(CONFIG_HAVE_DOUBLE) && defined(CONFIG_LIBC_FLOATINGPOINT)
- double now;
+ lib_sprintf(stream, "%10.2f\n", attr->now);
#else
- uint64_t sec;
- unsigned int remainder;
- unsigned int csec;
+ lib_sprintf(stream, "%7" PRIu64 ".%02u\n", attr->sec, attr->csec);
#endif
- finfo("buffer=%p buflen=%d\n", buffer, (int)buflen);
+ return OK;
+}
- /* Recover our private data from the struct file instance */
+/****************************************************************************
+ * Name: uptime_read
+ *
+ * Description:
+ * Read one window of the formatted up time text through the formatted
+ * read helper.
+ *
+ * Input Parameters:
+ * filep - Open file structure
+ * buffer - User buffer that receives procfs data
+ * buflen - Size of the user buffer in bytes
+ *
+ * Returned Value:
+ * The number of bytes copied to the user buffer
+ *
+ ****************************************************************************/
- attr = (FAR struct uptime_file_s *)filep->f_priv;
- DEBUGASSERT(attr);
+static ssize_t uptime_read(FAR struct file *filep, FAR char *buffer,
+ size_t buflen)
+{
+ FAR struct uptime_file_s *attr = filep->f_priv;
+ clock_t ticktime;
- /* If f_pos is zero, then sample the system time. Otherwise, use
- * the cached system time from the previous read(). It is necessary
- * save the cached value in case, for example, the user is reading
- * the time one byte at a time. In that case, the time must remain
- * stable throughout the reads.
- */
+ finfo("buffer=%p buflen=%d\n", buffer, (int)buflen);
+
+ DEBUGASSERT(attr != NULL && buffer != NULL);
if (filep->f_pos == 0)
{
- /* System time */
-
ticktime = clock_systime_ticks() - INITIAL_SYSTEM_TIMER_TICKS;
#if defined(CONFIG_HAVE_DOUBLE) && defined(CONFIG_LIBC_FLOATINGPOINT)
- /* Convert the up time to a seconds + hundredths of seconds string */
-
- now = (double)ticktime / (double)CLOCKS_PER_SEC;
- linesize = procfs_snprintf(attr->line, UPTIME_LINELEN,
- "%10.2f\n", now);
-
+ attr->now = (double)ticktime / (double)CLOCKS_PER_SEC;
Review Comment:
why not move to uptime_format
##########
fs/procfs/fs_procfsutil.c:
##########
@@ -45,6 +51,116 @@
#define LINEBUF_SIZE 128
+/* Largest representable positive off_t, derived from the actual off_t width.
+ * The windowed stream uses it to keep the returned byte count and the
+ * advanced file position representable.
+ */
+
+#define PROCFS_OFF_MAX \
+ ((off_t)(((uintmax_t)1 << (sizeof(off_t) * CHAR_BIT - 1)) - 1))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Private windowed output stream state used by procfs_format_read(). */
+
+struct procfs_format_stream_s
+{
+ struct lib_outstream_s common; /* Common stream state; nput is the logical
+ * count of all bytes offered so far */
+ FAR char *buffer; /* User receive buffer */
+ size_t buflen; /* Representable copy capacity of buffer */
+ size_t copied; /* Bytes copied to buffer so far */
+ off_t skip; /* Bytes still to skip before the window */
+ int err; /* First sticky negative errno, or zero */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: procfs_format_puts
+ *
+ * Description:
+ * Consume one renderer output block through the window: bytes before the
+ * requested file position reduce the remaining skip, bytes intersecting
+ * the user buffer are copied, and bytes beyond it are discarded. A block
+ * whose length cannot be represented in the logical count records a
+ * sticky deferred -EOVERFLOW.
+ *
+ ****************************************************************************/
+
+static ssize_t procfs_format_puts(FAR struct lib_outstream_s *self,
+ FAR const void *buf, size_t len)
+{
+ FAR struct procfs_format_stream_s *stream =
+ (FAR struct procfs_format_stream_s *)self;
+ FAR const char *src = buf;
+ size_t chunk;
+
+ if (stream->err < 0 || len == 0)
+ {
+ return (ssize_t)len;
+ }
+
+ /* Reject a block whose length cannot be represented in the logical count
+ * before it changes the count or the buffer.
+ */
+
+ if (len > (size_t)(PROCFS_OFF_MAX - stream->common.nput))
Review Comment:
remove the cast
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]