From: Li Wang <liwang@redhat.com>
To: ltp@lists.linux.it
Subject: [LTP] [PATCH v3 1/3] kconfig: add funtion to parse /proc/cmdline
Date: Sun, 17 Mar 2024 17:38:59 +0800 [thread overview]
Message-ID: <20240317093901.3212684-2-liwang@redhat.com> (raw)
In-Reply-To: <20240317093901.3212684-1-liwang@redhat.com>
A new structure tst_kcmdline_var is defined to hold a command-line
argument's key and a fixed-size value. Furthermore, function
tst_kcmdline_parse is added to the corresponding .c file, which
reads from /proc/cmdline, parses the command-line arguments, and
populates the tst_kcmdline_var array with the obtained key-value
pairs, ensuring safe file operations and buffer size checks.
Signed-off-by: Li Wang <liwang@redhat.com>
---
include/tst_kconfig.h | 29 ++++++++++++++
lib/newlib_tests/test_kconfig03.c | 40 +++++++++++++++++++
lib/tst_kconfig.c | 66 +++++++++++++++++++++++++++++++
3 files changed, 135 insertions(+)
create mode 100644 lib/newlib_tests/test_kconfig03.c
diff --git a/include/tst_kconfig.h b/include/tst_kconfig.h
index 8b24a8380..bbb899784 100644
--- a/include/tst_kconfig.h
+++ b/include/tst_kconfig.h
@@ -6,6 +6,8 @@
#ifndef TST_KCONFIG_H__
#define TST_KCONFIG_H__
+#include <stdbool.h>
+
/**
* Initialization helper macro for struct tst_kconfig_var. Requires <string.h>
*/
@@ -64,4 +66,31 @@ void tst_kconfig_read(struct tst_kconfig_var vars[], size_t vars_len);
*/
int tst_kconfig_check(const char *const kconfigs[]);
+/**
+ * Macro to initialize a tst_kcmdline_var structure with a specified parameter
+ * name and an empty value. This is useful for setting up an array of parameter
+ * structures before parsing the actual command-line arguments.
+ */
+#define TST_KCMDLINE_INIT(paraname) { \
+ .key = paraname, \
+ .value = "", \
+ .found = false \
+}
+
+/**
+ * Structure for storing command-line parameter key and its corresponding value
+ */
+struct tst_kcmdline_var {
+ const char *key;
+ char value[128];
+ bool found;
+};
+
+/**
+ * Parses command-line parameters from /proc/cmdline and stores them in params array.
+ * params: The array of tst_kcmdline_var structures to be filled with parsed key-value pairs.
+ * params_len: The length of the params array, indicating how many parameters to parse.
+ */
+void tst_kcmdline_parse(struct tst_kcmdline_var params[], size_t params_len);
+
#endif /* TST_KCONFIG_H__ */
diff --git a/lib/newlib_tests/test_kconfig03.c b/lib/newlib_tests/test_kconfig03.c
new file mode 100644
index 000000000..937c2b29c
--- /dev/null
+++ b/lib/newlib_tests/test_kconfig03.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2024 Li Wang <liwang@redhat.com>
+ */
+
+#include "tst_test.h"
+#include "tst_kconfig.h"
+
+static struct tst_kcmdline_var params[] = {
+ TST_KCMDLINE_INIT("BOOT_IMAGE"),
+ TST_KCMDLINE_INIT("root"),
+ TST_KCMDLINE_INIT("foo")
+};
+
+static void do_test(void)
+{
+ int i, N;
+
+ N = (int) ARRAY_SIZE(params);
+
+ tst_kcmdline_parse(params, N);
+
+ for (i = 0; i < N; i++) {
+ if (params[i].found) {
+ if (params[i].value)
+ tst_res(TPASS, "params[%d] = {%s, %s}", i, params[i].key, params[i].value);
+ else
+ tst_res(TPASS, "params[%d] = {%s, no value}", i, params[i].key);
+ } else {
+ if (!strcmp(params[i].key, "foo"))
+ tst_res(TPASS, "%s is not found in /proc/cmdline", params[i].key);
+ else
+ tst_res(TFAIL, "%s is not found in /proc/cmdline", params[i].key);
+ }
+ }
+}
+
+static struct tst_test test = {
+ .test_all = do_test,
+};
diff --git a/lib/tst_kconfig.c b/lib/tst_kconfig.c
index 595ea4b09..e16ca1400 100644
--- a/lib/tst_kconfig.c
+++ b/lib/tst_kconfig.c
@@ -14,6 +14,7 @@
#include "tst_private.h"
#include "tst_kconfig.h"
#include "tst_bool_expr.h"
+#include "tst_safe_stdio.h"
static int kconfig_skip_check(void)
{
@@ -565,3 +566,68 @@ char tst_kconfig_get(const char *confname)
return var.choice;
}
+
+void tst_kcmdline_parse(struct tst_kcmdline_var params[], size_t params_len)
+{
+ char buf[128], line[512];
+ size_t b_pos = 0,l_pos =0, i;
+ int var_id = -1;
+
+ FILE *f = SAFE_FOPEN("/proc/cmdline", "r");
+
+ if (fgets(line, sizeof(line), f) == NULL) {
+ SAFE_FCLOSE(f);
+ tst_brk(TBROK, "Failed to read /proc/cmdline");
+ }
+
+ for (l_pos = 0; line[l_pos] != '\0'; l_pos++) {
+ char c = line[l_pos];
+
+ switch (c) {
+ case '=':
+ buf[b_pos] = '\0';
+ for (i = 0; i < params_len; i++) {
+ if (strcmp(buf, params[i].key) == 0) {
+ var_id = (int)i;
+ params[i].found = true;
+ }
+ }
+
+ b_pos = 0;
+ break;
+ case ' ':
+ case '\n':
+ buf[b_pos] = '\0';
+ if (var_id >= 0 && var_id < (int)params_len)
+ strcpy(params[var_id].value, buf);
+
+ var_id = -1;
+ b_pos = 0;
+ break;
+ default:
+ if (b_pos + 1 >= sizeof(buf)) {
+ tst_res(TWARN, "Buffer overflowed while parsing /proc/cmdline");
+ while (line[l_pos] != '\0' && line[l_pos] != ' ' && line[l_pos] != '\n')
+ l_pos++;
+
+ var_id = -1;
+ b_pos = 0;
+
+ if (line[l_pos] != '\0')
+ l_pos--;
+ } else {
+ buf[b_pos++] = c;
+ }
+ break;
+ }
+ }
+
+ for (i = 0; i < params_len; i++) {
+ if (params[i].found)
+ tst_res(TINFO, "%s is found in /proc/cmdline", params[i].key);
+ else
+ tst_res(TINFO, "%s is not found in /proc/cmdline", params[i].key);
+ }
+
+ SAFE_FCLOSE(f);
+}
--
2.40.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
next prev parent reply other threads:[~2024-03-17 9:39 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-17 9:38 [LTP] [PATCH v3 0/3] provide a unified way to parse /proc/cmdline Li Wang
2024-03-17 9:38 ` Li Wang [this message]
2024-03-17 21:10 ` [LTP] [PATCH v3 1/3] kconfig: add funtion " Petr Vorel
2024-03-18 6:18 ` Li Wang
2024-03-17 9:39 ` [LTP] [PATCH v3 2/3] init_module: To handle kernel module signature enforcement Li Wang
2024-03-17 9:39 ` [LTP] [PATCH v3 3/3] stack_clash: make use of tst_kcmdline_parse Li Wang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240317093901.3212684-2-liwang@redhat.com \
--to=liwang@redhat.com \
--cc=ltp@lists.linux.it \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.