From zhousiqi5 at huawei.com Mon Jul 3 03:22:59 2023 From: zhousiqi5 at huawei.com (zhousiqi (A)) Date: Mon, 3 Jul 2023 03:22:59 +0000 Subject: [Patch] Enable udhcpc6 in the busybox to obtain the SNTP server. Message-ID: <3e1151e8c82a4efd8f97a2fe495c45eb@huawei.com> Gentle ping... Is this function easy to use and is the community willing to accept it? In addition, can the community provide a default6.script for udhcpc6? ------------------------------------------------------ Dear BusyBox maintainers, I am writing to propose a patch for udhcpc6 that adds support for retrieving SNTP (Simple Network Time Protocol) servers. Currently, udhcpc6 does not support this function, which limits its usefulness in certain environments. My patch extends the existing -O option in udhcpc6 to include a new option, -O sntpsrv. When the -O sntpsrv option is used, udhcpc6 will request SNTP servers from the DHCPv6 server, and will configure the system's time accordingly. I have tested this patch on my own system, and have verified that it works as expected. I believe that this patch will be useful to other users who need to retrieve SNTP servers using udhcpc6. Thank you for your time and consideration. Best regards, Zhou >From 57e404b2a227e40fffe4d56045885939fa0e00d6 Mon Sep 17 00:00:00 2001 From: Zhou Siqi Date: Tue, 6 Jun 2023 15:46:36 +0800 Subject: [PATCH] The sntp server helps synchronize clock signals between the client and the server. Most DHCP software in the industry supports this function.Currently, udhcpc6 does not support the function of obtaining the SNTP server.This modification enables udhcpc6 to support this function. Signed-off-by: Zhou Siqi --- examples/var_service/dhcp_if/convert2sntpconf | 30 +++++++++++++ networking/udhcp/Config.src | 8 ++++ networking/udhcp/d6_common.h | 3 ++ networking/udhcp/d6_dhcpc.c | 61 +++++++++++++++++---------- 4 files changed, 79 insertions(+), 23 deletions(-) create mode 100644 examples/var_service/dhcp_if/convert2sntpconf diff --git a/examples/var_service/dhcp_if/convert2sntpconf b/examples/var_service/dhcp_if/convert2sntpconf new file mode 100644 index 0000000..c23e914 --- /dev/null +++ b/examples/var_service/dhcp_if/convert2sntpconf @@ -0,0 +1,30 @@ +#!/bin/sh +# This example shows how to obtain the SNTP server information from the configuration information obtained by the client. +# convert: +# (Client configuration information) +# dhcptype=5 +# lease=97200 +# interface=eth0 +# ip=2000:192:168::64:84/64 +# mask=64 +# dns=fec0:70:4000::22:33:40 fec0:70:4000::22:33:41 +fec0:70:4000::22:33:42 # domain=lab.example.com example.com # +sntpsrv=fec0:0:0:23::43 fec0:0:0:23::44 + +# into: + +#let cfg=cfg+1 +#sntpip[$cfg]=... + +exec >/dev/null +exec 2>&1 + +test "$interface" || exit 1 +test "$ip" || exit 1 + +{ +for n in $sntpsrv; do + echo "let cfg=cfg+1" + echo "sntpip[\$cfg]='$n'" +done +} >"$1" diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src index 8c8c11c..574c33c 100644 --- a/networking/udhcp/Config.src +++ b/networking/udhcp/Config.src @@ -171,3 +171,11 @@ config FEATURE_UDHCP_8021Q help If selected, both client and server will support passing of VLAN ID and priority via options 132 and 133 as per 802.1Q. + +config FEATURE_UDHCPC6_RFC4075 + bool "Support udhcpc6 obtain the SNTP servers." + default y + depends on UDHCPC6 + help + If selected, the IPv6 client udhcpc6 can obtain the SNTP servers. + diff --git a/networking/udhcp/d6_common.h b/networking/udhcp/d6_common.h index 9dfde77..49e1b5b 100644 --- a/networking/udhcp/d6_common.h +++ b/networking/udhcp/d6_common.h @@ -87,6 +87,9 @@ struct d6_option { #define D6_OPT_IA_PD 25 #define D6_OPT_IAPREFIX 26 +/* Adapted from dhcp */ +#define D6_OPT_SNTP_SERVERS 31 + /* RFC 4704 "The DHCPv6 Client FQDN Option" * uint16 option-code OPTION_CLIENT_FQDN (39) * uint16 option-len 1 + length of domain name diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 8d11a75..8707da1 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c @@ -81,6 +81,9 @@ static const struct dhcp_optflag d6_optflags[] = { { OPTION_STRING, D6_OPT_BOOT_URL }, { OPTION_STRING, D6_OPT_BOOT_PARAM }, #endif +#if ENABLE_FEATURE_UDHCPC6_RFC4075 + { OPTION_6RD | OPTION_LIST | OPTION_REQ, D6_OPT_SNTP_SERVERS }, +#endif { OPTION_STRING, 0xd1 }, /* DHCP_PXE_CONF_FILE */ { OPTION_STRING, 0xd2 }, /* DHCP_PXE_PATH_PREFIX */ { 0, 0 } @@ -102,6 +105,9 @@ static const char d6_option_strings[] ALIGN1 = "bootfile_url" "\0" /* D6_OPT_BOOT_URL */ "bootfile_param" "\0" /* D6_OPT_BOOT_PARAM */ #endif +#if ENABLE_FEATURE_UDHCPC6_RFC4075 + "sntpsrv" "\0" /* D6_OPT_SNTP_SERVERS */ +#endif "pxeconffile" "\0" /* DHCP_PXE_CONF_FILE */ "pxepathprefix" "\0" /* DHCP_PXE_PATH_PREFIX */ "\0"; @@ -243,10 +249,34 @@ static char *string_option_to_env(const uint8_t *option, return xasprintf("%s=%.*s", name, val_len, (char*)option + 4); } +static void handle_server_info(char *dev_key, const uint8_t *option, +int addrs, int option_offset) { + char *dlist; + + /* Make sure payload-size is a multiple of 16 */ + if ((option[3] & 0x0f) != 0) + return; + + /* Get the number of addresses on the option */ + addrs = option[3] >> 4; + + /* Setup environment variable */ + *new_env() = dlist = xmalloc(strlen(dev_key) + addrs * 40 - 1); + dlist = stpcpy(dlist, dev_key); + option_offset = 0; + + while (addrs--) { + dlist += sprint_nip6(dlist, option + 4 + option_offset); + option_offset += 16; + if (addrs) + *dlist++ = ' '; + } +} + /* put all the parameters into the environment */ static void option_to_env(const uint8_t *option, const uint8_t *option_end) { -#if ENABLE_FEATURE_UDHCPC6_RFC3646 +#if ENABLE_FEATURE_UDHCPC6_RFC3646 || ENABLE_FEATURE_UDHCPC6_RFC4075 int addrs, option_offset; #endif /* "length minus 4" */ @@ -339,28 +369,7 @@ static void option_to_env(const uint8_t *option, const uint8_t *option_end) break; #if ENABLE_FEATURE_UDHCPC6_RFC3646 case D6_OPT_DNS_SERVERS: { - char *dlist; - - /* Make sure payload-size is a multiple of 16 */ - if ((option[3] & 0x0f) != 0) - break; - - /* Get the number of addresses on the option */ - addrs = option[3] >> 4; - - /* Setup environment variable */ - *new_env() = dlist = xmalloc(4 + addrs * 40 - 1); - dlist = stpcpy(dlist, "dns="); - option_offset = 0; - - while (addrs--) { - sprint_nip6(dlist, option + 4 + option_offset); - dlist += 39; - option_offset += 16; - if (addrs) - *dlist++ = ' '; - } - + handle_server_info("dns=",option,addrs,option_offset); break; } case D6_OPT_DOMAIN_LIST: { @@ -406,6 +415,12 @@ static void option_to_env(const uint8_t *option, const uint8_t *option_end) *new_env() = xasprintf("tz_name=%.*s", (int)option[3], (char*)option + 4); break; #endif +#if ENABLE_FEATURE_UDHCPC6_RFC4075 + case D6_OPT_SNTP_SERVERS: { + handle_server_info("sntpsrv=",option,addrs,option_offset); + break; + } +#endif case D6_OPT_BOOT_URL: case D6_OPT_BOOT_PARAM: case 0xd1: /* DHCP_PXE_CONF_FILE */ -- 2.12.3 From zhousiqi5 at huawei.com Mon Jul 3 03:23:57 2023 From: zhousiqi5 at huawei.com (zhousiqi (A)) Date: Mon, 3 Jul 2023 03:23:57 +0000 Subject: [PATCH] Simplify display of IPv6 addresses based on international standard Message-ID: Gentle ping... Is this function easy to use and is the community willing to accept it? In addition, can the community provide a default6.script for udhcpc6? --------------------------------------------------------- Dear BusyBox maintainers, I am writing to propose a patch for dhcpc6 that simplifies the display of IPv6 addresses based on the international standard. Currently, when dhcpc6 obtains an IPv6 address, it displays the address in a full format, which can be difficult to read and compare. With this patch, the address will be displayed in a simplified format that is easier to read and understand. I have tested this patch on my own system and have not encountered any issues. However, I welcome any feedback or suggestions from the community. Thank you for considering my proposal. Best regards, Zhou >From 757b2901fd397399f6b050a015767d2355a6f36e Mon Sep 17 00:00:00 2001 From: Zhou Siqi Date: Tue, 6 Jun 2023 15:49:59 +0800 Subject: [PATCH] Currently, udhcpc6 does not support simplified IPv6 address based on standards. This modification enables udhcpc6 to support this function. Signed-off-by: Zhou Siqi --- networking/udhcp/Config.src | 7 +++++++ networking/udhcp/common.c | 19 ++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src index 574c33c..c4bb89f 100644 --- a/networking/udhcp/Config.src +++ b/networking/udhcp/Config.src @@ -179,3 +179,10 @@ config FEATURE_UDHCPC6_RFC4075 help If selected, the IPv6 client udhcpc6 can obtain the SNTP servers. +config FEATURE_UDHCPC6_SIMPLIFY + bool "Support udhcpc6 simplified ipv6 address" + default y + depends on UDHCPC6 + help + If selected, the IPv6 client udhcpc6 can simplify IPv6 addresses + based on international standards. diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index 31e525c..e457734 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c @@ -5,6 +5,9 @@ * Licensed under GPLv2, see file LICENSE in this source tree. */ #include "common.h" +#if ENABLE_FEATURE_UDHCPC6_SIMPLIFY +#include +#endif #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 unsigned dhcp_verbose; @@ -704,8 +707,12 @@ int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg, int FAST_FUNC sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) { char hexstrbuf[16 * 2]; +#if ENABLE_FEATURE_UDHCPC6_SIMPLIFY + struct in6_addr addr; + char compressed_address[INET6_ADDRSTRLEN]; +#endif bin2hex(hexstrbuf, (void*)ip, 16); - return sprintf(dest, /* "%s" */ + sprintf(dest, /* "%s" */ "%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s", /* pre, */ hexstrbuf + 0 * 4, @@ -717,4 +724,14 @@ int FAST_FUNC sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) hexstrbuf + 6 * 4, hexstrbuf + 7 * 4 ); +#if ENABLE_FEATURE_UDHCPC6_SIMPLIFY + inet_pton(AF_INET6, dest, &addr); + inet_ntop(AF_INET6, &addr, compressed_address, INET6_ADDRSTRLEN); + /* If dest is different from compressed_address, the simplified address is valid. + * In this case, assign the simplified address to dest. + */ + if (strcmp(dest, compressed_address) != 0) + strcpy(dest,compressed_address); +#endif + return strlen(dest); } -- 2.12.3 From andrej.picej at norik.com Mon Jul 3 06:30:39 2023 From: andrej.picej at norik.com (Andrej Picej) Date: Mon, 3 Jul 2023 08:30:39 +0200 Subject: [PATCH] hwclock: add get/set parameters option In-Reply-To: <20230605085745.1974591-1-andrej.picej@norik.com> References: <20230605085745.1974591-1-andrej.picej@norik.com> Message-ID: <9bde65d1-dda7-62c2-d6ba-ee9f7262d367@norik.com> Gentle ping. On 5. 06. 23 10:57, Andrej Picej wrote: > In kernel 5.16 special ioctls were introduced to get/set RTC parameters. > Add option to get/set parameters into busybox version of hwclock. > Implementation is similar to the one already used in linux-utils hwclock > tool. > > Example of parameter get use: > $ hwclock -g 2 > The RTC parameter 0x2 is set to 0x2. > $ hwclock --param-get bsm > The RTC parameter 0x2 is set to 0x2. > > Example of parameter set use: > $ hwclock -p 2=1 > The RTC parameter 0x2 will be set to 0x1. > $ hwclock -p bsm=2 > The RTC parameter 0x2 will be set to 0x2. > > Signed-off-by: Andrej Picej > --- > include/rtc_.h | 23 +++++++++ > util-linux/hwclock.c | 119 +++++++++++++++++++++++++++++++++++++++++-- > 2 files changed, 137 insertions(+), 5 deletions(-) > > diff --git a/include/rtc_.h b/include/rtc_.h > index 24ff536..4b8d9fc 100644 > --- a/include/rtc_.h > +++ b/include/rtc_.h > @@ -22,6 +22,11 @@ int rtc_xopen(const char **default_rtc, int flags) FAST_FUNC; > void rtc_read_tm(struct tm *ptm, int fd) FAST_FUNC; > time_t rtc_tm2time(struct tm *ptm, int utc) FAST_FUNC; > > +struct hwclock_param { > + int id; > + const char *name; > + const char *help; > +}; > > /* > * Everything below this point has been copied from linux/rtc.h > @@ -46,6 +51,17 @@ struct linux_rtc_wkalrm { > struct linux_rtc_time time; /* time the alarm is set to */ > }; > > +struct rtc_param { > + __u64 param; > + union { > + __u64 uvalue; > + __s64 svalue; > + __u64 ptr; > + }; > + __u32 index; > + __u32 __pad; > +}; > + > /* > * ioctl calls that are permitted to the /dev/rtc interface, if > * any of the RTC drivers are enabled. > @@ -71,12 +87,19 @@ struct linux_rtc_wkalrm { > #define RTC_WKALM_SET _IOW('p', 0x0f, struct linux_rtc_wkalrm)/* Set wakeup alarm*/ > #define RTC_WKALM_RD _IOR('p', 0x10, struct linux_rtc_wkalrm)/* Get wakeup alarm*/ > > +#define RTC_PARAM_GET _IOW('p', 0x13, struct rtc_param) /* Get parameter */ > +#define RTC_PARAM_SET _IOW('p', 0x14, struct rtc_param) /* Set parameter */ > + > /* interrupt flags */ > #define RTC_IRQF 0x80 /* any of the following is active */ > #define RTC_PF 0x40 > #define RTC_AF 0x20 > #define RTC_UF 0x10 > > +# define RTC_PARAM_FEATURES 0 > +# define RTC_PARAM_CORRECTION 1 > +# define RTC_PARAM_BACKUP_SWITCH_MODE 2 > + > POP_SAVED_FUNCTION_VISIBILITY > > #endif > diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c > index 723b095..0a49671 100644 > --- a/util-linux/hwclock.c > +++ b/util-linux/hwclock.c > @@ -48,6 +48,19 @@ > # define LIBC_IS_MUSL 0 > #endif > > +static const struct hwclock_param hwclock_params[] = > +{ > + { RTC_PARAM_FEATURES, "features", "supported features" }, > + { RTC_PARAM_CORRECTION, "correction", "time correction" }, > + { RTC_PARAM_BACKUP_SWITCH_MODE, "bsm", "backup switch mode" }, > + { } > +}; > + > +const struct hwclock_param *get_hwclock_params(void) > +{ > + return hwclock_params; > +} > + > > /* diff code is disabled: it's not sys/hw clock diff, it's some useless > * "time between hwclock was started and we saw CMOS tick" quantity. > @@ -320,6 +333,89 @@ static void from_sys_clock(const char **pp_rtcname, int utc) > close(rtc); > } > > +static int resolve_rtc_param_alias(const char *alias, __u64 *value) > +{ > + const struct hwclock_param *param = &hwclock_params[0]; > + > + while (param->name) { > + if (!strcmp(alias, param->name)) { > + *value = param->id; > + return 0; > + } > + param++; > + } > + > + return 1; > +} > + > +static void get_rtc_param(const char **pp_rtcname, const char *rtc_param) > +{ > + int rtc; > + struct rtc_param param = { .param = 0 }; > + > + if (resolve_rtc_param_alias(rtc_param, ¶m.param) != 0) { > + param.param = bb_strtoull(rtc_param, NULL, 0); > + if (errno) > + bb_error_msg_and_die("could not convert parameter name: '%s' to number", rtc_param); > + } > + > + rtc = rtc_xopen(pp_rtcname, O_RDONLY); > + > + xioctl(rtc, RTC_PARAM_GET, ¶m); > + > + printf("The RTC parameter 0x%jx is set to 0x%jx.\n", > + (uintmax_t) param.param, (uintmax_t) param.uvalue); > + > + if (ENABLE_FEATURE_CLEAN_UP) > + close(rtc); > +} > + > +static void set_rtc_param(const char **pp_rtcname, const char *rtc_param) > +{ > + int rtc; > + int ret = 1; > + struct rtc_param param = { .param = 0 }; > + char *tok, *opt = xstrdup(rtc_param); > + > + /* handle param name */ > + tok = strtok(opt, "="); > + if (resolve_rtc_param_alias(tok, ¶m.param) != 0) { > + param.param = bb_strtoull(tok, NULL, 0); > + if (errno) { > + bb_error_msg("could not convert parameter name: '%s' to number", tok); > + goto done; > + } > + } > + > + /* handle param value */ > + tok = strtok(NULL, "="); > + if (!tok) { > + bb_error_msg("expected ="); > + goto done; > + } > + param.uvalue = bb_strtoull(tok, NULL, 0); > + if (errno) { > + bb_error_msg("could not convert parameter value to number"); > + goto done; > + } > + > + rtc = rtc_xopen(pp_rtcname, O_WRONLY); > + > + printf("The RTC parameter 0x%jx will be set to 0x%jx.\n", > + (uintmax_t) param.param, (uintmax_t) param.uvalue); > + > + xioctl(rtc, RTC_PARAM_SET, ¶m); > + > + if (ENABLE_FEATURE_CLEAN_UP) > + close(rtc); > + > + ret = 0; > +done: > + free(opt); > + if (ret) > + bb_error_msg_and_die("error: %d", ret); > +} > + > // hwclock from util-linux 2.36.1 > // hwclock [function] [option...] > //Functions: > @@ -346,10 +442,10 @@ static void from_sys_clock(const char **pp_rtcname, int utc) > > //usage:#define hwclock_trivial_usage > //usage: IF_LONG_OPTS( > -//usage: "[-swul] [--systz] [-f DEV]" > +//usage: "[-swul] [--systz] [--param-get PARAM] [--param-set PARAM=VAL] [-f DEV]" > //usage: ) > //usage: IF_NOT_LONG_OPTS( > -//usage: "[-swult] [-f DEV]" > +//usage: "[-swult] [-g PARAM] [-p PARAM=VAL] [-f DEV]" > //usage: ) > //usage:#define hwclock_full_usage "\n\n" > //usage: "Show or set hardware clock (RTC)\n" > @@ -360,6 +456,8 @@ static void from_sys_clock(const char **pp_rtcname, int utc) > //usage: IF_LONG_OPTS( > //usage: "\n --systz Set in-kernel timezone, correct system time" > //usage: "\n if RTC is kept in local time" > +//usage: "\n --param-get PARAM Get RTC parameter" > +//usage: "\n --param-set PARAM=VAL Set RTC parameter" > //usage: ) > //usage: "\n -f DEV Use specified device (e.g. /dev/rtc2)" > //usage: "\n -u Assume RTC is kept in UTC" > @@ -375,11 +473,14 @@ static void from_sys_clock(const char **pp_rtcname, int utc) > #define HWCLOCK_OPT_SYSTOHC 0x10 > #define HWCLOCK_OPT_SYSTZ 0x20 > #define HWCLOCK_OPT_RTCFILE 0x40 > +#define HWCLOCK_OPT_PARAM_GET 0x80 > +#define HWCLOCK_OPT_PARAM_SET 0x100 > > int hwclock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; > int hwclock_main(int argc UNUSED_PARAM, char **argv) > { > const char *rtcname = NULL; > + const char *param = NULL; > unsigned opt; > int utc; > #if ENABLE_LONG_OPTS > @@ -391,14 +492,18 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv) > "systohc\0" No_argument "w" > "systz\0" No_argument "t" /* short opt is non-standard */ > "rtc\0" Required_argument "f" > + "param-get\0" Required_argument "g" /* short opt is non-standard */ > + "param-set\0" Required_argument "p" /* short opt is non-standard */ > ; > #endif > opt = getopt32long(argv, > - "^""lurswtf:v" /* -v is accepted and ignored */ > + "^""lurswtf:g:p:v" /* -v is accepted and ignored */ > "\0" > - "r--wst:w--rst:s--wrt:t--rsw:l--u:u--l", > + "r--wstgp:w--rstgp:s--wrtgp:t--rswgp:g--rswtp:p--rswtg:l--u:u--l", > hwclock_longopts, > - &rtcname > + &rtcname, > + ¶m, > + ¶m > ); > > /* If -u or -l wasn't given, check if we are using utc */ > @@ -413,6 +518,10 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv) > from_sys_clock(&rtcname, utc); > else if (opt & HWCLOCK_OPT_SYSTZ) > set_kernel_timezone_and_clock(utc, NULL); > + else if (opt & HWCLOCK_OPT_PARAM_GET) > + get_rtc_param(&rtcname, param); > + else if (opt & HWCLOCK_OPT_PARAM_SET) > + set_rtc_param(&rtcname, param); > else > /* default HWCLOCK_OPT_SHOW */ > show_clock(&rtcname, utc); From lovesykun at gmail.com Mon Jul 3 07:22:49 2023 From: lovesykun at gmail.com (=?UTF-8?B?5L2Z55Sf5LiO5ZCb?=) Date: Mon, 3 Jul 2023 15:22:49 +0800 Subject: [PATCH] getfattr: new applet In-Reply-To: <20230618085301.83181-1-lovesykun@gmail.com> References: <20230618085301.83181-1-lovesykun@gmail.com> Message-ID: Gentle ping. On Sun, Jun 18, 2023 at 4:53?PM LoveSy wrote: > > function old new delta > getfattr_main - 380 +380 > print_attr - 204 +204 > list_attr - 152 +152 > .rodata 95358 95401 +43 > applet_names 2766 2775 +9 > e843419 at 0048_000003ed_14 - 8 +8 > e843419 at 0047_000003d1_550 - 8 +8 > applet_main 3216 3224 +8 > packed_usage 34560 34567 +7 > applet_install_loc 201 202 +1 > ------------------------------------------------------------------------------ > (add/remove: 6/0 grow/shrink: 5/0 up/down: 820/0) Total: 820 bytes > text data bss dec hex filename > 1127717 16889 1736 1146342 117de6 busybox_old > 1141124 16937 1736 1159797 11b275 busybox_unstripped > > Signed-off-by: LoveSy > --- > miscutils/getfattr.c | 122 +++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 122 insertions(+) > create mode 100644 miscutils/getfattr.c > > diff --git a/miscutils/getfattr.c b/miscutils/getfattr.c > new file mode 100644 > index 000000000..4d4eacb5f > --- /dev/null > +++ b/miscutils/getfattr.c > @@ -0,0 +1,122 @@ > +/* > + * getfattr - get extended attributes of filesystem objects. > + * > + * Copyright (C) 2023 by LoveSy > + * > + * Licensed under GPLv2, see file LICENSE in this source tree. > + */ > +//config:config GETFATTR > +//config: bool "getfattr (12.3 kb)" > +//config: default y > +//config: help > +//config: Get extended attributes on files > + > +//applet:IF_GETFATTR(APPLET_NOEXEC(getfattr, getfattr, BB_DIR_USR_BIN, BB_SUID_DROP, getfattr)) > + > +//kbuild:lib-$(CONFIG_GETFATTR) += getfattr.o > + > +#include > +#include > +#include "libbb.h" > + > +//usage:#define getfattr_trivial_usage > +//usage: "[-h] -n|-d ATTR FILE..." > +//usage:#define getfattr_full_usage "\n\n" > +//usage: "Get extended attributes" > +//usage: "\n" > +//usage: "\n -h Do not follow symlinks" > +//usage: "\n -d Dump all attributes" > +//usage: "\n -n ATTR Get attribute ATTR" > +int getfattr_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; > + > +int print_attr(const char *file, const char *name, int follow, char **buf, size_t *buflen) > +{ > + ssize_t vallen, gotlen; > + vallen = (follow ? getxattr: lgetxattr)(file, name, NULL, 0); > + if (vallen == -1) { > + return -1; > + } > + vallen += 1; > + if (*buflen < vallen) { > + *buf = (char *)xrealloc(*buf, vallen); > + *buflen = vallen; > + } > + vallen = (follow ? getxattr : lgetxattr)(file, name, *buf, vallen); > + if (vallen == -1) { > + return -1; > + } > + (*buf)[vallen] = '\0'; > + printf("%s=\"%s\"\n", name, *buf); > + return 0; > +} > + > +ssize_t list_attr(const char *file, int follow, char **list, size_t *listlen) > +{ > + ssize_t len; > + len = (follow ? listxattr : llistxattr)(file, NULL, 0); > + if (len == -1) { > + return -1; > + } > + if (*listlen < len) { > + *list = (char *)xrealloc(*list, len); > + *listlen = len; > + } > + len = (follow ? listxattr : llistxattr)(file, *list, len); > + if (len == -1) { > + return -1; > + } > + return len; > +} > + > +int getfattr_main(int argc UNUSED_PARAM, char **argv) > +{ > + const char *name = NULL; > + int status; > + int opt; > + char *buf = NULL; > + size_t buflen = 0; > + char *list = NULL; > + size_t listlen = 0; > + enum { > + OPT_h = (1 << 0), > + OPT_d = (1 << 1), > + }; > + > + opt = getopt32(argv, "^" > + "hdn:" > + /* Min one arg, either -x or -n is a must, -d does not allow -n */ > + "\0" "-1:dn:n--d:d--n" > + , &name > + ); > + argv += optind; > + status = EXIT_SUCCESS; > + > + do { > + int r = 0; > + printf("# file: %s\n", *argv); > + if (opt & OPT_d) { > + ssize_t len = list_attr(*argv, !(opt & OPT_h), &list, &listlen); > + ssize_t keylen; > + char *key = list; > + while (len > 0 && !r) { > + r = print_attr(*argv, key, !(opt & OPT_h), &buf, &buflen); > + keylen = strlen(key) + 1; > + key += keylen; > + len -= keylen; > + } > + } > + else { > + r = print_attr(*argv, name, !(opt & OPT_h), &buf, &buflen); > + } > + printf("\n"); > + > + if (r) { > + bb_simple_perror_msg(*argv); > + status = EXIT_FAILURE; > + } > + } while (*++argv); > + > + free(buf); > + > + return status; > +} > -- > 2.34.1 > From steffen at sdaoden.eu Wed Jul 5 18:03:45 2023 From: steffen at sdaoden.eu (Steffen Nurpmeso) Date: Wed, 05 Jul 2023 20:03:45 +0200 Subject: fyi: pstree: "somehow" mutilated Message-ID: <20230705180345._JjFk%steffen@sdaoden.eu> Hello. I just stumbled upon this a minute ago, 'have not looked around. No containers are such involved. #?127|kent:$ busybox.static --help|head -n1 BusyBox v1.37.0.git (2023-06-15 17:50:36 CEST) multi-call binary. #?0|kent:$ busybox.static pstree ?-+-2*[encfs] |-sh---sleep |-sleep `-tmux: server-+-bash---s-nail---less |-bash---busybox.static |-bash---git---git---less |-3*[bash] `-vim Vs #?0|kent:$ pkginfo -o $(command -v pstree) Package File psmisc usr/bin/pstree #?0|kent:$ prt-get info psmisc Name: psmisc Path: /usr/ports/core Version: 23.6 Release: 1 Description: Small utilities that use the /proc filesystem URL: https://gitlab.com/psmisc/psmisc Maintainer: CRUX System Team, core-ports at crux dot nu Dependencies: ncurses #?0|kent:$ pstree ?-+-?---startx.sh---xinit-+-Xorg---4*[{Xorg}] | `-cwm---st---tmux: client |-encfs---4*[{encfs}] |-encfs---2*[{encfs}] |-sh---sleep |-sleep `-tmux: server-+-bash---s-nail---less |-bash---pstree |-bash---git---git---less |-3*[bash] `-vim---{vim} Note i do have (fwiw) #?0|kent:~# findmnt /proc/ TARGET SOURCE FSTYPE OPTIONS /proc none proc rw,nosuid,nodev,noexec,relatime,gid=10,hidepid=invisible but busybox ps(1) sees them #?0|kent:nail.git$ busybox.static ps axu PID USER TIME COMMAND 1261 steffen 0:00 {startx.sh} /bin/sh - /home/steffen/usr-kent-crux-linux-x86_64/bin/startx.sh 1335 steffen 0:00 xinit /home/steffen/.xinitrc -- /usr/lib/xorg-server/Xorg :0 -nolisten tcp vt1 1336 steffen 11:01 /usr/lib/xorg-server/Xorg :0 -nolisten tcp vt1 1343 steffen 0:03 cwm 1354 steffen 1:05 st -n stgrey -t accu 1356 steffen 0:00 {tmux: client} tmux a 1528 steffen 1:02 {tmux: server} tmux a 1529 steffen 0:00 -bash 1530 steffen 0:01 -bash 1531 steffen 0:00 -bash 1532 steffen 0:00 -bash 1533 steffen 0:00 -bash 1534 steffen 1:03 vim -u /home/steffen/.vimrc 1535 steffen 0:00 -bash 1582 steffen 0:00 vim -c :set filetype=mail /tmp/s-nail-edbase3PyjMj 2080 steffen 0:00 ssh root at kent 2251 steffen 0:00 busybox.static ps axu 3448 steffen 0:04 s-nail -Aich 17618 steffen 0:00 git loca 17619 steffen 0:00 /usr/lib/git-core/git log --oneline --graph --all 17620 steffen 0:00 less -I -F -R 31157 steffen 0:02 encfs --stdinpass /home/steffen/.sec.arena /home/steffen/sec.arena 31166 steffen 0:00 encfs --stdinpass /home/steffen/.secweb-mozilla /home/steffen/.mozilla 31256 steffen 0:00 sh /home/steffen/sic/setup-privacy.sh 31257 steffen 0:00 sleep 3600 (One second vim(1), not working enough this week, sigh!) --steffen | |Der Kragenbaer, The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt) From steffen at sdaoden.eu Wed Jul 5 19:31:36 2023 From: steffen at sdaoden.eu (Steffen Nurpmeso) Date: Wed, 05 Jul 2023 21:31:36 +0200 Subject: fyi: pstree: "somehow" mutilated In-Reply-To: <20230705180345._JjFk%steffen@sdaoden.eu> References: <20230705180345._JjFk%steffen@sdaoden.eu> Message-ID: <20230705193136.WHtx8%steffen@sdaoden.eu> Hmm... Steffen Nurpmeso wrote in <20230705180345._JjFk%steffen at sdaoden.eu>: |I just stumbled upon this a minute ago, 'have not looked around. |No containers are such involved. ... | #?0|kent:$ busybox.static pstree | ?-+-2*[encfs] ||-sh---sleep ||-sleep | `-tmux: server-+-bash---s-nail---less ||-bash---busybox.static ||-bash---git---git---less ||-3*[bash] | `-vim | |Vs .... | ?-+-?---startx.sh---xinit-+-Xorg---4*[{Xorg}] || `-cwm---st---tmux: client ||-encfs---4*[{encfs}] ||-encfs---2*[{encfs}] ||-sh---sleep ||-sleep | `-tmux: server-+-bash---s-nail---less ||-bash---pstree ||-bash---git---git---less ||-3*[bash] | `-vim---{vim} Now that i look at it again after some hours, if that "2*[encfs]" of busybox actually refers to ||-encfs---4*[{encfs}] ||-encfs---2*[{encfs}] and likely it does, then it makes sense to me again, and it is only that the X session as such is missing. ... |but busybox ps(1) sees them ... I do not know. --steffen | |Der Kragenbaer, The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt) From d+busybox at adaptive-enterprises.com Thu Jul 6 03:15:24 2023 From: d+busybox at adaptive-enterprises.com (David Leonard) Date: Thu, 6 Jul 2023 13:15:24 +1000 (AEST) Subject: [PATCH] getfattr: new applet In-Reply-To: References: <20230618085301.83181-1-lovesykun@gmail.com> Message-ID: <60o69nqq-q3rs-qrs9-o10-8oo0r02q1s98@nqncgvir-ragrecevfrf.pbz> On Mon, 3 Jul 2023, ???? wrote: > Gentle ping. > > On Sun, Jun 18, 2023 at 4:53?PM LoveSy wrote: >> >> function old new delta >> getfattr_main - 380 +380 >> print_attr - 204 +204 >> list_attr - 152 +152 >> .rodata 95358 95401 +43 >> applet_names 2766 2775 +9 >> e843419 at 0048_000003ed_14 - 8 +8 >> e843419 at 0047_000003d1_550 - 8 +8 >> applet_main 3216 3224 +8 >> packed_usage 34560 34567 +7 >> applet_install_loc 201 202 +1 >> ------------------------------------------------------------------------------ >> (add/remove: 6/0 grow/shrink: 5/0 up/down: 820/0) Total: 820 bytes >> text data bss dec hex filename >> 1127717 16889 1736 1146342 117de6 busybox_old >> 1141124 16937 1736 1159797 11b275 busybox_unstripped >> >> Signed-off-by: LoveSy >> --- >> miscutils/getfattr.c | 122 +++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 122 insertions(+) >> create mode 100644 miscutils/getfattr.c >> >> diff --git a/miscutils/getfattr.c b/miscutils/getfattr.c >> new file mode 100644 >> index 000000000..4d4eacb5f >> --- /dev/null >> +++ b/miscutils/getfattr.c >> @@ -0,0 +1,122 @@ >> +/* >> + * getfattr - get extended attributes of filesystem objects. >> + * >> + * Copyright (C) 2023 by LoveSy >> + * >> + * Licensed under GPLv2, see file LICENSE in this source tree. >> + */ >> +//config:config GETFATTR >> +//config: bool "getfattr (12.3 kb)" >> +//config: default y >> +//config: help >> +//config: Get extended attributes on files >> + >> +//applet:IF_GETFATTR(APPLET_NOEXEC(getfattr, getfattr, BB_DIR_USR_BIN, BB_SUID_DROP, getfattr)) >> + >> +//kbuild:lib-$(CONFIG_GETFATTR) += getfattr.o >> + >> +#include >> +#include >> +#include "libbb.h" >> + >> +//usage:#define getfattr_trivial_usage >> +//usage: "[-h] -n|-d ATTR FILE..." >> +//usage:#define getfattr_full_usage "\n\n" >> +//usage: "Get extended attributes" >> +//usage: "\n" >> +//usage: "\n -h Do not follow symlinks" >> +//usage: "\n -d Dump all attributes" >> +//usage: "\n -n ATTR Get attribute ATTR" Hi, The usage string is a bit confusing. The libattr tools' usages are online as: getfattr [-hRLP] -n name [-e en] pathname... getfattr [-hRLP] -d [-e en] [-m pattern] pathname... setfattr [-h] -n name [-v value] pathname... setfattr [-h] -x name pathname... setfattr [-h] --restore=file And the existing busybox setfattr is setfattr [-h] -n|-x ATTR [-v VALUE] FILE... Which I suppose makes more sense if you read it as setfattr [-h] {-n|-x} ATTR [-v VALUE] FILE... Here, in getfattr, perhaps you could steal the trivial usage pattern from mv.c and sed.c and write it like this? //usage: #define getfattr_trivial_usage //usage: "[-h] -n name FILE...\n" //usage: "or: getfattr [-h] -d FILE..." >> +int getfattr_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; >> + >> +int print_attr(const char *file, const char *name, int follow, char **buf, size_t *buflen) >> +{ >> + ssize_t vallen, gotlen; >> + vallen = (follow ? getxattr: lgetxattr)(file, name, NULL, 0); >> + if (vallen == -1) { >> + return -1; >> + } >> + vallen += 1; >> + if (*buflen < vallen) { >> + *buf = (char *)xrealloc(*buf, vallen); The cast should be unnecessary. Also for another xrealloc later. >> + *buflen = vallen; >> + } >> + vallen = (follow ? getxattr : lgetxattr)(file, name, *buf, vallen); Probably should pass arg 4 as *buflen. Also, similar for [l]listxattr later. >> + if (vallen == -1) { >> + return -1; >> + } >> + (*buf)[vallen] = '\0'; >> + printf("%s=\"%s\"\n", name, *buf); Could avoid +1 and '\0' termination with: printf("%s=\"%.*s\"\n", name, vallen, *buf); >> + return 0; >> +} >> + >> +ssize_t list_attr(const char *file, int follow, char **list, size_t *listlen) >> +{ >> + ssize_t len; >> + len = (follow ? listxattr : llistxattr)(file, NULL, 0); >> + if (len == -1) { >> + return -1; >> + } >> + if (*listlen < len) { >> + *list = (char *)xrealloc(*list, len); >> + *listlen = len; >> + } >> + len = (follow ? listxattr : llistxattr)(file, *list, len); >> + if (len == -1) { >> + return -1; >> + } >> + return len; >> +} >> + >> +int getfattr_main(int argc UNUSED_PARAM, char **argv) >> +{ >> + const char *name = NULL; >> + int status; >> + int opt; >> + char *buf = NULL; >> + size_t buflen = 0; >> + char *list = NULL; >> + size_t listlen = 0; Small nitpick: buflen and listlen (and keylen) are sizes, not lengths. It would align with the syscall parameter names ("size") in the manual pages. >> + enum { >> + OPT_h = (1 << 0), >> + OPT_d = (1 << 1), >> + }; >> + >> + opt = getopt32(argv, "^" >> + "hdn:" >> + /* Min one arg, either -x or -n is a must, -d does not allow -n */ >> + "\0" "-1:dn:n--d:d--n" The -x in the comment should be -d? Also, I suspect the ':dn:' component should be :d:n:, i.e.: /* Min one arg; exactly one of -n or -d is required. */ "\0" "-1:d:n:n--d:d--n" I'm unsure but I based this on the example in getopt32.c which says: // Don't allow -KS -SK, but -S or -K is required flags = getopt32(argv, "^KS...""\0""K:S:K--S:S--K"); >> + , &name >> + ); >> + argv += optind; >> + status = EXIT_SUCCESS; >> + >> + do { >> + int r = 0; >> + printf("# file: %s\n", *argv); >> + if (opt & OPT_d) { >> + ssize_t len = list_attr(*argv, !(opt & OPT_h), &list, &listlen); >> + ssize_t keylen; >> + char *key = list; >> + while (len > 0 && !r) { >> + r = print_attr(*argv, key, !(opt & OPT_h), &buf, &buflen); >> + keylen = strlen(key) + 1; >> + key += keylen; >> + len -= keylen; >> + } >> + } >> + else { >> + r = print_attr(*argv, name, !(opt & OPT_h), &buf, &buflen); >> + } >> + printf("\n"); >> + >> + if (r) { >> + bb_simple_perror_msg(*argv); >> + status = EXIT_FAILURE; >> + } >> + } while (*++argv); >> + >> + free(buf); >> + >> + return status; >> +} >> -- >> 2.34.1 >> > _______________________________________________ > busybox mailing list > busybox at busybox.net > http://lists.busybox.net/mailman/listinfo/busybox From d+busybox at adaptive-enterprises.com Thu Jul 6 03:58:08 2023 From: d+busybox at adaptive-enterprises.com (David Leonard) Date: Thu, 6 Jul 2023 13:58:08 +1000 (AEST) Subject: [PATCH] hwclock: add get/set parameters option In-Reply-To: <9bde65d1-dda7-62c2-d6ba-ee9f7262d367@norik.com> References: <20230605085745.1974591-1-andrej.picej@norik.com> <9bde65d1-dda7-62c2-d6ba-ee9f7262d367@norik.com> Message-ID: <98875r4n-2o0-1864-48p-2p1655n876o@nqncgvir-ragrecevfrf.pbz> On Mon, 3 Jul 2023, Andrej Picej wrote: > Gentle ping. > > On 5. 06. 23 10:57, Andrej Picej wrote: >> In kernel 5.16 special ioctls were introduced to get/set RTC parameters. >> Add option to get/set parameters into busybox version of hwclock. >> Implementation is similar to the one already used in linux-utils hwclock >> tool. >> >> Example of parameter get use: >> $ hwclock -g 2 >> The RTC parameter 0x2 is set to 0x2. >> $ hwclock --param-get bsm >> The RTC parameter 0x2 is set to 0x2. >> >> Example of parameter set use: >> $ hwclock -p 2=1 >> The RTC parameter 0x2 will be set to 0x1. >> $ hwclock -p bsm=2 >> The RTC parameter 0x2 will be set to 0x2. >> >> Signed-off-by: Andrej Picej >> --- >> include/rtc_.h | 23 +++++++++ >> util-linux/hwclock.c | 119 +++++++++++++++++++++++++++++++++++++++++-- >> 2 files changed, 137 insertions(+), 5 deletions(-) >> >> diff --git a/include/rtc_.h b/include/rtc_.h >> index 24ff536..4b8d9fc 100644 >> --- a/include/rtc_.h >> +++ b/include/rtc_.h >> @@ -22,6 +22,11 @@ int rtc_xopen(const char **default_rtc, int flags) >> FAST_FUNC; >> void rtc_read_tm(struct tm *ptm, int fd) FAST_FUNC; >> time_t rtc_tm2time(struct tm *ptm, int utc) FAST_FUNC; >> +struct hwclock_param { >> + int id; >> + const char *name; >> + const char *help; >> +}; >> /* >> * Everything below this point has been copied from linux/rtc.h >> @@ -46,6 +51,17 @@ struct linux_rtc_wkalrm { >> struct linux_rtc_time time; /* time the alarm is set to */ >> }; >> +struct rtc_param { >> + __u64 param; >> + union { >> + __u64 uvalue; >> + __s64 svalue; >> + __u64 ptr; >> + }; >> + __u32 index; >> + __u32 __pad; >> +}; >> + >> /* >> * ioctl calls that are permitted to the /dev/rtc interface, if >> * any of the RTC drivers are enabled. >> @@ -71,12 +87,19 @@ struct linux_rtc_wkalrm { >> #define RTC_WKALM_SET _IOW('p', 0x0f, struct linux_rtc_wkalrm)/* Set >> wakeup alarm*/ >> #define RTC_WKALM_RD _IOR('p', 0x10, struct linux_rtc_wkalrm)/* Get >> wakeup alarm*/ >> +#define RTC_PARAM_GET _IOW('p', 0x13, struct rtc_param) /* Get >> parameter */ >> +#define RTC_PARAM_SET _IOW('p', 0x14, struct rtc_param) /* Set >> parameter */ >> + >> /* interrupt flags */ >> #define RTC_IRQF 0x80 /* any of the following is active */ >> #define RTC_PF 0x40 >> #define RTC_AF 0x20 >> #define RTC_UF 0x10 >> +# define RTC_PARAM_FEATURES 0 >> +# define RTC_PARAM_CORRECTION 1 >> +# define RTC_PARAM_BACKUP_SWITCH_MODE 2 >> + >> POP_SAVED_FUNCTION_VISIBILITY >> #endif >> diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c >> index 723b095..0a49671 100644 >> --- a/util-linux/hwclock.c >> +++ b/util-linux/hwclock.c >> @@ -48,6 +48,19 @@ >> # define LIBC_IS_MUSL 0 >> #endif >> +static const struct hwclock_param hwclock_params[] = >> +{ >> + { RTC_PARAM_FEATURES, "features", "supported features" }, >> + { RTC_PARAM_CORRECTION, "correction", "time correction" }, >> + { RTC_PARAM_BACKUP_SWITCH_MODE, "bsm", "backup switch mode" }, >> + { } >> +}; >> + >> +const struct hwclock_param *get_hwclock_params(void) >> +{ >> + return hwclock_params; >> +} >> + >> /* diff code is disabled: it's not sys/hw clock diff, it's some useless >> * "time between hwclock was started and we saw CMOS tick" quantity. >> @@ -320,6 +333,89 @@ static void from_sys_clock(const char **pp_rtcname, >> int utc) >> close(rtc); >> } >> +static int resolve_rtc_param_alias(const char *alias, __u64 *value) >> +{ >> + const struct hwclock_param *param = &hwclock_params[0]; >> + >> + while (param->name) { >> + if (!strcmp(alias, param->name)) { Per docs/style-guide.txt, please use strcmp() == 0 >> + *value = param->id; >> + return 0; >> + } >> + param++; >> + } >> + >> + return 1; >> +} >> + >> +static void get_rtc_param(const char **pp_rtcname, const char *rtc_param) >> +{ >> + int rtc; >> + struct rtc_param param = { .param = 0 }; >> + >> + if (resolve_rtc_param_alias(rtc_param, ¶m.param) != 0) { >> + param.param = bb_strtoull(rtc_param, NULL, 0); >> + if (errno) >> + bb_error_msg_and_die("could not convert parameter >> name: '%s' to number", rtc_param); >> + } >> + >> + rtc = rtc_xopen(pp_rtcname, O_RDONLY); >> + >> + xioctl(rtc, RTC_PARAM_GET, ¶m); >> + >> + printf("The RTC parameter 0x%jx is set to 0x%jx.\n", >> + (uintmax_t) param.param, (uintmax_t) param.uvalue); >> + >> + if (ENABLE_FEATURE_CLEAN_UP) >> + close(rtc); >> +} >> + >> +static void set_rtc_param(const char **pp_rtcname, const char *rtc_param) >> +{ >> + int rtc; >> + int ret = 1; >> + struct rtc_param param = { .param = 0 }; >> + char *tok, *opt = xstrdup(rtc_param); >> + >> + /* handle param name */ >> + tok = strtok(opt, "="); >> + if (resolve_rtc_param_alias(tok, ¶m.param) != 0) { >> + param.param = bb_strtoull(tok, NULL, 0); >> + if (errno) { >> + bb_error_msg("could not convert parameter name: '%s' >> to number", tok); >> + goto done; >> + } >> + } >> + >> + /* handle param value */ >> + tok = strtok(NULL, "="); >> + if (!tok) { >> + bb_error_msg("expected ="); >> + goto done; >> + } >> + param.uvalue = bb_strtoull(tok, NULL, 0); >> + if (errno) { >> + bb_error_msg("could not convert parameter value to number"); >> + goto done; Could possibly replace all these {bb_error_msg();goto done;} with bb_error_msg_and_die(), then kill ret? >> + } >> + >> + rtc = rtc_xopen(pp_rtcname, O_WRONLY); >> + >> + printf("The RTC parameter 0x%jx will be set to 0x%jx.\n", >> + (uintmax_t) param.param, (uintmax_t) param.uvalue); >> + >> + xioctl(rtc, RTC_PARAM_SET, ¶m); >> + >> + if (ENABLE_FEATURE_CLEAN_UP) >> + close(rtc); >> + >> + ret = 0; >> +done: >> + free(opt); >> + if (ret) >> + bb_error_msg_and_die("error: %d", ret); >> +} >> + >> // hwclock from util-linux 2.36.1 >> // hwclock [function] [option...] >> //Functions: >> @@ -346,10 +442,10 @@ static void from_sys_clock(const char **pp_rtcname, >> int utc) >> //usage:#define hwclock_trivial_usage >> //usage: IF_LONG_OPTS( >> -//usage: "[-swul] [--systz] [-f DEV]" >> +//usage: "[-swul] [--systz] [--param-get PARAM] [--param-set >> PARAM=VAL] [-f DEV]" >> //usage: ) >> //usage: IF_NOT_LONG_OPTS( >> -//usage: "[-swult] [-f DEV]" >> +//usage: "[-swult] [-g PARAM] [-p PARAM=VAL] [-f DEV]" >> //usage: ) >> //usage:#define hwclock_full_usage "\n\n" >> //usage: "Show or set hardware clock (RTC)\n" >> @@ -360,6 +456,8 @@ static void from_sys_clock(const char **pp_rtcname, int >> utc) >> //usage: IF_LONG_OPTS( >> //usage: "\n --systz Set in-kernel timezone, correct system time" >> //usage: "\n if RTC is kept in local time" >> +//usage: "\n --param-get PARAM Get RTC parameter" >> +//usage: "\n --param-set PARAM=VAL Set RTC parameter" >> //usage: ) >> //usage: "\n -f DEV Use specified device (e.g. /dev/rtc2)" >> //usage: "\n -u Assume RTC is kept in UTC" >> @@ -375,11 +473,14 @@ static void from_sys_clock(const char **pp_rtcname, >> int utc) >> #define HWCLOCK_OPT_SYSTOHC 0x10 >> #define HWCLOCK_OPT_SYSTZ 0x20 >> #define HWCLOCK_OPT_RTCFILE 0x40 >> +#define HWCLOCK_OPT_PARAM_GET 0x80 >> +#define HWCLOCK_OPT_PARAM_SET 0x100 >> int hwclock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; >> int hwclock_main(int argc UNUSED_PARAM, char **argv) >> { >> const char *rtcname = NULL; >> + const char *param = NULL; >> unsigned opt; >> int utc; >> #if ENABLE_LONG_OPTS >> @@ -391,14 +492,18 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv) >> "systohc\0" No_argument "w" >> "systz\0" No_argument "t" /* short opt is non-standard */ >> "rtc\0" Required_argument "f" >> + "param-get\0" Required_argument "g" /* short opt is >> non-standard */ >> + "param-set\0" Required_argument "p" /* short opt is >> non-standard */ Could this be big enough to warrant a feature guard? e.g. FEATURE_HWCLOCK_SUPPORT_PARAM >> ; >> #endif >> opt = getopt32long(argv, >> - "^""lurswtf:v" /* -v is accepted and ignored */ >> + "^""lurswtf:g:p:v" /* -v is accepted and ignored */ >> "\0" >> - "r--wst:w--rst:s--wrt:t--rsw:l--u:u--l", >> + >> "r--wstgp:w--rstgp:s--wrtgp:t--rswgp:g--rswtp:p--rswtg:l--u:u--l", >> hwclock_longopts, >> - &rtcname >> + &rtcname, >> + ¶m, >> + ¶m >> ); >> /* If -u or -l wasn't given, check if we are using utc */ >> @@ -413,6 +518,10 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv) >> from_sys_clock(&rtcname, utc); >> else if (opt & HWCLOCK_OPT_SYSTZ) >> set_kernel_timezone_and_clock(utc, NULL); >> + else if (opt & HWCLOCK_OPT_PARAM_GET) >> + get_rtc_param(&rtcname, param); >> + else if (opt & HWCLOCK_OPT_PARAM_SET) >> + set_rtc_param(&rtcname, param); >> else >> /* default HWCLOCK_OPT_SHOW */ >> show_clock(&rtcname, utc); > _______________________________________________ > busybox mailing list > busybox at busybox.net > http://lists.busybox.net/mailman/listinfo/busybox > From andrej.picej at norik.com Thu Jul 6 05:05:42 2023 From: andrej.picej at norik.com (Andrej Picej) Date: Thu, 6 Jul 2023 07:05:42 +0200 Subject: [PATCH] hwclock: add get/set parameters option In-Reply-To: <98875r4n-2o0-1864-48p-2p1655n876o@nqncgvir-ragrecevfrf.pbz> References: <20230605085745.1974591-1-andrej.picej@norik.com> <9bde65d1-dda7-62c2-d6ba-ee9f7262d367@norik.com> <98875r4n-2o0-1864-48p-2p1655n876o@nqncgvir-ragrecevfrf.pbz> Message-ID: <1a05eb10-96db-ee6f-e0ca-80ac11ddc0f6@norik.com> Hi David, On 6. 07. 23 05:58, David Leonard wrote: > On Mon, 3 Jul 2023, Andrej Picej wrote: >> Gentle ping. >> >> On 5. 06. 23 10:57, Andrej Picej wrote: >>> In kernel 5.16 special ioctls were introduced to get/set RTC parameters. >>> Add option to get/set parameters into busybox version of hwclock. >>> Implementation is similar to the one already used in linux-utils hwclock >>> tool. >>> >>> Example of parameter get use: >>> $ hwclock -g 2 >>> The RTC parameter 0x2 is set to 0x2. >>> $ hwclock --param-get bsm >>> The RTC parameter 0x2 is set to 0x2. >>> >>> Example of parameter set use: >>> $ hwclock -p 2=1 >>> The RTC parameter 0x2 will be set to 0x1. >>> $ hwclock -p bsm=2 >>> The RTC parameter 0x2 will be set to 0x2. >>> >>> Signed-off-by: Andrej Picej >>> --- >>> ? include/rtc_.h?????? |? 23 +++++++++ >>> ? util-linux/hwclock.c | 119 +++++++++++++++++++++++++++++++++++++++++-- >>> ? 2 files changed, 137 insertions(+), 5 deletions(-) >>> >>> diff --git a/include/rtc_.h b/include/rtc_.h >>> index 24ff536..4b8d9fc 100644 >>> --- a/include/rtc_.h >>> +++ b/include/rtc_.h >>> @@ -22,6 +22,11 @@ int rtc_xopen(const char **default_rtc, int flags) >>> FAST_FUNC; >>> ? void rtc_read_tm(struct tm *ptm, int fd) FAST_FUNC; >>> ? time_t rtc_tm2time(struct tm *ptm, int utc) FAST_FUNC; >>> ? +struct hwclock_param { >>> +??? int id; >>> +??? const char *name; >>> +??? const char *help; >>> +}; >>> ??? /* >>> ?? * Everything below this point has been copied from linux/rtc.h >>> @@ -46,6 +51,17 @@ struct linux_rtc_wkalrm { >>> ????? struct linux_rtc_time time;? /* time the alarm is set to */ >>> ? }; >>> ? +struct rtc_param { >>> +??? __u64 param; >>> +??? union { >>> +??????? __u64 uvalue; >>> +??????? __s64 svalue; >>> +??????? __u64 ptr; >>> +??? }; >>> +??? __u32 index; >>> +??? __u32 __pad; >>> +}; >>> + >>> ? /* >>> ?? * ioctl calls that are permitted to the /dev/rtc interface, if >>> ?? * any of the RTC drivers are enabled. >>> @@ -71,12 +87,19 @@ struct linux_rtc_wkalrm { >>> ? #define RTC_WKALM_SET?? _IOW('p', 0x0f, struct linux_rtc_wkalrm)/* >>> Set wakeup alarm*/ >>> ? #define RTC_WKALM_RD??? _IOR('p', 0x10, struct linux_rtc_wkalrm)/* >>> Get wakeup alarm*/ >>> ? +#define RTC_PARAM_GET??? _IOW('p', 0x13, struct rtc_param)? /* Get >>> parameter */ >>> +#define RTC_PARAM_SET??? _IOW('p', 0x14, struct rtc_param)? /* Set >>> parameter */ >>> + >>> ? /* interrupt flags */ >>> ? #define RTC_IRQF 0x80 /* any of the following is active */ >>> ? #define RTC_PF 0x40 >>> ? #define RTC_AF 0x20 >>> ? #define RTC_UF 0x10 >>> ? +# define RTC_PARAM_FEATURES??????? 0 >>> +# define RTC_PARAM_CORRECTION??????? 1 >>> +# define RTC_PARAM_BACKUP_SWITCH_MODE??? 2 >>> + >>> ? POP_SAVED_FUNCTION_VISIBILITY >>> ??? #endif >>> diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c >>> index 723b095..0a49671 100644 >>> --- a/util-linux/hwclock.c >>> +++ b/util-linux/hwclock.c >>> @@ -48,6 +48,19 @@ >>> ? # define LIBC_IS_MUSL 0 >>> ? #endif >>> ? +static const struct hwclock_param hwclock_params[] = >>> +{ >>> +??? { RTC_PARAM_FEATURES,? "features", "supported features" }, >>> +??? { RTC_PARAM_CORRECTION, "correction", "time correction" }, >>> +??? { RTC_PARAM_BACKUP_SWITCH_MODE, "bsm", "backup switch mode" }, >>> +??? { } >>> +}; >>> + >>> +const struct hwclock_param *get_hwclock_params(void) >>> +{ >>> +??? return hwclock_params; >>> +} >>> + >>> ??? /* diff code is disabled: it's not sys/hw clock diff, it's some >>> useless >>> ?? * "time between hwclock was started and we saw CMOS tick" quantity. >>> @@ -320,6 +333,89 @@ static void from_sys_clock(const char >>> **pp_rtcname, int utc) >>> ????????? close(rtc); >>> ? } >>> ? +static int resolve_rtc_param_alias(const char *alias, __u64 *value) >>> +{ >>> +??? const struct hwclock_param *param = &hwclock_params[0]; >>> + >>> +??? while (param->name) { >>> +??????? if (!strcmp(alias, param->name)) { > > Per docs/style-guide.txt, please use strcmp() == 0 > Sorry, was not aware of that, will change in v2. >>> +??????????? *value = param->id; >>> +??????????? return 0; >>> +??????? } >>> +??????? param++; >>> +??? } >>> + >>> +??? return 1; >>> +} >>> + >>> +static void get_rtc_param(const char **pp_rtcname, const char >>> *rtc_param) >>> +{ >>> +??? int rtc; >>> +??? struct rtc_param param = { .param = 0 }; >>> + >>> +??? if (resolve_rtc_param_alias(rtc_param, ¶m.param) != 0) { >>> +??????? param.param = bb_strtoull(rtc_param, NULL, 0); >>> +??????? if (errno) >>> +??????????? bb_error_msg_and_die("could not convert parameter name: >>> '%s' to number", rtc_param); >>> +??? } >>> + >>> +??? rtc = rtc_xopen(pp_rtcname, O_RDONLY); >>> + >>> +??? xioctl(rtc, RTC_PARAM_GET, ¶m); >>> + >>> +??? printf("The RTC parameter 0x%jx is set to 0x%jx.\n", >>> +??????? (uintmax_t) param.param, (uintmax_t) param.uvalue); >>> + >>> +??? if (ENABLE_FEATURE_CLEAN_UP) >>> +??????? close(rtc); >>> +} >>> + >>> +static void set_rtc_param(const char **pp_rtcname, const char >>> *rtc_param) >>> +{ >>> +??? int rtc; >>> +??? int? ret = 1; >>> +??? struct rtc_param param = { .param = 0 }; >>> +??? char *tok, *opt = xstrdup(rtc_param); >>> + >>> +??? /* handle param name */ >>> +??? tok = strtok(opt, "="); >>> +??? if (resolve_rtc_param_alias(tok, ¶m.param) != 0) { >>> +??????? param.param = bb_strtoull(tok, NULL, 0); >>> +??????? if (errno) { >>> +??????????? bb_error_msg("could not convert parameter name: '%s' to >>> number", tok); >>> +??????????? goto done; >>> +??????? } >>> +??? } >>> + >>> +??? /* handle param value */ >>> +??? tok = strtok(NULL, "="); >>> +??? if (!tok) { >>> +??????? bb_error_msg("expected ="); >>> +??????? goto done; >>> +??? } >>> +??? param.uvalue = bb_strtoull(tok, NULL, 0); >>> +??? if (errno) { >>> +??????? bb_error_msg("could not convert parameter value to number"); >>> +??????? goto done; > > Could possibly replace all these {bb_error_msg();goto done;} with > bb_error_msg_and_die(), then kill ret? > Yeah sure, resources are freed with process termination. Will change in v2. >>> +??? } >>> + >>> +??? rtc = rtc_xopen(pp_rtcname, O_WRONLY); >>> + >>> +??? printf("The RTC parameter 0x%jx will be set to 0x%jx.\n", >>> +??????? (uintmax_t) param.param, (uintmax_t) param.uvalue); >>> + >>> +??? xioctl(rtc, RTC_PARAM_SET, ¶m); >>> + >>> +??? if (ENABLE_FEATURE_CLEAN_UP) >>> +??????? close(rtc); >>> + >>> +??? ret = 0; >>> +done: >>> +??? free(opt); >>> +??? if (ret) >>> +??????? bb_error_msg_and_die("error: %d", ret); >>> +} >>> + >>> ? // hwclock from util-linux 2.36.1 >>> ? // hwclock [function] [option...] >>> ? //Functions: >>> @@ -346,10 +442,10 @@ static void from_sys_clock(const char >>> **pp_rtcname, int utc) >>> ??? //usage:#define hwclock_trivial_usage >>> ? //usage:??? IF_LONG_OPTS( >>> -//usage:?????? "[-swul] [--systz] [-f DEV]" >>> +//usage:?????? "[-swul] [--systz] [--param-get PARAM] [--param-set >>> PARAM=VAL] [-f DEV]" >>> ? //usage:??? ) >>> ? //usage:??? IF_NOT_LONG_OPTS( >>> -//usage:?????? "[-swult] [-f DEV]" >>> +//usage:?????? "[-swult] [-g PARAM] [-p PARAM=VAL] [-f DEV]" >>> ? //usage:??? ) >>> ? //usage:#define hwclock_full_usage "\n\n" >>> ? //usage:?????? "Show or set hardware clock (RTC)\n" >>> @@ -360,6 +456,8 @@ static void from_sys_clock(const char >>> **pp_rtcname, int utc) >>> ? //usage:??? IF_LONG_OPTS( >>> ? //usage:???? "\n??? --systz??? Set in-kernel timezone, correct >>> system time" >>> ? //usage:???? "\n??????? if RTC is kept in local time" >>> +//usage:???? "\n??? --param-get PARAM??? Get RTC parameter" >>> +//usage:???? "\n??? --param-set PARAM=VAL??? Set RTC parameter" >>> ? //usage:??? ) >>> ? //usage:???? "\n??? -f DEV??? Use specified device (e.g. /dev/rtc2)" >>> ? //usage:???? "\n??? -u??? Assume RTC is kept in UTC" >>> @@ -375,11 +473,14 @@ static void from_sys_clock(const char >>> **pp_rtcname, int utc) >>> ? #define HWCLOCK_OPT_SYSTOHC???? 0x10 >>> ? #define HWCLOCK_OPT_SYSTZ?????? 0x20 >>> ? #define HWCLOCK_OPT_RTCFILE???? 0x40 >>> +#define HWCLOCK_OPT_PARAM_GET?? 0x80 >>> +#define HWCLOCK_OPT_PARAM_SET?? 0x100 >>> ??? int hwclock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; >>> ? int hwclock_main(int argc UNUSED_PARAM, char **argv) >>> ? { >>> ????? const char *rtcname = NULL; >>> +??? const char *param = NULL; >>> ????? unsigned opt; >>> ????? int utc; >>> ? #if ENABLE_LONG_OPTS >>> @@ -391,14 +492,18 @@ int hwclock_main(int argc UNUSED_PARAM, char >>> **argv) >>> ????????? "systohc\0"?? No_argument "w" >>> ????????? "systz\0"???? No_argument "t" /* short opt is non-standard */ >>> ????????? "rtc\0"?????? Required_argument "f" >>> +??????? "param-get\0" Required_argument "g"? /* short opt is >>> non-standard */ >>> +??????? "param-set\0" Required_argument "p"? /* short opt is >>> non-standard */ > > Could this be big enough to warrant a feature guard? > e.g. FEATURE_HWCLOCK_SUPPORT_PARAM > I don't think this is necessary since this should be a default, and the code for this is really not that big. Do you agree? Thanks for the review, Andrej >>> ????????? ; >>> ? #endif >>> ????? opt = getopt32long(argv, >>> -??????? "^""lurswtf:v" /* -v is accepted and ignored */ >>> +??????? "^""lurswtf:g:p:v" /* -v is accepted and ignored */ >>> ????????? "\0" >>> -??????? "r--wst:w--rst:s--wrt:t--rsw:l--u:u--l", >>> + "r--wstgp:w--rstgp:s--wrtgp:t--rswgp:g--rswtp:p--rswtg:l--u:u--l", >>> ????????? hwclock_longopts, >>> -??????? &rtcname >>> +??????? &rtcname, >>> +??????? ¶m, >>> +??????? ¶m >>> ????? ); >>> ??????? /* If -u or -l wasn't given, check if we are using utc */ >>> @@ -413,6 +518,10 @@ int hwclock_main(int argc UNUSED_PARAM, char >>> **argv) >>> ????????? from_sys_clock(&rtcname, utc); >>> ????? else if (opt & HWCLOCK_OPT_SYSTZ) >>> ????????? set_kernel_timezone_and_clock(utc, NULL); >>> +??? else if (opt & HWCLOCK_OPT_PARAM_GET) >>> +??????? get_rtc_param(&rtcname, param); >>> +??? else if (opt & HWCLOCK_OPT_PARAM_SET) >>> +??????? set_rtc_param(&rtcname, param); >>> ????? else >>> ????????? /* default HWCLOCK_OPT_SHOW */ >>> ????????? show_clock(&rtcname, utc); >> _______________________________________________ >> busybox mailing list >> busybox at busybox.net >> http://lists.busybox.net/mailman/listinfo/busybox >> From lovesykun at gmail.com Fri Jul 7 08:44:24 2023 From: lovesykun at gmail.com (LoveSy) Date: Fri, 7 Jul 2023 16:44:24 +0800 Subject: [PATCH] getfattr: new applet In-Reply-To: <60o69nqq-q3rs-qrs9-o10-8oo0r02q1s98@nqncgvir-ragrecevfrf.pbz> References: <60o69nqq-q3rs-qrs9-o10-8oo0r02q1s98@nqncgvir-ragrecevfrf.pbz> Message-ID: <20230707084424.215610-1-lovesykun@gmail.com> function old new delta getfattr_main - 380 +380 print_attr - 204 +204 list_attr - 152 +152 .rodata 95358 95401 +43 applet_names 2766 2775 +9 e843419 at 0048_000003ed_14 - 8 +8 e843419 at 0047_000003d1_550 - 8 +8 applet_main 3216 3224 +8 packed_usage 34560 34567 +7 applet_install_loc 201 202 +1 ------------------------------------------------------------------------------ (add/remove: 6/0 grow/shrink: 5/0 up/down: 820/0) Total: 820 bytes text data bss dec hex filename 1127717 16889 1736 1146342 117de6 busybox_old 1141124 16937 1736 1159797 11b275 busybox_unstripped Signed-off-by: LoveSy --- Thansk for your review. Updated the patch. Please have a check. miscutils/getfattr.c | 121 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 miscutils/getfattr.c diff --git a/miscutils/getfattr.c b/miscutils/getfattr.c new file mode 100644 index 000000000..44556cb24 --- /dev/null +++ b/miscutils/getfattr.c @@ -0,0 +1,121 @@ +/* + * getfattr - get extended attributes of filesystem objects. + * + * Copyright (C) 2023 by LoveSy + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ +//config:config GETFATTR +//config: bool "getfattr (12.3 kb)" +//config: default y +//config: help +//config: Get extended attributes on files + +//applet:IF_GETFATTR(APPLET_NOEXEC(getfattr, getfattr, BB_DIR_USR_BIN, BB_SUID_DROP, getfattr)) + +//kbuild:lib-$(CONFIG_GETFATTR) += getfattr.o + +#include +#include +#include "libbb.h" + +//usage:#define getfattr_trivial_usage +//usage: "[-h] -n ATTR FILE...\n" +//usage: "or: getfattr [-h] -d FILE..." +//usage:#define getfattr_full_usage "\n\n" +//usage: "Get extended attributes" +//usage: "\n" +//usage: "\n -h Do not follow symlinks" +//usage: "\n -d Dump all attributes" +//usage: "\n -n ATTR Get attribute ATTR" +int getfattr_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; + +int print_attr(const char *file, const char *name, int follow, char **buf, size_t *bufsize) +{ + ssize_t len; + len = (follow ? getxattr: lgetxattr)(file, name, NULL, 0); + if (len == -1) { + return -1; + } + if (*bufsize < len) { + *buf = xrealloc(*buf, len); + *bufsize = len; + } + len = (follow ? getxattr : lgetxattr)(file, name, *buf, *bufsize); + if (len == -1) { + return -1; + } + printf("%s=\"%.*s\"\n", name, len, *buf); + return 0; +} + +ssize_t list_attr(const char *file, int follow, char **list, size_t *listsize) +{ + ssize_t len; + len = (follow ? listxattr : llistxattr)(file, NULL, 0); + if (len == -1) { + return -1; + } + if (*listsize < len) { + *list = xrealloc(*list, len); + *listsize = len; + } + len = (follow ? listxattr : llistxattr)(file, *list, *listsize); + if (len == -1) { + return -1; + } + return len; +} + +int getfattr_main(int argc UNUSED_PARAM, char **argv) +{ + const char *name = NULL; + int status; + int opt; + char *buf = NULL; + size_t bufsize = 0; + char *list = NULL; + size_t listsize = 0; + enum { + OPT_h = (1 << 0), + OPT_d = (1 << 1), + }; + + opt = getopt32(argv, "^" + "hdn:" + /* Min one arg; exactly one of -n or -d is required. */ + "\0" "-1:d:n:n--d:d--n" + , &name + ); + argv += optind; + status = EXIT_SUCCESS; + + do { + int r = 0; + printf("# file: %s\n", *argv); + if (opt & OPT_d) { + ssize_t len = list_attr(*argv, !(opt & OPT_h), &list, &listsize); + ssize_t keylen; + char *key = list; + while (len > 0 && !r) { + r = print_attr(*argv, key, !(opt & OPT_h), &buf, &bufsize); + keylen = strlen(key) + 1; + key += keylen; + len -= keylen; + } + } + else { + r = print_attr(*argv, name, !(opt & OPT_h), &buf, &bufsize); + } + + if (r) { + bb_simple_perror_msg(*argv); + status = EXIT_FAILURE; + } + printf("\n"); + } while (*++argv); + + free(buf); + + return status; +} -- 2.34.1 From oliver+busybox at schinagl.nl Fri Jul 7 09:17:38 2023 From: oliver+busybox at schinagl.nl (Olliver Schinagl) Date: Fri, 7 Jul 2023 11:17:38 +0200 Subject: [PATCH] Extend I2C tools to read unlimited lengths In-Reply-To: <20230512083525.3164148-1-oliver+busybox@schinagl.nl> References: <20230512083525.3164148-1-oliver+busybox@schinagl.nl> Message-ID: <3ba887d5-db51-6fd0-eb8e-dc54e825801c@schinagl.nl> Gentle ping :) On 12-05-2023 10:35, Olliver Schinagl wrote: > The I2C tools suggest they can do block read/writes using either > 's'(mbus) or 'i'(2c) access. However the current code limits reads > specifically to a single block, which depending on the driver, may limit > this to even less bytes. Looking closer, we actually see that the commands > to read via either access is really the same, where the only difference > is, that SMBus access can at most read 32 bytes (but can read less) but > cannot be told to read less, and I2C access can read up to 1 byte > granularity. Everything else works the same, and thus the loop to read > multiple bytes works for both cases equally well. This change thus also > reduces the code a tiny bit, but makes it more readable at the least. > > Further more, while here, a little bit of cleanup. One cosmetic and one > where instead of always returning -1 (which is horrible to debug when > your console just tells you this) instead returns errno that ioctl had > already set for us anyway. > > > _______________________________________________ > busybox mailing list > busybox at busybox.net > http://lists.busybox.net/mailman/listinfo/busybox From vda.linux at googlemail.com Sun Jul 9 18:44:00 2023 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sun, 9 Jul 2023 20:44:00 +0200 Subject: [PATCH] libiproute: fix filtering ip6 route by table id In-Reply-To: References: <20230212043020.861-1-yszhou4tech@gmail.com> Message-ID: Applied, thank you. On Sun, Mar 5, 2023 at 2:38?AM Yousong Zhou wrote: > > > > The very same code exists in current iproute2 git tree. > > > Is it also buggy in the same way? > > > > Hi Denys > > > > I checked before and iproute2 works just fine. The code is a bit different: > > Friendly ping. > > Regards, > yousong > > > > > > > > > iproute.c > > > static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len) > > > { > > > struct rtmsg *r = NLMSG_DATA(n); > > > inet_prefix dst = { .family = r->rtm_family }; > > > inet_prefix src = { .family = r->rtm_family }; > > > inet_prefix via = { .family = r->rtm_family }; > > > inet_prefix prefsrc = { .family = r->rtm_family }; > > > __u32 table; > > > static int ip6_multiple_tables; > > > > > > table = rtm_get_table(r, tb); > > > > > > if (preferred_family != AF_UNSPEC && r->rtm_family != preferred_family) > > > return 0; > > > > > > if (r->rtm_family == AF_INET6 && table != RT_TABLE_MAIN) > > > ip6_multiple_tables = 1; > > > > It sets ip6_multiple_tables here. > > > > > > > > if (filter.cloned == !(r->rtm_flags & RTM_F_CLONED)) > > > return 0; > > > > > > if (r->rtm_family == AF_INET6 && !ip6_multiple_tables) { > > > > So it won't go into this branch > > > > > if (filter.tb) { > > > if (filter.tb == RT_TABLE_LOCAL) { > > > if (r->rtm_type != RTN_LOCAL) > > > return 0; > > > } else if (filter.tb == RT_TABLE_MAIN) { > > > if (r->rtm_type == RTN_LOCAL) > > > return 0; > > > } else { > > > return 0; > > > } > > > } > > > } else { > > > if (filter.tb > 0 && filter.tb != table) > > > return 0; > > > > The check happens here. > > > > Regards, > > yousong > > > > > } From steffen.hamann at keysight.com Tue Jul 11 07:40:16 2023 From: steffen.hamann at keysight.com (Steffen Hamann) Date: Tue, 11 Jul 2023 07:40:16 +0000 Subject: httpd x-frame-option HTTP respnse header Message-ID: Dear BusyBox maintainers, I hope this information can be useful for you. Our Nessus scan recommends adding some additional x-frame-option to your httpd. Is there something already available? (sorry, but I can't find anything where I can modify the HTTP response header). This is just an idea: --- a/networking/httpd.c +++ b/networking/httpd.c @@ -1133,6 +1133,7 @@ static void send_headers(unsigned responseNum) if (responseNum != HTTP_OK || found_mime_type) { len += sprintf(iobuf + len, "Content-type: %s\r\n", + "x-frame-options: SAMEORIGIN\r\n", /* if it's error message, then it's HTML */ (responseNum != HTTP_OK ? "text/html" : found_mime_type) ); Description: The remote web server does not set an X-Frame-Options response header or a Content-Security-Policy 'frame-ancestors' response header in all content responses. This could potentially expose the site to a clickjacking or UI redress attack, in which an attacker can trick a user into clicking an area of the vulnerable page that is different than what the user perceives the page to be. This can result in a user performing fraudulent or malicious transactions. X-Frame-Options has been proposed by Microsoft as a way to mitigate clickjacking attacks and is currently supported by all major browser vendors. Content-Security-Policy (CSP) has been proposed by the W3C Web Application Security Working Group, with increasing support among all major browser vendors, as a way to mitigate clickjacking and other attacks. The 'frame-ancestors' policy directive restricts which sources can embed the protected resource. Note that while the X-Frame-Options and Content-Security-Policy response headers are not the only mitigations for clickjacking, they are currently the most reliable methods that can be detected through automation. Therefore, this plugin may produce false positives if other mitigation strategies (e.g., frame-busting JavaScript) are deployed or if the page does not perform any security-sensitive transactions. Remediation: Return the X-Frame-Options or Content-Security-Policy (with the 'frame-ancestors' directive) HTTP header with the page's response. This prevents the page's content from being rendered by another site when using the frame or iframe HTML tags. Reference: CWE:693 Best regards, Steffen Hamann -------------- next part -------------- An HTML attachment was scrubbed... URL: From andrej.picej at norik.com Tue Jul 11 08:42:49 2023 From: andrej.picej at norik.com (Andrej Picej) Date: Tue, 11 Jul 2023 10:42:49 +0200 Subject: [PATCH v2] hwclock: add get/set parameters option Message-ID: <20230711084249.721086-1-andrej.picej@norik.com> In kernel 5.16 special ioctls were introduced to get/set RTC parameters. Add option to get/set parameters into busybox version of hwclock. Implementation is similar to the one already used in linux-utils hwclock tool. Example of parameter get use: $ hwclock -g 2 The RTC parameter 0x2 is set to 0x2. $ hwclock --param-get bsm The RTC parameter 0x2 is set to 0x2. Example of parameter set use: $ hwclock -p 2=1 The RTC parameter 0x2 will be set to 0x1. $ hwclock -p bsm=2 The RTC parameter 0x2 will be set to 0x2. Signed-off-by: Andrej Picej --- Changes since v2: - use "strcmp() == 0" instead of "!strcmp()", - get rid of goto and just bb_error_msg_and_die(). --- include/rtc_.h | 23 +++++++++ util-linux/hwclock.c | 110 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 128 insertions(+), 5 deletions(-) diff --git a/include/rtc_.h b/include/rtc_.h index 24ff5363f..4b8d9fce3 100644 --- a/include/rtc_.h +++ b/include/rtc_.h @@ -22,6 +22,11 @@ int rtc_xopen(const char **default_rtc, int flags) FAST_FUNC; void rtc_read_tm(struct tm *ptm, int fd) FAST_FUNC; time_t rtc_tm2time(struct tm *ptm, int utc) FAST_FUNC; +struct hwclock_param { + int id; + const char *name; + const char *help; +}; /* * Everything below this point has been copied from linux/rtc.h @@ -46,6 +51,17 @@ struct linux_rtc_wkalrm { struct linux_rtc_time time; /* time the alarm is set to */ }; +struct rtc_param { + __u64 param; + union { + __u64 uvalue; + __s64 svalue; + __u64 ptr; + }; + __u32 index; + __u32 __pad; +}; + /* * ioctl calls that are permitted to the /dev/rtc interface, if * any of the RTC drivers are enabled. @@ -71,12 +87,19 @@ struct linux_rtc_wkalrm { #define RTC_WKALM_SET _IOW('p', 0x0f, struct linux_rtc_wkalrm)/* Set wakeup alarm*/ #define RTC_WKALM_RD _IOR('p', 0x10, struct linux_rtc_wkalrm)/* Get wakeup alarm*/ +#define RTC_PARAM_GET _IOW('p', 0x13, struct rtc_param) /* Get parameter */ +#define RTC_PARAM_SET _IOW('p', 0x14, struct rtc_param) /* Set parameter */ + /* interrupt flags */ #define RTC_IRQF 0x80 /* any of the following is active */ #define RTC_PF 0x40 #define RTC_AF 0x20 #define RTC_UF 0x10 +# define RTC_PARAM_FEATURES 0 +# define RTC_PARAM_CORRECTION 1 +# define RTC_PARAM_BACKUP_SWITCH_MODE 2 + POP_SAVED_FUNCTION_VISIBILITY #endif diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c index 723b09589..542081d63 100644 --- a/util-linux/hwclock.c +++ b/util-linux/hwclock.c @@ -48,6 +48,19 @@ # define LIBC_IS_MUSL 0 #endif +static const struct hwclock_param hwclock_params[] = +{ + { RTC_PARAM_FEATURES, "features", "supported features" }, + { RTC_PARAM_CORRECTION, "correction", "time correction" }, + { RTC_PARAM_BACKUP_SWITCH_MODE, "bsm", "backup switch mode" }, + { } +}; + +const struct hwclock_param *get_hwclock_params(void) +{ + return hwclock_params; +} + /* diff code is disabled: it's not sys/hw clock diff, it's some useless * "time between hwclock was started and we saw CMOS tick" quantity. @@ -320,6 +333,80 @@ static void from_sys_clock(const char **pp_rtcname, int utc) close(rtc); } +static int resolve_rtc_param_alias(const char *alias, __u64 *value) +{ + const struct hwclock_param *param = &hwclock_params[0]; + + while (param->name) { + if (strcmp(alias, param->name) == 0) { + *value = param->id; + return 0; + } + param++; + } + + return 1; +} + +static void get_rtc_param(const char **pp_rtcname, const char *rtc_param) +{ + int rtc; + struct rtc_param param = { .param = 0 }; + + if (resolve_rtc_param_alias(rtc_param, ¶m.param) != 0) { + param.param = bb_strtoull(rtc_param, NULL, 0); + if (errno) + bb_error_msg_and_die("could not convert parameter name: '%s' to number", rtc_param); + } + + rtc = rtc_xopen(pp_rtcname, O_RDONLY); + + xioctl(rtc, RTC_PARAM_GET, ¶m); + + printf("The RTC parameter 0x%jx is set to 0x%jx.\n", + (uintmax_t) param.param, (uintmax_t) param.uvalue); + + if (ENABLE_FEATURE_CLEAN_UP) + close(rtc); +} + +static void set_rtc_param(const char **pp_rtcname, const char *rtc_param) +{ + int rtc; + struct rtc_param param = { .param = 0 }; + char *tok, *opt = xstrdup(rtc_param); + + /* handle param name */ + tok = strtok(opt, "="); + if (resolve_rtc_param_alias(tok, ¶m.param) != 0) { + param.param = bb_strtoull(tok, NULL, 0); + if (errno) + bb_error_msg_and_die("could not convert parameter name: '%s' to number", + tok); + } + + /* handle param value */ + tok = strtok(NULL, "="); + if (!tok) + bb_error_msg_and_die("expected ="); + + param.uvalue = bb_strtoull(tok, NULL, 0); + if (errno) + bb_error_msg_and_die("could not convert parameter value to number"); + + rtc = rtc_xopen(pp_rtcname, O_WRONLY); + + printf("The RTC parameter 0x%jx will be set to 0x%jx.\n", + (uintmax_t) param.param, (uintmax_t) param.uvalue); + + xioctl(rtc, RTC_PARAM_SET, ¶m); + + if (ENABLE_FEATURE_CLEAN_UP) + close(rtc); + + free(opt); +} + // hwclock from util-linux 2.36.1 // hwclock [function] [option...] //Functions: @@ -346,10 +433,10 @@ static void from_sys_clock(const char **pp_rtcname, int utc) //usage:#define hwclock_trivial_usage //usage: IF_LONG_OPTS( -//usage: "[-swul] [--systz] [-f DEV]" +//usage: "[-swul] [--systz] [--param-get PARAM] [--param-set PARAM=VAL] [-f DEV]" //usage: ) //usage: IF_NOT_LONG_OPTS( -//usage: "[-swult] [-f DEV]" +//usage: "[-swult] [-g PARAM] [-p PARAM=VAL] [-f DEV]" //usage: ) //usage:#define hwclock_full_usage "\n\n" //usage: "Show or set hardware clock (RTC)\n" @@ -360,6 +447,8 @@ static void from_sys_clock(const char **pp_rtcname, int utc) //usage: IF_LONG_OPTS( //usage: "\n --systz Set in-kernel timezone, correct system time" //usage: "\n if RTC is kept in local time" +//usage: "\n --param-get PARAM Get RTC parameter" +//usage: "\n --param-set PARAM=VAL Set RTC parameter" //usage: ) //usage: "\n -f DEV Use specified device (e.g. /dev/rtc2)" //usage: "\n -u Assume RTC is kept in UTC" @@ -375,11 +464,14 @@ static void from_sys_clock(const char **pp_rtcname, int utc) #define HWCLOCK_OPT_SYSTOHC 0x10 #define HWCLOCK_OPT_SYSTZ 0x20 #define HWCLOCK_OPT_RTCFILE 0x40 +#define HWCLOCK_OPT_PARAM_GET 0x80 +#define HWCLOCK_OPT_PARAM_SET 0x100 int hwclock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int hwclock_main(int argc UNUSED_PARAM, char **argv) { const char *rtcname = NULL; + const char *param = NULL; unsigned opt; int utc; #if ENABLE_LONG_OPTS @@ -391,14 +483,18 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv) "systohc\0" No_argument "w" "systz\0" No_argument "t" /* short opt is non-standard */ "rtc\0" Required_argument "f" + "param-get\0" Required_argument "g" /* short opt is non-standard */ + "param-set\0" Required_argument "p" /* short opt is non-standard */ ; #endif opt = getopt32long(argv, - "^""lurswtf:v" /* -v is accepted and ignored */ + "^""lurswtf:g:p:v" /* -v is accepted and ignored */ "\0" - "r--wst:w--rst:s--wrt:t--rsw:l--u:u--l", + "r--wstgp:w--rstgp:s--wrtgp:t--rswgp:g--rswtp:p--rswtg:l--u:u--l", hwclock_longopts, - &rtcname + &rtcname, + ¶m, + ¶m ); /* If -u or -l wasn't given, check if we are using utc */ @@ -413,6 +509,10 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv) from_sys_clock(&rtcname, utc); else if (opt & HWCLOCK_OPT_SYSTZ) set_kernel_timezone_and_clock(utc, NULL); + else if (opt & HWCLOCK_OPT_PARAM_GET) + get_rtc_param(&rtcname, param); + else if (opt & HWCLOCK_OPT_PARAM_SET) + set_rtc_param(&rtcname, param); else /* default HWCLOCK_OPT_SHOW */ show_clock(&rtcname, utc); -- 2.25.1 From vda.linux at googlemail.com Wed Jul 12 14:28:48 2023 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Wed, 12 Jul 2023 16:28:48 +0200 Subject: [PATCH v2] hwclock: add get/set parameters option In-Reply-To: <20230711084249.721086-1-andrej.picej@norik.com> References: <20230711084249.721086-1-andrej.picej@norik.com> Message-ID: On Tue, Jul 11, 2023 at 10:43?AM Andrej Picej wrote: > --- a/include/rtc_.h > +++ b/include/rtc_.h > @@ -22,6 +22,11 @@ int rtc_xopen(const char **default_rtc, int flags) FAST_FUNC; > void rtc_read_tm(struct tm *ptm, int fd) FAST_FUNC; > time_t rtc_tm2time(struct tm *ptm, int utc) FAST_FUNC; > > +struct hwclock_param { > + int id; > + const char *name; > + const char *help; > +}; Can be in hwclock.c, its only user > /* > * Everything below this point has been copied from linux/rtc.h > @@ -46,6 +51,17 @@ struct linux_rtc_wkalrm { > struct linux_rtc_time time; /* time the alarm is set to */ > }; > > +struct rtc_param { > + __u64 param; > + union { > + __u64 uvalue; > + __s64 svalue; > + __u64 ptr; > + }; > + __u32 index; > + __u32 __pad; > +}; Should use uint64_t and such, noit kernel internal typedefs. > +static const struct hwclock_param hwclock_params[] = > +{ > + { RTC_PARAM_FEATURES, "features", "supported features" }, > + { RTC_PARAM_CORRECTION, "correction", "time correction" }, > + { RTC_PARAM_BACKUP_SWITCH_MODE, "bsm", "backup switch mode" }, > + { } > +}; help strings are unused. > +const struct hwclock_param *get_hwclock_params(void) > +{ > + return hwclock_params; > +} util-linux/hwclock.c:65:29: error: no previous prototype for ?get_hwclock_params? - unused function > +static void set_rtc_param(const char **pp_rtcname, const char *rtc_param) > +{ > + int rtc; > + struct rtc_param param = { .param = 0 }; Why zeroing? > + char *tok, *opt = xstrdup(rtc_param); Why strdup? Using the string in-place is more efficient > + > + /* handle param name */ > + tok = strtok(opt, "="); > + if (resolve_rtc_param_alias(tok, ¶m.param) != 0) { > + param.param = bb_strtoull(tok, NULL, 0); > + if (errno) > + bb_error_msg_and_die("could not convert parameter name: '%s' to number", > + tok); Duplicated code. Too verbose message. Can just use xstrtoull(): static uint64_t resolve_rtc_param_alias(const char *alias) { int n; BUILD_BUG_ON(RTC_PARAM_FEATURES != 0 || RTC_PARAM_CORRECTION != 1 || RTC_PARAM_BACKUP_SWITCH_MODE != 2 ); n = index_in_strings( "features" "\0" "correction" "\0" "bsm" "\0" , alias); if (n >= 0) return n; return xstrtoull(alias, 0); } > + } > + ) pulls in > + /* handle param value */ > + tok = strtok(NULL, "="); strtok() pulls in a global variable, increasing bss. > const char *param = NULL; Why zeroing? After addressing these, the size is twice as small: function old new delta hwclock_main 298 756 +458 .rodata 105231 105526 +295 strtok - 148 +148 hwclock_params - 48 +48 packed_usage 34541 34576 +35 static.hwclock_longopts 60 84 +24 static.p - 4 +4 ------------------------------------------------------------------------------ (add/remove: 4/0 grow/shrink: 4/0 up/down: 1012/0) Total: 1012 bytes function old new delta hwclock_main 298 584 +286 .rodata 105231 105400 +169 packed_usage 34541 34576 +35 static.hwclock_longopts 60 84 +24 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 4/0 up/down: 514/0) Total: 514 bytes From vda.linux at googlemail.com Sun Jul 16 12:55:42 2023 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sun, 16 Jul 2023 14:55:42 +0200 Subject: [PATCH] getfattr: new applet In-Reply-To: <20230707084424.215610-1-lovesykun@gmail.com> References: <60o69nqq-q3rs-qrs9-o10-8oo0r02q1s98@nqncgvir-ragrecevfrf.pbz> <20230707084424.215610-1-lovesykun@gmail.com> Message-ID: Applied, thank you. Please try current git. I would like to check how we do on errors. How to easily get getxattr error? Neither sysfs, procfs, nor devtmpfs throw errors on it. On Fri, Jul 7, 2023 at 10:45?AM LoveSy wrote: > > function old new delta > getfattr_main - 380 +380 > print_attr - 204 +204 > list_attr - 152 +152 > .rodata 95358 95401 +43 > applet_names 2766 2775 +9 > e843419 at 0048_000003ed_14 - 8 +8 > e843419 at 0047_000003d1_550 - 8 +8 > applet_main 3216 3224 +8 > packed_usage 34560 34567 +7 > applet_install_loc 201 202 +1 > ------------------------------------------------------------------------------ > (add/remove: 6/0 grow/shrink: 5/0 up/down: 820/0) Total: 820 bytes > text data bss dec hex filename > 1127717 16889 1736 1146342 117de6 busybox_old > 1141124 16937 1736 1159797 11b275 busybox_unstripped > > Signed-off-by: LoveSy > --- > Thansk for your review. Updated the patch. Please have a check. > > miscutils/getfattr.c | 121 +++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 121 insertions(+) > create mode 100644 miscutils/getfattr.c > > diff --git a/miscutils/getfattr.c b/miscutils/getfattr.c > new file mode 100644 > index 000000000..44556cb24 > --- /dev/null > +++ b/miscutils/getfattr.c > @@ -0,0 +1,121 @@ > +/* > + * getfattr - get extended attributes of filesystem objects. > + * > + * Copyright (C) 2023 by LoveSy > + * > + * Licensed under GPLv2, see file LICENSE in this source tree. > + */ > +//config:config GETFATTR > +//config: bool "getfattr (12.3 kb)" > +//config: default y > +//config: help > +//config: Get extended attributes on files > + > +//applet:IF_GETFATTR(APPLET_NOEXEC(getfattr, getfattr, BB_DIR_USR_BIN, BB_SUID_DROP, getfattr)) > + > +//kbuild:lib-$(CONFIG_GETFATTR) += getfattr.o > + > +#include > +#include > +#include "libbb.h" > + > +//usage:#define getfattr_trivial_usage > +//usage: "[-h] -n ATTR FILE...\n" > +//usage: "or: getfattr [-h] -d FILE..." > +//usage:#define getfattr_full_usage "\n\n" > +//usage: "Get extended attributes" > +//usage: "\n" > +//usage: "\n -h Do not follow symlinks" > +//usage: "\n -d Dump all attributes" > +//usage: "\n -n ATTR Get attribute ATTR" > +int getfattr_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; > + > +int print_attr(const char *file, const char *name, int follow, char **buf, size_t *bufsize) > +{ > + ssize_t len; > + len = (follow ? getxattr: lgetxattr)(file, name, NULL, 0); > + if (len == -1) { > + return -1; > + } > + if (*bufsize < len) { > + *buf = xrealloc(*buf, len); > + *bufsize = len; > + } > + len = (follow ? getxattr : lgetxattr)(file, name, *buf, *bufsize); > + if (len == -1) { > + return -1; > + } > + printf("%s=\"%.*s\"\n", name, len, *buf); > + return 0; > +} > + > +ssize_t list_attr(const char *file, int follow, char **list, size_t *listsize) > +{ > + ssize_t len; > + len = (follow ? listxattr : llistxattr)(file, NULL, 0); > + if (len == -1) { > + return -1; > + } > + if (*listsize < len) { > + *list = xrealloc(*list, len); > + *listsize = len; > + } > + len = (follow ? listxattr : llistxattr)(file, *list, *listsize); > + if (len == -1) { > + return -1; > + } > + return len; > +} > + > +int getfattr_main(int argc UNUSED_PARAM, char **argv) > +{ > + const char *name = NULL; > + int status; > + int opt; > + char *buf = NULL; > + size_t bufsize = 0; > + char *list = NULL; > + size_t listsize = 0; > + enum { > + OPT_h = (1 << 0), > + OPT_d = (1 << 1), > + }; > + > + opt = getopt32(argv, "^" > + "hdn:" > + /* Min one arg; exactly one of -n or -d is required. */ > + "\0" "-1:d:n:n--d:d--n" > + , &name > + ); > + argv += optind; > + status = EXIT_SUCCESS; > + > + do { > + int r = 0; > + printf("# file: %s\n", *argv); > + if (opt & OPT_d) { > + ssize_t len = list_attr(*argv, !(opt & OPT_h), &list, &listsize); > + ssize_t keylen; > + char *key = list; > + while (len > 0 && !r) { > + r = print_attr(*argv, key, !(opt & OPT_h), &buf, &bufsize); > + keylen = strlen(key) + 1; > + key += keylen; > + len -= keylen; > + } > + } > + else { > + r = print_attr(*argv, name, !(opt & OPT_h), &buf, &bufsize); > + } > + > + if (r) { > + bb_simple_perror_msg(*argv); > + status = EXIT_FAILURE; > + } > + printf("\n"); > + } while (*++argv); > + > + free(buf); > + > + return status; > +} > -- > 2.34.1 > > _______________________________________________ > busybox mailing list > busybox at busybox.net > http://lists.busybox.net/mailman/listinfo/busybox From dario.binacchi at amarulasolutions.com Tue Jul 18 07:41:45 2023 From: dario.binacchi at amarulasolutions.com (Dario Binacchi) Date: Tue, 18 Jul 2023 09:41:45 +0200 Subject: [PATCH] ip link: support for the CAN netlink Message-ID: <20230718074145.1651881-1-dario.binacchi@amarulasolutions.com> I developed this application to test the Linux kernel series [1]. As described in the cover letter I could not use the iproute2 package since the microcontroller is without MMU. cc: Marc Kleine-Budde [1] https://marc.info/?l=linux-netdev&m=167999323611710&w=2 Signed-off-by: Dario Binacchi --- configs/TEST_nommu_defconfig | 1 + networking/ip.c | 84 ++++++++++ networking/libiproute/iplink.c | 298 ++++++++++++++++++++++++++++++++- 3 files changed, 374 insertions(+), 9 deletions(-) diff --git a/configs/TEST_nommu_defconfig b/configs/TEST_nommu_defconfig index 415f5a8027f9..fa3e9632622a 100644 --- a/configs/TEST_nommu_defconfig +++ b/configs/TEST_nommu_defconfig @@ -703,6 +703,7 @@ CONFIG_FEATURE_INETD_RPC=y CONFIG_IP=y CONFIG_FEATURE_IP_ADDRESS=y CONFIG_FEATURE_IP_LINK=y +CONFIG_FEATURE_IP_LINK_CAN=y CONFIG_FEATURE_IP_ROUTE=y CONFIG_FEATURE_IP_TUNNEL=y CONFIG_FEATURE_IP_RULE=y diff --git a/networking/ip.c b/networking/ip.c index 36126b74738c..e5b704df5b85 100644 --- a/networking/ip.c +++ b/networking/ip.c @@ -32,6 +32,14 @@ //config: help //config: Short form of "ip link" //config: +//config:config IPLINK_CAN +//config: bool "iplink for CAN (4.6 kb)" +//config: default n +//config: depends on IPLINK +//config: select FEATURE_IP_LINK_CAN +//config: help +//config: Short form of "ip link" for CAN +//config: //config:config IPROUTE //config: bool "iproute (15 kb)" //config: default y @@ -74,6 +82,13 @@ //config: help //config: Configure network devices with "ip". //config: +//config:config FEATURE_IP_LINK_CAN +//config: bool "ip link can" +//config: default n +//config: depends on IP_LINK_CAN +//config: help +//config: Configure CAN devices with "ip". +//config: //config:config FEATURE_IP_ROUTE //config: bool "ip route" //config: default y @@ -122,6 +137,7 @@ //applet:IF_IP( APPLET_NOEXEC(ip , ip , BB_DIR_SBIN, BB_SUID_DROP, ip )) //applet:IF_IPADDR( APPLET_NOEXEC(ipaddr , ipaddr , BB_DIR_SBIN, BB_SUID_DROP, ipaddr )) //applet:IF_IPLINK( APPLET_NOEXEC(iplink , iplink , BB_DIR_SBIN, BB_SUID_DROP, iplink )) +//applet:IF_IPLINK_CAN(APPLET_NOEXEC(iplinkcan , iplinkcan , BB_DIR_SBIN, BB_SUID_DROP, iplinkcan)) //applet:IF_IPROUTE( APPLET_NOEXEC(iproute , iproute , BB_DIR_SBIN, BB_SUID_DROP, iproute )) //applet:IF_IPRULE( APPLET_NOEXEC(iprule , iprule , BB_DIR_SBIN, BB_SUID_DROP, iprule )) //applet:IF_IPTUNNEL(APPLET_NOEXEC(iptunnel, iptunnel, BB_DIR_SBIN, BB_SUID_DROP, iptunnel)) @@ -130,6 +146,7 @@ //kbuild:lib-$(CONFIG_IP) += ip.o //kbuild:lib-$(CONFIG_IPADDR) += ip.o //kbuild:lib-$(CONFIG_IPLINK) += ip.o +//kbuild:lib-$(CONFIG_IPLINK_CAN) += ip.o //kbuild:lib-$(CONFIG_IPROUTE) += ip.o //kbuild:lib-$(CONFIG_IPRULE) += ip.o //kbuild:lib-$(CONFIG_IPTUNNEL) += ip.o @@ -149,10 +166,16 @@ //usage: "ipaddr show|flush [dev IFACE] [scope SCOPE] [to PREFIX] [label PATTERN]" //usage: //--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79 +//usage:#if ENABLE_FEATURE_IP_LINK_CAN +//usage:#define iplink_type_usage "\n [type TYPE ARGS]" +//usage:#else +//usage:#define iplink_type_usage "" +//usage:#endif //usage:#define iplink_trivial_usage //usage: /*Usage:iplink*/"set IFACE [up|down] [arp on|off] [multicast on|off]\n" //usage: " [promisc on|off] [mtu NUM] [name NAME] [qlen NUM] [address MAC]\n" //usage: " [master IFACE | nomaster] [netns PID]" +//usage: IF_FEATURE_IP_LINK(iplink_type_usage) // * short help shows only "set" command, long help continues (with just one "\n") // * and shows all other commands: //usage:#define iplink_full_usage "\n" @@ -207,6 +230,59 @@ // bond_slave | ipvlan | geneve | bridge_slave | vrf } //usage: //--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79 +//usage:#define iplinkcan_trivial_usage +//usage: /*Usage:iplinkcan*/"set DEVICE type can" +//usage:#define iplinkcan_full_usage "\n\n" +//usage: " [bitrate BITRATE [sample-point SAMPLE-POINT]] |\n" +//usage: " [tq TQ prop-seg PROP_SEG phase-seg1 PHASE-SEG1\n" +//usage: " phase-seg2 PHASE-SEG2 [sjw SJW]]\n" +//usage: "\n" +//usage: " [dbitrate BITRATE [dsample-point SAMPLE-POINT]] |\n" +//usage: " [dtq TQ dprop-seg PROP_SEG dphase-seg1 PHASE-SEG1\n" +//usage: " dphase-seg2 PHASE-SEG2 [dsjw SJW]]\n" +//usage: "\n" +//usage: " [loopback on|off] [listen-only on|off] [triple-sampling on|off]\n" +//usage: " [one-shot on|off] [berr-reporting on|off]\n" +//usage: " [fd on|off] [fd-non-iso on|off] [presume-ack on|off]\n" +//usage: "\n" +//usage: " [restart-ms TIME-MS] [restart]\n" +//usage: "\n" +//usage: " [termination 0..65535]\n" +//usage: +//upstream man ip-link-can: +//Usage: ip link set DEVICE type can +// [ bitrate BITRATE [ sample-point SAMPLE-POINT] ] | +// [ tq TQ prop-seg PROP_SEG phase-seg1 PHASE-SEG1 +// phase-seg2 PHASE-SEG2 [ sjw SJW ] ] +// +// [ dbitrate BITRATE [ dsample-point SAMPLE-POINT] ] | +// [ dtq TQ dprop-seg PROP_SEG dphase-seg1 PHASE-SEG1 +// dphase-seg2 PHASE-SEG2 [ dsjw SJW ] ] +// +// [ loopback { on | off } ] +// [ listen-only { on | off } ] +// [ triple-sampling { on | off } ] +// [ one-shot { on | off } ] +// [ berr-reporting { on | off } ] +// [ fd { on | off } ] +// [ fd-non-iso { on | off } ] +// [ presume-ack { on | off } ] +// +// [ restart-ms TIME-MS ] +// [ restart ] +// +// [ termination { 0..65535 } ] +// +// Where: BITRATE := { 1..1000000 } +// SAMPLE-POINT := { 0.000..0.999 } +// TQ := { NUMBER } +// PROP-SEG := { 1..8 } +// PHASE-SEG1 := { 1..8 } +// PHASE-SEG2 := { 1..8 } +// SJW := { 1..4 } +// RESTART-MS := { 0 | NUMBER } +//usage: +//--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79 //usage:#define iproute_trivial_usage //usage: "list|flush|add|del|change|append|replace|test ROUTE" //usage:#define iproute_full_usage "\n\n" @@ -327,6 +403,7 @@ typedef int FAST_FUNC (*ip_func_ptr_t)(char**); #if ENABLE_IPADDR \ || ENABLE_IPLINK \ + || ENABLE_IPLINK_CAN \ || ENABLE_IPROUTE \ || ENABLE_IPRULE \ || ENABLE_IPTUNNEL \ @@ -352,6 +429,13 @@ int iplink_main(int argc UNUSED_PARAM, char **argv) return ip_do(do_iplink, argv); } #endif +#if ENABLE_IPLINK_CAN +int iplinkcan_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int iplinkcan_main(int argc UNUSED_PARAM, char **argv) +{ + return ip_do(do_iplink, argv); +} +#endif #if ENABLE_IPROUTE int iproute_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int iproute_main(int argc UNUSED_PARAM, char **argv) diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c index 9eb0b4f5f118..c3be54f841dd 100644 --- a/networking/libiproute/iplink.c +++ b/networking/libiproute/iplink.c @@ -11,10 +11,17 @@ #include #include +#include #include "ip_common.h" /* #include "libbb.h" is inside */ #include "rt_names.h" #include "utils.h" +#if ENABLE_FEATURE_IP_LINK_CAN +#define ENABLE_FEATURE_IP_LINK_IFACE 1 +#else +#define ENABLE_FEATURE_IP_LINK_IFACE 0 +#endif + #undef ETH_P_8021AD #define ETH_P_8021AD 0x88A8 #undef VLAN_FLAG_REORDER_HDR @@ -28,6 +35,11 @@ #undef IFLA_VLAN_PROTOCOL #define IFLA_VLAN_PROTOCOL 5 +#ifndef NLMSG_TAIL +#define NLMSG_TAIL(nmsg) \ + ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) +#endif + #ifndef IFLA_LINKINFO # define IFLA_LINKINFO 18 # define IFLA_INFO_KIND 1 @@ -55,6 +67,13 @@ struct ifla_vlan_flags { #define str_on_off "on\0""off\0" +enum { + PARM_on = 0, + PARM_off +}; + +typedef void FAST_FUNC(*ip_type_set_func_ptr_t)(char*, char**); + /* Exits on error */ static int get_ctl_fd(void) { @@ -241,10 +260,261 @@ static void die_must_be_on_off(const char *msg) bb_error_msg_and_die("argument of \"%s\" must be \"on\" or \"off\"", msg); } +#if ENABLE_FEATURE_IP_LINK_CAN +static float FAST_FUNC get_float(char *arg, const char *errmsg) +{ + float ret; + char *ptr; + + if (!arg || !*arg) + invarg_1_to_2(arg, errmsg); /* does not return */ + + ret = strtof(arg, &ptr); + if (!ptr || ptr == arg || *ptr) + invarg_1_to_2(arg, errmsg); /* does not return */ + + return ret; +} + +static void do_set_can(char *dev, char **argv) +{ + struct can_bittiming bt = {}, dbt = {}; + struct can_ctrlmode cm = {}; + char *keyword; + static const char keywords[] ALIGN1 = + "bitrate\0""sample-point\0""tq\0" + "prop-seg\0""phase-seg1\0""phase-seg2\0""sjw\0" + "dbitrate\0""dsample-point\0""dtq\0" + "dprop-seg\0""dphase-seg1\0""dphase-seg2\0""dsjw\0" + "loopback\0""listen-only\0""triple-sampling\0" + "one-shot\0""berr-reporting\0" + "fd\0""fd-non-iso\0""presume-ack\0" + "cc-len8-dlc\0""restart\0""restart-ms\0" + "termination\0"; + enum { ARG_bitrate = 0, ARG_sample_point, ARG_tq, + ARG_prop_seg, ARG_phase_seg1, ARG_phase_seg2, ARG_sjw, + ARG_dbitrate, ARG_dsample_point, ARG_dtq, + ARG_dprop_seg, ARG_dphase_seg1, ARG_dphase_seg2, ARG_dsjw, + ARG_loopback, ARG_listen_only, ARG_triple_sampling, + ARG_one_shot, ARG_berr_reporting, + ARG_fd, ARG_fd_non_iso, ARG_presume_ack, + ARG_cc_len8_dlc, ARG_restart, ARG_restart_ms, + ARG_termination }; + struct rtnl_handle rth; + struct { + struct nlmsghdr n; + struct ifinfomsg i; + char buf[1024]; + } req; + size_t dev_len; + struct rtattr *linkinfo, *data; + smalluint key, param; + + memset(&req, 0, sizeof(req)); + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + req.n.nlmsg_flags = NLM_F_REQUEST; + req.n.nlmsg_type = RTM_NEWLINK; + req.i.ifi_family = preferred_family; + xrtnl_open(&rth); + req.i.ifi_index = xll_name_to_index(dev); + dev_len = strlen(dev); + if (dev_len < 2 || dev_len > IFNAMSIZ) + invarg_1_to_2(dev, "dev"); + + addattr_l(&req.n, sizeof(req), IFLA_IFNAME, dev, dev_len); + linkinfo = NLMSG_TAIL(&req.n); + addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0); + addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, (void *)"can", + strlen("can")); + data = NLMSG_TAIL(&req.n); + addattr_l(&req.n, sizeof(req), IFLA_INFO_DATA, NULL, 0); + while (*argv) { + key = index_in_substrings(keywords, *argv); + keyword = *argv; + //printf("%s: key: %d, *argv: %s\n", __func__, key, *argv); + switch (key) { + case ARG_bitrate: + case ARG_tq: + case ARG_prop_seg: + case ARG_phase_seg1: + case ARG_phase_seg2: + case ARG_sjw: { + __u32 *val; + + NEXT_ARG(); + if (key == ARG_bitrate) + val = &bt.bitrate; + else if (key == ARG_tq) + val = &bt.tq; + else if (key == ARG_prop_seg) + val = &bt.prop_seg; + else if (key == ARG_phase_seg1) + val = &bt.phase_seg1; + else if (key == ARG_phase_seg2) + val = &bt.phase_seg2; + else + val = &bt.sjw; + + *val = get_u32(*argv, keyword); + break; + } + case ARG_sample_point: { + float sp; + + NEXT_ARG(); + sp = get_float(*argv, keyword); + bt.sample_point = (__u32)(sp * 1000); + break; + } + case ARG_dbitrate: + case ARG_dtq: + case ARG_dprop_seg: + case ARG_dphase_seg1: + case ARG_dphase_seg2: + case ARG_dsjw: { + __u32 *val; + + NEXT_ARG(); + if (key == ARG_dbitrate) + val = &dbt.bitrate; + else if (key == ARG_dtq) + val = &dbt.tq; + else if (key == ARG_dprop_seg) + val = &dbt.prop_seg; + else if (key == ARG_dphase_seg1) + val = &dbt.phase_seg1; + else if (key == ARG_dphase_seg2) + val = &dbt.phase_seg2; + else + val = &dbt.sjw; + + *val = get_u32(*argv, keyword); + break; + } + case ARG_dsample_point: { + float sp; + + NEXT_ARG(); + sp = get_float(*argv, keyword); + dbt.sample_point = (__u32)(sp * 1000); + break; + } + case ARG_loopback: + case ARG_listen_only: + case ARG_triple_sampling: + case ARG_one_shot: + case ARG_berr_reporting: + case ARG_fd: + case ARG_fd_non_iso: + case ARG_presume_ack: + case ARG_cc_len8_dlc: { + __u32 flag = 0; + + NEXT_ARG(); + param = index_in_strings(str_on_off, *argv); + if (param < 0) + die_must_be_on_off(keyword); + + if (key == ARG_loopback) + flag = CAN_CTRLMODE_LOOPBACK; + else if (key == ARG_listen_only) + flag = CAN_CTRLMODE_LISTENONLY; + else if (key == ARG_triple_sampling) + flag = CAN_CTRLMODE_3_SAMPLES; + else if (key == ARG_one_shot) + flag = CAN_CTRLMODE_ONE_SHOT; + else if (key == ARG_berr_reporting) + flag = CAN_CTRLMODE_BERR_REPORTING; + else if (key == ARG_fd) + flag = CAN_CTRLMODE_FD; + else if (key == ARG_fd_non_iso) + flag = CAN_CTRLMODE_FD_NON_ISO; + else if (key == ARG_presume_ack) + flag = CAN_CTRLMODE_PRESUME_ACK; + else +#if defined(CAN_CTRLMODE_CC_LEN8_DLC) + flag = CAN_CTRLMODE_CC_LEN8_DLC; +#else + die_must_be_on_off(keyword); +#endif + cm.mask |= flag; + if (param == PARM_on) + cm.flags |= flag; + + break; + } + case ARG_restart: { + __u32 val = 1; + + NEXT_ARG(); + addattr_l(&req.n, sizeof(req), IFLA_CAN_RESTART, &val, sizeof(val)); + break; + } + case ARG_restart_ms: { + __u32 val; + + NEXT_ARG(); + val = get_u32(*argv, keyword); + addattr_l(&req.n, sizeof(req), IFLA_CAN_RESTART_MS, &val, sizeof(val)); + break; + } + case ARG_termination: { + __u16 val; + + NEXT_ARG(); + val = get_u16(*argv, keyword); + addattr_l(&req.n, sizeof(req), IFLA_CAN_TERMINATION, &val, sizeof(val)); + break; + } + default: + break; + } + + argv++; + } + + if (bt.bitrate || bt.tq) + addattr_l(&req.n, sizeof(req), IFLA_CAN_BITTIMING, &bt, sizeof(bt)); + + if (cm.mask) + addattr_l(&req.n, sizeof(req), IFLA_CAN_CTRLMODE, &cm, sizeof(cm)); + + data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data; + linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo; + + if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) + xfunc_die(); +} +#endif + +#if ENABLE_FEATURE_IP_LINK_IFACE +static void do_set_iface(char *type, char *dev, char **argv) +{ + static const char keywords[] ALIGN1 = "" + IF_FEATURE_IP_LINK_CAN("can\0") + ; + static const ip_type_set_func_ptr_t funcs[] ALIGN_PTR = { + IF_FEATURE_IP_LINK_CAN(do_set_can,) + }; + ip_type_set_func_ptr_t func; + int key; + + key = index_in_substrings(keywords, type); + if (key < 0) + return; + func = funcs[key]; + func(dev, argv); +} +#endif + /* Return value becomes exitcode. It's okay to not return at all */ static int do_set(char **argv) { char *dev = NULL; +#if ENABLE_FEATURE_IP_LINK_IFACE + char *type = NULL; +#endif uint32_t mask = 0; uint32_t flags = 0; int qlen = -1; @@ -261,18 +531,24 @@ static int do_set(char **argv) "up\0""down\0""name\0""mtu\0""qlen\0""multicast\0" "arp\0""promisc\0""address\0""netns\0" "master\0""nomaster\0" +#if ENABLE_FEATURE_IP_LINK_IFACE + "type\0" +#endif "dev\0" /* must be last */; enum { ARG_up = 0, ARG_down, ARG_name, ARG_mtu, ARG_qlen, ARG_multicast, ARG_arp, ARG_promisc, ARG_addr, ARG_netns, ARG_master, ARG_nomaster, +#if ENABLE_FEATURE_IP_LINK_IFACE + ARG_type, +#endif ARG_dev }; - enum { PARM_on = 0, PARM_off }; smalluint key; while (*argv) { /* substring search ensures that e.g. "addr" and "address" * are both accepted */ key = index_in_substrings(keywords, *argv); + //printf("%s: key: %d, *argv: %s\n", __func__, key, *argv); if (key == ARG_up) { mask |= IFF_UP; flags |= IFF_UP; @@ -304,6 +580,13 @@ static int do_set(char **argv) } else if (key == ARG_netns) { NEXT_ARG(); netns = get_unsigned(*argv, "netns"); +#if ENABLE_FEATURE_IP_LINK_IFACE + } else if (key == ARG_type) { + NEXT_ARG(); + type = *argv; + argv++; + break; +#endif } else if (key >= ARG_dev) { /* ^^^^^^ ">=" here results in "dev IFACE" treated as default */ if (key == ARG_dev) { @@ -311,6 +594,7 @@ static int do_set(char **argv) } if (dev) duparg2("dev", *argv); + dev = *argv; } else { /* "on|off" options */ @@ -496,6 +780,10 @@ static int do_set(char **argv) } if (mask) do_chflags(dev, flags, mask); +#if ENABLE_FEATURE_IP_LINK_IFACE + if (type) + do_set_iface(type, dev, argv); +#endif return 0; } @@ -531,10 +819,6 @@ static void vlan_parse_opt(char **argv, struct nlmsghdr *n, unsigned int size) PROTO_8021Q = 0, PROTO_8021AD, }; - enum { - PARM_on = 0, - PARM_off - }; int arg; uint16_t id, proto; struct ifla_vlan_flags flags = {}; @@ -610,10 +894,6 @@ static void vrf_parse_opt(char **argv, struct nlmsghdr *n, unsigned int size) addattr_l(n, size, IFLA_VRF_TABLE, &table, sizeof(table)); } -#ifndef NLMSG_TAIL -#define NLMSG_TAIL(nmsg) \ - ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) -#endif /* Return value becomes exitcode. It's okay to not return at all */ static int do_add_or_delete(char **argv, const unsigned rtm) { -- 2.34.1 From andrej.picej at norik.com Tue Jul 18 09:10:26 2023 From: andrej.picej at norik.com (Andrej Picej) Date: Tue, 18 Jul 2023 11:10:26 +0200 Subject: [PATCH v2] hwclock: add get/set parameters option In-Reply-To: References: <20230711084249.721086-1-andrej.picej@norik.com> Message-ID: <0eeb0d49-4f40-078c-00be-5cf7addcec32@norik.com> Hi Denys, On 12. 07. 23 16:28, Denys Vlasenko wrote: > On Tue, Jul 11, 2023 at 10:43?AM Andrej Picej wrote: >> --- a/include/rtc_.h >> +++ b/include/rtc_.h >> @@ -22,6 +22,11 @@ int rtc_xopen(const char **default_rtc, int flags) FAST_FUNC; >> void rtc_read_tm(struct tm *ptm, int fd) FAST_FUNC; >> time_t rtc_tm2time(struct tm *ptm, int utc) FAST_FUNC; >> >> +struct hwclock_param { >> + int id; >> + const char *name; >> + const char *help; >> +}; > > Can be in hwclock.c, its only user > >> /* >> * Everything below this point has been copied from linux/rtc.h >> @@ -46,6 +51,17 @@ struct linux_rtc_wkalrm { >> struct linux_rtc_time time; /* time the alarm is set to */ >> }; >> >> +struct rtc_param { >> + __u64 param; >> + union { >> + __u64 uvalue; >> + __s64 svalue; >> + __u64 ptr; >> + }; >> + __u32 index; >> + __u32 __pad; >> +}; > > Should use uint64_t and such, noit kernel internal typedefs. > >> +static const struct hwclock_param hwclock_params[] = >> +{ >> + { RTC_PARAM_FEATURES, "features", "supported features" }, >> + { RTC_PARAM_CORRECTION, "correction", "time correction" }, >> + { RTC_PARAM_BACKUP_SWITCH_MODE, "bsm", "backup switch mode" }, >> + { } >> +}; > > help strings are unused. > >> +const struct hwclock_param *get_hwclock_params(void) >> +{ >> + return hwclock_params; >> +} > > util-linux/hwclock.c:65:29: error: no previous prototype for > ?get_hwclock_params? > > - unused function > >> +static void set_rtc_param(const char **pp_rtcname, const char *rtc_param) >> +{ >> + int rtc; >> + struct rtc_param param = { .param = 0 }; > > Why zeroing? > >> + char *tok, *opt = xstrdup(rtc_param); > > Why strdup? Using the string in-place is more efficient > >> + >> + /* handle param name */ >> + tok = strtok(opt, "="); >> + if (resolve_rtc_param_alias(tok, ¶m.param) != 0) { >> + param.param = bb_strtoull(tok, NULL, 0); >> + if (errno) >> + bb_error_msg_and_die("could not convert parameter name: '%s' to number", >> + tok); > > Duplicated code. Too verbose message. Can just use xstrtoull(): > > static uint64_t resolve_rtc_param_alias(const char *alias) > { > int n; > > BUILD_BUG_ON(RTC_PARAM_FEATURES != 0 > || RTC_PARAM_CORRECTION != 1 > || RTC_PARAM_BACKUP_SWITCH_MODE != 2 > ); > n = index_in_strings( > "features" "\0" > "correction" "\0" > "bsm" "\0" > , alias); > if (n >= 0) > return n; > return xstrtoull(alias, 0); > } > > >> + } >> + > ) pulls in > + /* handle param value */ >> + tok = strtok(NULL, "="); > > strtok() pulls in a global variable, increasing bss. > >> const char *param = NULL; > > Why zeroing? > > > After addressing these, the size is twice as small: > > function old new delta > hwclock_main 298 756 +458 > .rodata 105231 105526 +295 > strtok - 148 +148 > hwclock_params - 48 +48 > packed_usage 34541 34576 +35 > static.hwclock_longopts 60 84 +24 > static.p - 4 +4 > ------------------------------------------------------------------------------ > (add/remove: 4/0 grow/shrink: 4/0 up/down: 1012/0) Total: 1012 bytes > > > function old new delta > hwclock_main 298 584 +286 > .rodata 105231 105400 +169 > packed_usage 34541 34576 +35 > static.hwclock_longopts 60 84 +24 > ------------------------------------------------------------------------------ > (add/remove: 0/0 grow/shrink: 4/0 up/down: 514/0) Total: 514 bytes First of all sorry for late answer, I was quite busy the last week. Just as I wanted to analyse your comments and prepare a v2 I saw that you already fixed what was necessary and applied the patch. Thanks for that. Next time I'll check the size and optimize the code. Best regards, Andrej From roberto.foglietta at gmail.com Fri Jul 21 19:39:57 2023 From: roberto.foglietta at gmail.com (Roberto A. Foglietta) Date: Fri, 21 Jul 2023 21:39:57 +0200 Subject: Proposal for a new applet: strings Message-ID: To the maintainers and everyone else whom can be interested, today I developed for a mobile device running a Linux kernel and related GNU system (almost) a quite promising version of 'strings' faster than the original and giving out the same output with the same syntax. Good for me! I hope it will be good enough for you also. However, before starting the integration with busybox I wish to know if this applet and/or its implementation or an improved one, would have a good chance and appreciation to enter in the busybox development stream. Here in the attachment I put the .c file in GPLv2, like busybox. In its header just a raw estimation of its performance that can vary from system to system and among different platforms but at least comparable with the original from binutils. Best regards, R- -------------- next part -------------- A non-text attachment was scrubbed... Name: strings.c Type: text/x-csrc Size: 3239 bytes Desc: not available URL: From farmatito at tiscali.it Fri Jul 21 20:32:19 2023 From: farmatito at tiscali.it (tito) Date: Fri, 21 Jul 2023 22:32:19 +0200 Subject: Proposal for a new applet: strings In-Reply-To: References: Message-ID: <20230721223219.508ece1e@devuan> On Fri, 21 Jul 2023 21:39:57 +0200 "Roberto A. Foglietta" wrote: > To the maintainers and everyone else whom can be interested, > > today I developed for a mobile device running a Linux kernel and > related GNU system (almost) a quite promising version of 'strings' > faster than the original and giving out the same output with the same > syntax. Good for me! > > I hope it will be good enough for you also. However, before starting > the integration with busybox I wish to know if this applet and/or its > implementation or an improved one, would have a good chance and > appreciation to enter in the busybox development stream. > > Here in the attachment I put the .c file in GPLv2, like busybox. In > its header just a raw estimation of its performance that can vary from > system to system and among different platforms but at least comparable > with the original from binutils. > > Best regards, R- Hi, seems to me that the current strings busybox implementation is faster. tito at devuan:~/Desktop$ time ./strings vmlinux.o > out.txt real 0m0.369s user 0m0.365s sys 0m0.004s tito at devuan:~/Desktop$ time ./busybox strings vmlinux.o > out1.txt real 0m0.289s user 0m0.277s sys 0m0.012s tito at devuan:~/Desktop$ rm out*.txt tito at devuan:~/Desktop$ time ./strings vmlinux.o > out.txt real 0m0.355s user 0m0.347s sys 0m0.008s tito at devuan:~/Desktop$ time ./busybox strings vmlinux.o > out1.txt real 0m0.291s user 0m0.286s sys 0m0.004s tito at devuan:~/Desktop$ rm out*.txt tito at devuan:~/Desktop$ time ./strings vmlinux.o > out.txt real 0m0.356s user 0m0.335s sys 0m0.020s tito at devuan:~/Desktop$ time ./busybox strings vmlinux.o > out1.txt real 0m0.291s user 0m0.274s sys 0m0.016s Ciao, Tito From karabaja4 at gmail.com Fri Jul 21 21:15:56 2023 From: karabaja4 at gmail.com (=?UTF-8?B?SWdvciDFoGFyacSH?=) Date: Fri, 21 Jul 2023 23:15:56 +0200 Subject: ash builtin sleep behavior Message-ID: Hello, I posted a description with an example script of this issue to the Busybox bug tracker: https://bugs.busybox.net/show_bug.cgi?id=15694 Essentially, builtin ash sleep command is behaving differently than /bin/sleep, but I can't explain it. I appreciate any insights. Regards, Igor -------------- next part -------------- An HTML attachment was scrubbed... URL: From roberto.foglietta at gmail.com Sat Jul 22 01:36:52 2023 From: roberto.foglietta at gmail.com (Roberto A. Foglietta) Date: Sat, 22 Jul 2023 03:36:52 +0200 Subject: Proposal for a new applet: strings In-Reply-To: <20230721223219.508ece1e@devuan> References: <20230721223219.508ece1e@devuan> Message-ID: On Fri, 21 Jul 2023 at 22:37, tito wrote: > > On Fri, 21 Jul 2023 21:39:57 +0200 > "Roberto A. Foglietta" wrote: > > > To the maintainers and everyone else whom can be interested, > > [...] > > Hi, > seems to me that the current strings busybox implementation is faster. > [...] @Tito, first of all thanks for the test. The 'strings' applet into busybox is good enough for me and moreover, it is not about performance. The busybox installed into the system can theoretically be replaced but adding the only thing I am missing is easier. For my personal needs, this thread could be ended here. Just for sake of completeness, I took some tests too. There are several ways to use 'strings' and they belong to a matrix of 2x3 cases in:{file, stdin} X out:{file, stdout, /dev/null}. We can agree about the stdin case that the time of completion greatly depends on the way in which stdin feeds the command and among many ways the 'cat' is probably the most typical. Another aspect that can change the performances is about pre-compiled VS locally-compiled binaries. Therefore, the standard pre-compiled busybox has been introduced into the tests which finally create a 4 dimensions matrix like this {gnu strings, system busybox, compiled busybox, compiled strings} x :{file, stdin} X out:{file, stdout, /dev/null}. Finally, we need a test function with parameters and a basic but reasonably accurate average calculation. Using this function over the above 4D matrix, I am feeling confident in saying that: 1. there is no difference between pre-compiled and locally-compiled busybox 2. the busybox strings is as fast as GNU strings 3. the code I sent is on average 2x faster 4. the code I sent worst case is just 23% slower of the best of the others 3 cases 5. the code I sent best case is above 4x faster than the best of the others 3 cases Here below all the information to replicate the test on different systems and architectures. cat /proc/cpuinfo | grep "model name" | tail -n1 model name : Intel(R) Core(TM) i5-8350U CPU @ 1.70GHz GNOME Terminal Version 3.44.0 for GNOME 42 Using VTE version 0.68.0 +BIDI +GNUTLS +ICU +SYSTEMD stats() { rm -f t.time local cmd=${1:-/usr/bin/busybox strings /usr/bin/busybox} n=${2:-100} for i in $(seq 1 $n); do eval time $cmd; done 2>t.time { echo echo "$cmd" sed -ne "s,real\t,min: ,p" t.time | sort -n | head -n1 let avg=$(sed -ne "s,real\t0m0.[0]*\([0-9]*\)s,\\1,p" t.time | tr '\n' '+')0 printf "avg: 0m0.%03ds\n" $(( (50+$avg)/100 )) sed -ne "s,real\t,max: ,p" t.time | sort -n | tail -n1 } >&2 } ============= /usr/bin/busybox | head -n1 BusyBox v1.30.1 (Ubuntu 1:1.30.1-7ubuntu3) multi-call binary. rm -f 1.txt; cmd="/usr/bin/busybox strings /usr/bin/busybox"; stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt /usr/bin/busybox strings /usr/bin/busybox min: 0m0.067s avg: 0m0.090s max: 0m0.134s /usr/bin/busybox strings /usr/bin/busybox min: 0m0.013s avg: 0m0.013s max: 0m0.016s /usr/bin/busybox strings /usr/bin/busybox min: 0m0.013s avg: 0m0.014s max: 0m0.018s rm -f 1.txt; cmd="cat /usr/bin/busybox | /usr/bin/busybox strings"; stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt cat /usr/bin/busybox | /usr/bin/busybox strings min: 0m0.072s avg: 0m0.095s max: 0m0.141s cat /usr/bin/busybox | /usr/bin/busybox strings min: 0m0.021s avg: 0m0.022s max: 0m0.026s cat /usr/bin/busybox | /usr/bin/busybox strings min: 0m0.021s avg: 0m0.022s max: 0m0.025s ============= ./busybox | head -n1 BusyBox v1.37.0.git (2023-07-21 15:06:26 CEST) multi-call binary. gcc --version | head -n1 gcc (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0 rm -f 1.txt; cmd="./busybox strings /usr/bin/busybox"; stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.tx ./busybox strings /usr/bin/busybox min: 0m0.064s avg: 0m0.089s max: 0m0.123s ./busybox strings /usr/bin/busybox min: 0m0.014s avg: 0m0.014s max: 0m0.016s ./busybox strings /usr/bin/busybox min: 0m0.014s avg: 0m0.014s max: 0m0.016s rm -f 1.txt; cmd="cat /usr/bin/busybox | ./busybox strings"; stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt cat /usr/bin/busybox | ./busybox strings min: 0m0.075s avg: 0m0.098s max: 0m0.148s cat /usr/bin/busybox | ./busybox strings min: 0m0.022s avg: 0m0.023s max: 0m0.033s cat /usr/bin/busybox | ./busybox strings min: 0m0.023s avg: 0m0.023s max: 0m0.027s ============= gcc -Wall -O3 strings.c -o strings && strip strings gcc --version | head -n1 gcc (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0 rm -f 1.txt; cmd="../redfishos/recovery/strings /usr/bin/busybox"; stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt ../redfishos/recovery/strings /usr/bin/busybox min: 0m0.015s avg: 0m0.040s max: 0m0.079s ../redfishos/recovery/strings /usr/bin/busybox min: 0m0.009s avg: 0m0.009s max: 0m0.010s ../redfishos/recovery/strings /usr/bin/busybox min: 0m0.009s avg: 0m0.010s max: 0m0.021s rm -f 1.txt; cmd="cat /usr/bin/busybox | ../redfishos/recovery/strings strings"; stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt cat /usr/bin/busybox | ../redfishos/recovery/strings min: 0m0.041s avg: 0m0.050s max: 0m0.082s cat /usr/bin/busybox | ../redfishos/recovery/strings min: 0m0.017s avg: 0m0.017s max: 0m0.019s cat /usr/bin/busybox | ../redfishos/recovery/strings min: 0m0.017s avg: 0m0.017s max: 0m0.024s ============= strings --version | head -n1 GNU strings (GNU Binutils for Ubuntu) 2.38 rm -f 1.txt; cmd="strings /usr/bin/busybox"; stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt strings /usr/bin/busybox min: 0m0.073s avg: 0m0.097s max: 0m0.136s strings /usr/bin/busybox min: 0m0.020s avg: 0m0.021s max: 0m0.024s strings /usr/bin/busybox min: 0m0.021s avg: 0m0.021s max: 0m0.026s rm -f 1.txt; cmd="cat /usr/bin/busybox | strings"; stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt cat /usr/bin/busybox | strings min: 0m0.077s avg: 0m0.103s max: 0m0.140s cat /usr/bin/busybox | strings min: 0m0.029s avg: 0m0.029s max: 0m0.039s cat /usr/bin/busybox | strings min: 0m0.029s avg: 0m0.029s max: 0m0.037s From roberto.foglietta at gmail.com Sat Jul 22 02:10:31 2023 From: roberto.foglietta at gmail.com (Roberto A. Foglietta) Date: Sat, 22 Jul 2023 04:10:31 +0200 Subject: Proposal for a new applet: strings In-Reply-To: References: <20230721223219.508ece1e@devuan> Message-ID: On Sat, 22 Jul 2023 at 03:36, Roberto A. Foglietta wrote: > > On Fri, 21 Jul 2023 at 22:37, tito wrote: > > > > On Fri, 21 Jul 2023 21:39:57 +0200 > > "Roberto A. Foglietta" wrote: [...] ERRATA CORRIGE > rm -f 1.txt; cmd="cat /usr/bin/busybox | ../redfishos/recovery/strings strings"; > stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt The first row above is wrong, it should be rm -f 1.txt; cmd="cat /usr/bin/busybox | ../redfishos/recovery/strings"; However looking at the results, it was used correctly in the tests: > > cat /usr/bin/busybox | ../redfishos/recovery/strings > min: 0m0.041s > avg: 0m0.050s > max: 0m0.082s > Simply, I did not update my notes after having fixed it on the command line. Here below a quick test suite for 4 meaningful cases: bbcmd=$(which busybox) rm -f 1.txt; cmd="$bbcmd strings $bbcmd"; stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt rm -f 1.txt; cmd="cat $bbcmd | $bbcmd strings"; stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt rm -f 1.txt; cmd="./strings $bbcmd"; stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt rm -f 1.txt; cmd="cat $bbcmd | ./strings"; stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt You can easily replace the system busybox with your compiled version. Finally, the stats() functions should use tmpfile=$(mktemp) instead of t.time, just in case someone wishes to adopt it for general use. In this case it is (c) 2023, me under GPLv2, as well. From farmatito at tiscali.it Sat Jul 22 06:02:01 2023 From: farmatito at tiscali.it (tito) Date: Sat, 22 Jul 2023 08:02:01 +0200 Subject: Proposal for a new applet: strings In-Reply-To: References: <20230721223219.508ece1e@devuan> Message-ID: <20230722080201.32b21e94@devuan> On Sat, 22 Jul 2023 03:36:52 +0200 "Roberto A. Foglietta" wrote: > On Fri, 21 Jul 2023 at 22:37, tito wrote: > > > > On Fri, 21 Jul 2023 21:39:57 +0200 > > "Roberto A. Foglietta" wrote: > > > > > To the maintainers and everyone else whom can be interested, > > > > [...] > > > > Hi, > > seems to me that the current strings busybox implementation is faster. > > > [...] > > @Tito, first of all thanks for the test. > > The 'strings' applet into busybox is good enough for me and moreover, > it is not about performance. The busybox installed into the system can > theoretically be replaced but adding the only thing I am missing is > easier. For my personal needs, this thread could be ended here. > > Just for sake of completeness, I took some tests too. There are > several ways to use 'strings' and they belong to a matrix of 2x3 cases > in:{file, stdin} X out:{file, stdout, /dev/null}. > > We can agree about the stdin case that the time of completion greatly > depends on the way in which stdin feeds the command and among many > ways the 'cat' is probably the most typical. Another aspect that can > change the performances is about pre-compiled VS locally-compiled > binaries. Therefore, the standard pre-compiled busybox has been > introduced into the tests which finally create a 4 dimensions matrix > like this {gnu strings, system busybox, compiled busybox, compiled > strings} x :{file, stdin} X out:{file, stdout, /dev/null}. > > Finally, we need a test function with parameters and a basic but > reasonably accurate average calculation. Using this function over the > above 4D matrix, I am feeling confident in saying that: > > 1. there is no difference between pre-compiled and locally-compiled busybox > 2. the busybox strings is as fast as GNU strings > 3. the code I sent is on average 2x faster > 4. the code I sent worst case is just 23% slower of the best of the > others 3 cases > 5. the code I sent best case is above 4x faster than the best of the > others 3 cases > > Here below all the information to replicate the test on different > systems and architectures. > > cat /proc/cpuinfo | grep "model name" | tail -n1 > model name : Intel(R) Core(TM) i5-8350U CPU @ 1.70GHz > > GNOME Terminal > Version 3.44.0 for GNOME 42 > Using VTE version 0.68.0 +BIDI +GNUTLS +ICU +SYSTEMD > > stats() { > rm -f t.time > local cmd=${1:-/usr/bin/busybox strings /usr/bin/busybox} n=${2:-100} > for i in $(seq 1 $n); do eval time $cmd; done 2>t.time > { > echo > echo "$cmd" > sed -ne "s,real\t,min: ,p" t.time | sort -n | head -n1 > let avg=$(sed -ne "s,real\t0m0.[0]*\([0-9]*\)s,\\1,p" t.time | tr '\n' '+')0 > printf "avg: 0m0.%03ds\n" $(( (50+$avg)/100 )) > sed -ne "s,real\t,max: ,p" t.time | sort -n | tail -n1 > } >&2 > } > > ============= > > /usr/bin/busybox | head -n1 > BusyBox v1.30.1 (Ubuntu 1:1.30.1-7ubuntu3) multi-call binary. > > rm -f 1.txt; cmd="/usr/bin/busybox strings /usr/bin/busybox"; > stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt > > /usr/bin/busybox strings /usr/bin/busybox > min: 0m0.067s > avg: 0m0.090s > max: 0m0.134s > > /usr/bin/busybox strings /usr/bin/busybox > min: 0m0.013s > avg: 0m0.013s > max: 0m0.016s > > /usr/bin/busybox strings /usr/bin/busybox > min: 0m0.013s > avg: 0m0.014s > max: 0m0.018s > > rm -f 1.txt; cmd="cat /usr/bin/busybox | /usr/bin/busybox strings"; > stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt > > cat /usr/bin/busybox | /usr/bin/busybox strings > min: 0m0.072s > avg: 0m0.095s > max: 0m0.141s > > cat /usr/bin/busybox | /usr/bin/busybox strings > min: 0m0.021s > avg: 0m0.022s > max: 0m0.026s > > cat /usr/bin/busybox | /usr/bin/busybox strings > min: 0m0.021s > avg: 0m0.022s > max: 0m0.025s > > ============= > > ./busybox | head -n1 > BusyBox v1.37.0.git (2023-07-21 15:06:26 CEST) multi-call binary. > gcc --version | head -n1 > gcc (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0 > > rm -f 1.txt; cmd="./busybox strings /usr/bin/busybox"; > stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.tx > > ./busybox strings /usr/bin/busybox > min: 0m0.064s > avg: 0m0.089s > max: 0m0.123s > > ./busybox strings /usr/bin/busybox > min: 0m0.014s > avg: 0m0.014s > max: 0m0.016s > > ./busybox strings /usr/bin/busybox > min: 0m0.014s > avg: 0m0.014s > max: 0m0.016s > > rm -f 1.txt; cmd="cat /usr/bin/busybox | ./busybox strings"; > stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt > > cat /usr/bin/busybox | ./busybox strings > min: 0m0.075s > avg: 0m0.098s > max: 0m0.148s > > cat /usr/bin/busybox | ./busybox strings > min: 0m0.022s > avg: 0m0.023s > max: 0m0.033s > > cat /usr/bin/busybox | ./busybox strings > min: 0m0.023s > avg: 0m0.023s > max: 0m0.027s > > ============= > > gcc -Wall -O3 strings.c -o strings && strip strings > gcc --version | head -n1 > gcc (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0 > > rm -f 1.txt; cmd="../redfishos/recovery/strings /usr/bin/busybox"; > stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt > > ../redfishos/recovery/strings /usr/bin/busybox > min: 0m0.015s > avg: 0m0.040s > max: 0m0.079s > > ../redfishos/recovery/strings /usr/bin/busybox > min: 0m0.009s > avg: 0m0.009s > max: 0m0.010s > > ../redfishos/recovery/strings /usr/bin/busybox > min: 0m0.009s > avg: 0m0.010s > max: 0m0.021s > > rm -f 1.txt; cmd="cat /usr/bin/busybox | ../redfishos/recovery/strings strings"; > stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt > > cat /usr/bin/busybox | ../redfishos/recovery/strings > min: 0m0.041s > avg: 0m0.050s > max: 0m0.082s > > cat /usr/bin/busybox | ../redfishos/recovery/strings > min: 0m0.017s > avg: 0m0.017s > max: 0m0.019s > > cat /usr/bin/busybox | ../redfishos/recovery/strings > min: 0m0.017s > avg: 0m0.017s > max: 0m0.024s > > ============= > > strings --version | head -n1 > GNU strings (GNU Binutils for Ubuntu) 2.38 > > rm -f 1.txt; cmd="strings /usr/bin/busybox"; > stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt > > strings /usr/bin/busybox > min: 0m0.073s > avg: 0m0.097s > max: 0m0.136s > > strings /usr/bin/busybox > min: 0m0.020s > avg: 0m0.021s > max: 0m0.024s > > strings /usr/bin/busybox > min: 0m0.021s > avg: 0m0.021s > max: 0m0.026s > > rm -f 1.txt; cmd="cat /usr/bin/busybox | strings"; > stats "$cmd "; stats "$cmd" >/dev/null; stats "$cmd" >1.txt > > cat /usr/bin/busybox | strings > min: 0m0.077s > avg: 0m0.103s > max: 0m0.140s > > cat /usr/bin/busybox | strings > min: 0m0.029s > avg: 0m0.029s > max: 0m0.039s > > cat /usr/bin/busybox | strings > min: 0m0.029s > avg: 0m0.029s > max: 0m0.037s Hi, I just adopted the test in the PERFORMANCE section of your source ** PERFORMANCES *************************************************************** * * gcc -Wall -O3 strings.orig.c -o strings && strip strings * rm -f [12].txt * time strings /usr/bin/busybox >1.txt * real 0m0.035s * time ./strings /usr/bin/busybox >2.txt * real 0m1.843s * * gcc -Wall -O3 strings.c -o strings && strip strings * rm -f [12].txt * time strings /usr/bin/busybox >1.txt * real 0m0.033s * time ./strings /usr/bin/busybox >2.txt * real 0m0.011s * ** FOOTPRINT ****************************************************************** Ciao, Tito From rmy at pobox.com Sat Jul 22 07:33:08 2023 From: rmy at pobox.com (Ron Yorston) Date: Sat, 22 Jul 2023 08:33:08 +0100 Subject: ash builtin sleep behavior In-Reply-To: References: Message-ID: <64bb8634.Ih8njzu6RZwlcNZ4%rmy@pobox.com> Igor, There have been a number of problems with the sleep built-in. It was recently disabled by this commit: https://git.busybox.net/busybox/commit/?id=5e0411a7fb510b9aecda0a850c76bdd62c50efa4 >ash: disable sleep as builtin, closes 15619 >Has a few annoying problems: >* sleepcmd() -> sleep_main(), the parsing of bad arguments exits the shell. >* sleep_for_duration() in sleep_main() has to be interruptible for > ^C traps to work, which may be a problem for other users > of sleep_for_duration(). >* BUT, if sleep_for_duration() is interruptible, then SIGCHLD interrupts it > as well (try "/bin/sleep 1 & sleep 10"). >* sleep_main() must not allocate anything as ^C in ash longjmp's. > (currently, allocations are only on error paths, in message printing). Cheers, Ron From roberto.foglietta at gmail.com Sat Jul 22 11:35:56 2023 From: roberto.foglietta at gmail.com (Roberto A. Foglietta) Date: Sat, 22 Jul 2023 13:35:56 +0200 Subject: Proposal for a new applet: strings In-Reply-To: <20230722080201.32b21e94@devuan> References: <20230721223219.508ece1e@devuan> <20230722080201.32b21e94@devuan> Message-ID: On Sat, 22 Jul 2023 at 08:02, tito wrote: > > Hi, > I just adopted the test in the PERFORMANCE section of your source > > ** PERFORMANCES *************************************************************** > * > * gcc -Wall -O3 strings.orig.c -o strings && strip strings > * rm -f [12].txt > * time strings /usr/bin/busybox >1.txt > * real 0m0.035s > * time ./strings /usr/bin/busybox >2.txt > * real 0m1.843s > * > * gcc -Wall -O3 strings.c -o strings && strip strings > * rm -f [12].txt > * time strings /usr/bin/busybox >1.txt > * real 0m0.033s > * time ./strings /usr/bin/busybox >2.txt > * real 0m0.011s > * > ** FOOTPRINT ****************************************************************** > Sorry Tito, I do not want to be pedantic but that is not a benchmark suite. It is just the presentation of cherry-picked results that are meaningful about performances. After having introduced the use of tmpfs, the "real 0m0.033s" should be changed to "real 0m0.022s" or better the 11 in 16 in such a way to maintain a reasonable proportion with the original code but who cares anymore about the original code?. Now, we can argue - why I did not share the entire benchmark suite in the header since the beginning. Well, after all the benchmark suite is something like for i in 1..100 do time. This means that the "core engine" behind the source of completion time is the same (in good and bad shapes, both). Everything else is just a matter of simple math and presentation. Your three repetitions might seem very similar to my results presentation with a tiny sensitive difference: one single result is NOT a statistics, it does not even take in consideration the hypothesis of a variance in performances therefore it is a statement (a source of truth!). While three repetitions makes me think that something about statistics has been overlooked or like I did - I appreciated your sense of humor in suggesting that I should present statistics instead of a statement in the header. Finally, the mktmp on tmpfs is a must. Otherwise we are going to test the performance of our hdd/ssd when the execution time is faster than the I/O throughput. I have one of the fastest commercial SSD mounted on my laptop and therefore I do not care very much but an embedded/mobile system can have 8 CPU pipes like my laptop but a much slower flash on SoC. This is just to say that a benchmark should take care about caching and disk I/O. Obviously, the disk I/O gets into the picture also when we read the file to strings. Unless the file is cached (and a cache system exists and works efficiently) but in input is part of the benchmark. How the file/stdin is read, is part of the stings way of working, obviously. Probably we also need to try something like "sync; echo 3 > /proc/sys/vm/drop_caches" before every execution and use something different to string than a busybox, something which is independent from strings and bb, both. Finally, the benchmark suite should also do a single run before all the tests just to charge the cache and unleash the CPU at its maximum performance. Plus putting the CPU set to performance instead of anything else just to quickly make it work at its best. The benchmark.sh in attachment does stuff like that and can run with drop-the-cache or not. For this reason, it requires root privileges to run. It shows at my home that in fact 33 / 11 are a very good estimation and another one could be 32 / 12 or anything in between. Therefore my statement in the header was a source of truth under the limitation of the tests I did, obviously. In the code I have replaced the static inline function with a macro #define isPrintable(c) ((c) == 0x09 || ((c) >= 0x20 && (c) <= 0x7e)) because the inline is not always granted and the code is used just a single time. Probably the -O3 gcc optimization got it and inline by default. == QUESTION == Is this a preliminary work for the integration task or just an educated academic ping pong e-mail exchange? Best regards, R- -------------- next part -------------- A non-text attachment was scrubbed... Name: benchmark.sh Type: application/x-shellscript Size: 1919 bytes Desc: not available URL: From farmatito at tiscali.it Sat Jul 22 13:39:48 2023 From: farmatito at tiscali.it (tito) Date: Sat, 22 Jul 2023 15:39:48 +0200 Subject: Proposal for a new applet: strings In-Reply-To: References: <20230721223219.508ece1e@devuan> <20230722080201.32b21e94@devuan> Message-ID: <20230722153948.151f4b5b@devuan> On Sat, 22 Jul 2023 13:35:56 +0200 "Roberto A. Foglietta" wrote: > On Sat, 22 Jul 2023 at 08:02, tito wrote: > > > > Hi, > > I just adopted the test in the PERFORMANCE section of your source > > > > ** PERFORMANCES *************************************************************** > > * > > * gcc -Wall -O3 strings.orig.c -o strings && strip strings > > * rm -f [12].txt > > * time strings /usr/bin/busybox >1.txt > > * real 0m0.035s > > * time ./strings /usr/bin/busybox >2.txt > > * real 0m1.843s > > * > > * gcc -Wall -O3 strings.c -o strings && strip strings > > * rm -f [12].txt > > * time strings /usr/bin/busybox >1.txt > > * real 0m0.033s > > * time ./strings /usr/bin/busybox >2.txt > > * real 0m0.011s > > * > > ** FOOTPRINT ****************************************************************** > > > > Sorry Tito, > > I do not want to be pedantic but that is not a benchmark suite. It is > just the presentation of cherry-picked results that are meaningful > about performances. > > After having introduced the use of tmpfs, the "real 0m0.033s" should > be changed to "real 0m0.022s" or better the 11 in 16 in such a way to > maintain a reasonable proportion with the original code but who cares > anymore about the original code?. > > Now, we can argue - why I did not share the entire benchmark suite in > the header since the beginning. Well, after all the benchmark suite is > something like for i in 1..100 do time. This means that the "core > engine" behind the source of completion time is the same (in good and > bad shapes, both). Everything else is just a matter of simple math and > presentation. > > Your three repetitions might seem very similar to my results > presentation with a tiny sensitive difference: one single result is > NOT a statistics, it does not even take in consideration the > hypothesis of a variance in performances therefore it is a statement > (a source of truth!). While three repetitions makes me think that > something about statistics has been overlooked or like I did - I > appreciated your sense of humor in suggesting that I should present > statistics instead of a statement in the header. > > Finally, the mktmp on tmpfs is a must. Otherwise we are going to test > the performance of our hdd/ssd when the execution time is faster than > the I/O throughput. I have one of the fastest commercial SSD mounted > on my laptop and therefore I do not care very much but an > embedded/mobile system can have 8 CPU pipes like my laptop but a much > slower flash on SoC. > > This is just to say that a benchmark should take care about caching > and disk I/O. Obviously, the disk I/O gets into the picture also when > we read the file to strings. Unless the file is cached (and a cache > system exists and works efficiently) but in input is part of the > benchmark. How the file/stdin is read, is part of the stings way of > working, obviously. Probably we also need to try something like "sync; > echo 3 > /proc/sys/vm/drop_caches" before every execution and use > something different to string than a busybox, something which is > independent from strings and bb, both. > > Finally, the benchmark suite should also do a single run before all > the tests just to charge the cache and unleash the CPU at its maximum > performance. Plus putting the CPU set to performance instead of > anything else just to quickly make it work at its best. > > The benchmark.sh in attachment does stuff like that and can run with > drop-the-cache or not. For this reason, it requires root privileges to > run. It shows at my home that in fact 33 / 11 are a very good > estimation and another one could be 32 / 12 or anything in between. > Therefore my statement in the header was a source of truth under the > limitation of the tests I did, obviously. > > In the code I have replaced the static inline function with a macro > > #define isPrintable(c) ((c) == 0x09 || ((c) >= 0x20 && (c) <= 0x7e)) > > because the inline is not always granted and the code is used just a > single time. Probably the -O3 gcc optimization got it and inline by > default. > > == QUESTION == > > Is this a preliminary work for the integration task or just an > educated academic ping pong e-mail exchange? > > Best regards, R- Hi, I'm not the maintainer so I can say nothing about integration, I can just point out things that look strange to me and my limited knowledge. When I read that this code is faster vs other code as I'm a curious person I just try to see how much faster it is and why as there is always something to learn on the busybox mailing list. If in my little tests it is not faster then I think I'm entitled to ask questions about it as science results should be reproducible. For simple benchmarking maybe reading a big enough file into memory and feeding it to strings in a few 1000 iterations should do to avoid bias from hdd/sdd and system load, one shot shows: ramtmp="$(mktemp -p /dev/shm/)" dd if=vmlinux.o of=$ramtmp echo $ramtmp /dev/shm/tmp.ll3G2kzKE1 1) coreutils strings time strings $ramtmp > /dev/null real 0m0.473s user 0m0.460s sys 0m0.013s 2) busybox strings time ./busybox strings $ramtmp > /dev/null real 0m0.285s user 0m0.276s sys 0m0.008s 3) new strings time ./strings $ramtmp > /dev/null real 0m0.349s user 0m0.337s sys 0m0.012s of course a few more iterations would give statistically better results. After a few more tests about output it seems to me that it is not the same as coreutils strings nor busybox strings. A simple test: list=`find /usr/bin` 1) busybox strings vs coreutils strings: for i in $list; do if test -f $i; then strings $i > out1.txt; ./Desktop/busybox strings $i > out2.txt; diff -q out1.txt out2.txt; fi; done No output here, so no differences 2) busybox strings vs new strings: for i in $list; do if test -f $i; then ./Desktop/strings $i > out1.txt; ./Desktop/busybox strings $i > out2.txt; diff -q out1.txt out2.txt; fi; done Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ 3) coreutils strings vs new strings: for i in $list; do if test -f $i; then ./Desktop/strings $i > out1.txt; strings $i > out2.txt; diff -q out1.txt out2.txt; fi; done | wc -l 35 I suspect this could be a problem for integration and also size of code after integration is relevant. Ciao, Tito From roberto.foglietta at gmail.com Sat Jul 22 17:31:28 2023 From: roberto.foglietta at gmail.com (Roberto A. Foglietta) Date: Sat, 22 Jul 2023 19:31:28 +0200 Subject: Proposal for a new applet: strings In-Reply-To: <20230722153948.151f4b5b@devuan> References: <20230721223219.508ece1e@devuan> <20230722080201.32b21e94@devuan> <20230722153948.151f4b5b@devuan> Message-ID: On Sat, 22 Jul 2023 at 15:40, tito wrote: > Hi, > > I'm not the maintainer so I can say nothing about integration, > I can just point out things that look strange to me and my limited knowledge. > When I read that this code is faster vs other code as I'm a curious > person I just try to see how much faster it is and why as there > is always something to learn on the busybox mailing list. > If in my little tests it is not faster then I think I'm entitled > to ask questions about it as science results should be reproducible. > > For simple benchmarking maybe reading a big enough file > into memory and feeding it to strings in a few 1000 iterations > should do to avoid bias from hdd/sdd and system load, one shot shows: > > ramtmp="$(mktemp -p /dev/shm/)" > dd if=vmlinux.o of=$ramtmp > echo $ramtmp > /dev/shm/tmp.ll3G2kzKE1 > > 1) coreutils strings > time strings $ramtmp > /dev/null This is not correct because you are reading a file in tmpfs while the normal operations do not happen in this way for almost all the cases. Sometimes in ramfs, usually not. While it makes perfectly sense that the output will be sent to a tmpfs especially for those devices that the hdd/sdd/flash is particularly slow. After all, the strings output is temporary for its nature and IMHO is piped with grep, usually. > > of course a few more iterations would give statistically better results. The suite I provided with benchmark.sh is the answer because with dropping cache en/disabled check the two most important system states with all the cases that matter in real life, AFAIK. > 2) busybox strings vs new strings: > > for i in $list; do if test -f $i; then ./Desktop/strings $i > out1.txt; ./Desktop/busybox strings $i > out2.txt; diff -q out1.txt out2.txt; fi; done > Files out1.txt and out2.txt differ Confirmed that exists some differences in output with this: for i in /usr/bin/*; do if test -f $i; then ./strings $i > out1.txt; busybox strings $i > out2.txt; diff -q out1.txt out2.txt || break; fi; done diff -pruN out1.txt out2.txt Lines particularly long, more than 4096 characters are divided into blocks with \n. It is clearly a corner case for which \n should be omitted in printing. Thanks for this test, I did some but I did not catch the 4096 buffer overrun. > I suspect this could be a problem for integration and also size of code after integration is relevant. It is a corner case that could be addressed. I did not check the size of strings in busybox. However, once confirmed that the size is more important than the speed for busybox - I agree on this - then it can be proposed to binutils (or coreutils) depending on which package is included. I found the binary version for aarch64 on binutils, AFAIR. Best regards, R- From farmatito at tiscali.it Sat Jul 22 19:29:21 2023 From: farmatito at tiscali.it (tito) Date: Sat, 22 Jul 2023 21:29:21 +0200 Subject: Proposal for a new applet: strings In-Reply-To: References: <20230721223219.508ece1e@devuan> <20230722080201.32b21e94@devuan> <20230722153948.151f4b5b@devuan> Message-ID: <20230722212921.29538f1f@devuan> On Sat, 22 Jul 2023 19:31:28 +0200 "Roberto A. Foglietta" wrote: > On Sat, 22 Jul 2023 at 15:40, tito wrote: > > > Hi, > > > > I'm not the maintainer so I can say nothing about integration, > > I can just point out things that look strange to me and my limited knowledge. > > When I read that this code is faster vs other code as I'm a curious > > person I just try to see how much faster it is and why as there > > is always something to learn on the busybox mailing list. > > If in my little tests it is not faster then I think I'm entitled > > to ask questions about it as science results should be reproducible. > > > > For simple benchmarking maybe reading a big enough file > > into memory and feeding it to strings in a few 1000 iterations > > should do to avoid bias from hdd/sdd and system load, one shot shows: > > > > ramtmp="$(mktemp -p /dev/shm/)" > > dd if=vmlinux.o of=$ramtmp > > echo $ramtmp > > /dev/shm/tmp.ll3G2kzKE1 > > > > 1) coreutils strings > > time strings $ramtmp > /dev/null > > This is not correct because you are reading a file in tmpfs while the Yes, this was exactly the purpose of the test to eliminate all factors connected to underlying block devices and time the speed of code of the different implementations. > normal operations do not happen in this way for almost all the cases. > Sometimes in ramfs, usually not. While it makes perfectly sense that > the output will be sent to a tmpfs especially for those devices that > the hdd/sdd/flash is particularly slow. After all, the strings output > is temporary for its nature and IMHO is piped with grep, usually. > > > > > of course a few more iterations would give statistically better results. > > The suite I provided with benchmark.sh is the answer because with > dropping cache en/disabled check the two most important system states > with all the cases that matter in real life, AFAIK. > > > 2) busybox strings vs new strings: > > > > for i in $list; do if test -f $i; then ./Desktop/strings $i > out1.txt; ./Desktop/busybox strings $i > out2.txt; diff -q out1.txt out2.txt; fi; done > > Files out1.txt and out2.txt differ > > Confirmed that exists some differences in output with this: > > for i in /usr/bin/*; do if test -f $i; then ./strings $i > out1.txt; > busybox strings $i > out2.txt; diff -q out1.txt out2.txt || break; fi; > done > > diff -pruN out1.txt out2.txt > > Lines particularly long, more than 4096 characters are divided into > blocks with \n. It is clearly a corner case for which \n should be It was 35 corner cases in a handful of files due to a arbitrary hard-coded limitation. You should maybe run it on `find /` > omitted in printing. Thanks for this test, I did some but I did not > catch the 4096 buffer overrun. > > > I suspect this could be a problem for integration and also size of code after integration is relevant. > > It is a corner case that could be addressed. I did not check the size > of strings in busybox. However, once confirmed that the size is more > important than the speed for busybox - I agree on this - then it can > be proposed to binutils (or coreutils) depending on which package is > included. I found the binary version for aarch64 on binutils, AFAIR. I wonder why should they be wanting to change their stable code for a new implementation? > Best regards, R- Have a nice weekend! Ciao, Tito From roberto.foglietta at gmail.com Sat Jul 22 22:36:09 2023 From: roberto.foglietta at gmail.com (Roberto A. Foglietta) Date: Sun, 23 Jul 2023 00:36:09 +0200 Subject: Proposal for a new applet: strings In-Reply-To: <20230722212921.29538f1f@devuan> References: <20230721223219.508ece1e@devuan> <20230722080201.32b21e94@devuan> <20230722153948.151f4b5b@devuan> <20230722212921.29538f1f@devuan> Message-ID: On Sat, 22 Jul 2023 at 21:29, tito wrote: > > On Sat, 22 Jul 2023 19:31:28 +0200 > "Roberto A. Foglietta" wrote: > > > On Sat, 22 Jul 2023 at 15:40, tito wrote: > > > > > Hi, > > > > > > I'm not the maintainer so I can say nothing about integration, > > > I can just point out things that look strange to me and my limited knowledge. > > > When I read that this code is faster vs other code as I'm a curious > > > person I just try to see how much faster it is and why as there > > > is always something to learn on the busybox mailing list. > > > If in my little tests it is not faster then I think I'm entitled > > > to ask questions about it as science results should be reproducible. > > > > > > For simple benchmarking maybe reading a big enough file > > > into memory and feeding it to strings in a few 1000 iterations > > > should do to avoid bias from hdd/sdd and system load, one shot shows: > > > > > > ramtmp="$(mktemp -p /dev/shm/)" > > > dd if=vmlinux.o of=$ramtmp > > > echo $ramtmp > > > /dev/shm/tmp.ll3G2kzKE1 > > > > > > 1) coreutils strings > > > time strings $ramtmp > /dev/null > > > > This is not correct because you are reading a file in tmpfs while the > > Yes, this was exactly the purpose of the test to eliminate all > factors connected to underlying block devices and time > the speed of code of the different implementations. > Which is wrong because you did a hypothesis which is far away from the typical usage and in some cases you can even use it because strings over a 4GB ISO image would not necessarily fit into a tmpfs in every system. Abstract benchmarks can be funny but do not depict/measure the reality as usual. Extending this logic, we can trash the Ohm law because we can reach in the laboratory a near zero temperature! > > > > Lines particularly long, more than 4096 characters are divided into > > blocks with \n. It is clearly a corner case for which \n should be > > It was 35 corner cases in a handful of files due to a arbitrary hard-coded limitation. > You should maybe run it on `find /` Which can be solved quite easily with a cast of a bool: bool pr = isPrintable(*ch); use this bool instead of the check into the code and change this one #define print_text(p,b,c) if(p-b >= 4) { *p++ = 0; printf("%s%c",b,c); } print_text(p, buffer, pr ? *ch : '\n'); // print collected text in such a way it prints the current char rather than the new line. After this change the average of 2x speed has been maintained. > > > > > I suspect this could be a problem for integration and also size of code after integration is relevant. > > The size can be reduced using two buffers only without losing performances because three are redundant. Which is the current size of the strings applet? Just to have an idea because the size of a single binary with main() et company cannot immediately be compared with a busybox applet. For sure is a lot more smaller than the strings which also require a large shared library: size /usr/bin/strings text data bss dec hex filename 20943 1472 64 22479 57cf /usr/bin/strings ldd /usr/bin/strings linux-vdso.so.1 (0x00007ffde4fbc000) libbfd-2.38-system.so => /lib/x86_64-linux-gnu/libbfd-2.38-system.so (0x00007f6d64cf1000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6d64ac9000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f6d64aad000) /lib64/ld-linux-x86-64.so.2 (0x00007f6d64e8c000) size /lib/x86_64-linux-gnu/libbfd-2.38-system.so text data bss dec hex filename 1434786 94000 680 1529466 17567a /lib/x86_64-linux-gnu/libbfd-2.38-system.so > > It is a corner case that could be addressed. I did not check the size > > of strings in busybox. However, once confirmed that the size is more > > important than the speed for busybox - I agree on this - then it can > > be proposed to binutils (or coreutils) depending on which package is > > included. I found the binary version for aarch64 on binutils, AFAIR. > > I wonder why should they be wanting to change their stable code for > a new implementation? Because It is very easy to check that it works, it is 2x faster on average and on a fine-tuned system can reach 4x, the size drops dramatically considering to free the binary from the large shared library. In attachment the new version with the test suite and the benchmark suite in the header. The benchmark suite did not change with respect to the script file I just sent. Best regards, R- -------------- next part -------------- A non-text attachment was scrubbed... Name: strings.c Type: text/x-csrc Size: 6018 bytes Desc: not available URL: From farmatito at tiscali.it Sun Jul 23 09:41:33 2023 From: farmatito at tiscali.it (tito) Date: Sun, 23 Jul 2023 11:41:33 +0200 Subject: Proposal for a new applet: strings In-Reply-To: References: <20230721223219.508ece1e@devuan> <20230722080201.32b21e94@devuan> <20230722153948.151f4b5b@devuan> <20230722212921.29538f1f@devuan> Message-ID: <20230723114133.579c3a43@devuan> On Sun, 23 Jul 2023 00:36:09 +0200 "Roberto A. Foglietta" wrote: > On Sat, 22 Jul 2023 at 21:29, tito wrote: > > > > On Sat, 22 Jul 2023 19:31:28 +0200 > > "Roberto A. Foglietta" wrote: > > > > > On Sat, 22 Jul 2023 at 15:40, tito wrote: > > > > > > > Hi, > > > > > > > > I'm not the maintainer so I can say nothing about integration, > > > > I can just point out things that look strange to me and my limited knowledge. > > > > When I read that this code is faster vs other code as I'm a curious > > > > person I just try to see how much faster it is and why as there > > > > is always something to learn on the busybox mailing list. > > > > If in my little tests it is not faster then I think I'm entitled > > > > to ask questions about it as science results should be reproducible. > > > > > > > > For simple benchmarking maybe reading a big enough file > > > > into memory and feeding it to strings in a few 1000 iterations > > > > should do to avoid bias from hdd/sdd and system load, one shot shows: > > > > > > > > ramtmp="$(mktemp -p /dev/shm/)" > > > > dd if=vmlinux.o of=$ramtmp > > > > echo $ramtmp > > > > /dev/shm/tmp.ll3G2kzKE1 > > > > > > > > 1) coreutils strings > > > > time strings $ramtmp > /dev/null > > > > > > This is not correct because you are reading a file in tmpfs while the > > > > Yes, this was exactly the purpose of the test to eliminate all > > factors connected to underlying block devices and time > > the speed of code of the different implementations. > > > > Which is wrong because you did a hypothesis which is far away from the > typical usage and in some cases you can even use it because strings > over a 4GB ISO image would not necessarily fit into a tmpfs in every > system. Abstract benchmarks can be funny but do not depict/measure the > reality as usual. Extending this logic, we can trash the Ohm law > because we can reach in the laboratory a near zero temperature! I see but dropping the caches etc doesn't seem to be a typical use case either. Using the same optimization flag -O3 the busybox applet in a real life system gives close empirical results, which is the results most people in their normal life use cases (one shot, no loops running, no files in memory, no dropped caches, no giant multi-GB files) will see so the performance increase is swallowed by the system or by other bottlenecks. > > > > > > Lines particularly long, more than 4096 characters are divided into > > > blocks with \n. It is clearly a corner case for which \n should be > > > > It was 35 corner cases in a handful of files due to a arbitrary hard-coded limitation. > > You should maybe run it on `find /` > > Which can be solved quite easily with a cast of a bool: > > bool pr = isPrintable(*ch); > > use this bool instead of the check into the code and change this one > > #define print_text(p,b,c) if(p-b >= 4) { *p++ = 0; printf("%s%c",b,c); } > > print_text(p, buffer, pr ? *ch : '\n'); // print collected text > > in such a way it prints the current char rather than the new line. > After this change the average of 2x speed has been maintained. > > > > > > > > I suspect this could be a problem for integration and also size of code after integration is relevant. > > > > > The size can be reduced using two buffers only without losing > performances because three are redundant. Which is the current size of > the strings applet? Just to have an idea because the size of a single > binary with main() et company cannot immediately be compared with a > busybox applet. For sure is a lot more smaller than the strings which > also require a large shared library: > > size /usr/bin/strings > text data bss dec hex filename > 20943 1472 64 22479 57cf /usr/bin/strings > > ldd /usr/bin/strings > linux-vdso.so.1 (0x00007ffde4fbc000) > libbfd-2.38-system.so => /lib/x86_64-linux-gnu/libbfd-2.38-system.so > (0x00007f6d64cf1000) > libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6d64ac9000) > libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f6d64aad000) > /lib64/ld-linux-x86-64.so.2 (0x00007f6d64e8c000) > > size /lib/x86_64-linux-gnu/libbfd-2.38-system.so > text data bss dec hex filename > 1434786 94000 680 1529466 17567a > /lib/x86_64-linux-gnu/libbfd-2.38-system.so > > > > It is a corner case that could be addressed. I did not check the size > > > of strings in busybox. However, once confirmed that the size is more > > > important than the speed for busybox - I agree on this - then it can > > > be proposed to binutils (or coreutils) depending on which package is > > > included. I found the binary version for aarch64 on binutils, AFAIR. > > > > I wonder why should they be wanting to change their stable code for > > a new implementation? > > Because It is very easy to check that it works, it is 2x faster on > average and on a fine-tuned system can reach 4x, the size drops > dramatically considering to free the binary from the large shared > library. I think the size will rather increase as there are a bunch of features missing that the original bb implementation already has: 1) multiple file handling (a must i would dare to say) 2) -a -f -o -n -t command line options The options are: -a - --all Scan the entire file, not just the data section [default] -f --print-file-name Print the name of the file before each string -n --bytes=[number] Locate & print any NUL-terminated sequence of at least [number] characters (default 4). -t --radix={o,d,x} Print the location of the string in base 8, 10 or 16 -o An alias for --radix=o 3) output compatible with original gnu strings > In attachment the new version with the test suite and the benchmark > suite in the header. The benchmark suite did not change with respect > to the script file I just sent. > > Best regards, R- BTW: there still seem to be corner-cases: list=`find /usr` for i in $list; do if test -f $i; then ./strings $i > out1.txt; strings $i > out2.txt; diff -q out1.txt out2.txt; fi; done Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ Files out1.txt and out2.txt differ test is still running.... Ciao, Tito From roberto.foglietta at gmail.com Sun Jul 23 10:00:56 2023 From: roberto.foglietta at gmail.com (Roberto A. Foglietta) Date: Sun, 23 Jul 2023 12:00:56 +0200 Subject: Proposal for a new applet: strings In-Reply-To: <20230723114133.579c3a43@devuan> References: <20230721223219.508ece1e@devuan> <20230722080201.32b21e94@devuan> <20230722153948.151f4b5b@devuan> <20230722212921.29538f1f@devuan> <20230723114133.579c3a43@devuan> Message-ID: On Sun, 23 Jul 2023 at 11:42, tito wrote: > > On Sun, 23 Jul 2023 00:36:09 +0200 > "Roberto A. Foglietta" wrote: > > > On Sat, 22 Jul 2023 at 21:29, tito wrote: > > > > > > On Sat, 22 Jul 2023 19:31:28 +0200 > > > "Roberto A. Foglietta" wrote: > > > > > > > On Sat, 22 Jul 2023 at 15:40, tito wrote: > > > > > > > > > Hi, > > > > > > > > > > I'm not the maintainer so I can say nothing about integration, > > > > > I can just point out things that look strange to me and my limited knowledge. > > > > > When I read that this code is faster vs other code as I'm a curious > > > > > person I just try to see how much faster it is and why as there > > > > > is always something to learn on the busybox mailing list. > > > > > If in my little tests it is not faster then I think I'm entitled > > > > > to ask questions about it as science results should be reproducible. > > > > > > > > > > For simple benchmarking maybe reading a big enough file > > > > > into memory and feeding it to strings in a few 1000 iterations > > > > > should do to avoid bias from hdd/sdd and system load, one shot shows: > > > > > > > > > > ramtmp="$(mktemp -p /dev/shm/)" > > > > > dd if=vmlinux.o of=$ramtmp > > > > > echo $ramtmp > > > > > /dev/shm/tmp.ll3G2kzKE1 > > > > > > > > > > 1) coreutils strings > > > > > time strings $ramtmp > /dev/null > > > > > > > > This is not correct because you are reading a file in tmpfs while the > > > > > > Yes, this was exactly the purpose of the test to eliminate all > > > factors connected to underlying block devices and time > > > the speed of code of the different implementations. > > > > > > > Which is wrong because you did a hypothesis which is far away from the > > typical usage and in some cases you can even use it because strings > > over a 4GB ISO image would not necessarily fit into a tmpfs in every > > system. Abstract benchmarks can be funny but do not depict/measure the > > reality as usual. Extending this logic, we can trash the Ohm law > > because we can reach in the laboratory a near zero temperature! > > I see but dropping the caches etc doesn't seem to be a typical use case either. Dropping the cache is a trick to bring the system in its state after the boot or as much as possible at that point. It is indispensable for a confrontation with the normal functioning which has a larger variance in completion time for each runs. > > Using the same optimization flag -O3 the busybox applet in a real life > system gives close empirical results, which is the results most > people in their normal life use cases (one shot, no loops running, > no files in memory, no dropped caches, no giant multi-GB files) > will see so the performance increase is swallowed by the system > or by other bottlenecks. > This is correct, AFAIK my busybox has been compiled with -02. I have to check. > I think the size will rather increase as there are a bunch of features > missing that the original bb implementation already has: > > 1) multiple file handling (a must i would dare to say) Which is not such a problem, after all for i in "$@"; do simply-strings "$i" | sed -e "s/^/$i:/"; done the sed will include also the file name in front of the string which is useful for grepping. However, the single-file limitation brings to personalize the approach: for i in "$@"; do simply-strings "$i" | grep -w "word" && break; done; echo $i For example. However, I admit that you are right about multiple-files input. Personally, I do not need at all and if I need, I do with a custom for. > 2) -a -f -o -n -t command line options > The options are: > -a - --all Scan the entire file, not just the data section [default] > -f --print-file-name Print the name of the file before each string > -n --bytes=[number] Locate & print any NUL-terminated sequence of at > least [number] characters (default 4). > -t --radix={o,d,x} Print the location of the string in base 8, 10 or 16 > -o An alias for --radix=o > Yes, strings has a lot of options and also busybox have several options. This is the best critic about proceeding with an integration. I will check if I can put an optimization into bb strings, just for my own curiosity. > 3) output compatible with original gnu strings > > > In attachment the new version with the test suite and the benchmark > > suite in the header. The benchmark suite did not change with respect > > to the script file I just sent. > > > > Best regards, R- > > BTW: there still seem to be corner-cases: > list=`find /usr` > for i in $list; do if test -f $i; then ./strings $i > out1.txt; strings $i > out2.txt; diff -q out1.txt out2.txt; fi; done > Files out1.txt and out2.txt differ > Files out1.txt and out2.txt differ > Files out1.txt and out2.txt differ > Files out1.txt and out2.txt differ > > test is still running.... ok, I will do a run. Can you please echo the finenames, instead? for i in $list; do if test -f $i; then ./strings $i > out1.txt; strings $i > out2.txt; diff -q out1.txt out2.txt >/dev/null || echo $i; fi; done Thanks, R- From farmatito at tiscali.it Sun Jul 23 11:18:09 2023 From: farmatito at tiscali.it (tito) Date: Sun, 23 Jul 2023 13:18:09 +0200 Subject: Proposal for a new applet: strings In-Reply-To: References: <20230721223219.508ece1e@devuan> <20230722080201.32b21e94@devuan> <20230722153948.151f4b5b@devuan> <20230722212921.29538f1f@devuan> <20230723114133.579c3a43@devuan> Message-ID: <20230723131809.58e3adca@devuan> On Sun, 23 Jul 2023 12:00:56 +0200 "Roberto A. Foglietta" wrote: > On Sun, 23 Jul 2023 at 11:42, tito wrote: > > > > On Sun, 23 Jul 2023 00:36:09 +0200 > > "Roberto A. Foglietta" wrote: > > > > > On Sat, 22 Jul 2023 at 21:29, tito wrote: > > > > > > > > On Sat, 22 Jul 2023 19:31:28 +0200 > > > > "Roberto A. Foglietta" wrote: > > > > > > > > > On Sat, 22 Jul 2023 at 15:40, tito wrote: > > > > > > > > > > > Hi, > > > > > > > > > > > > I'm not the maintainer so I can say nothing about integration, > > > > > > I can just point out things that look strange to me and my limited knowledge. > > > > > > When I read that this code is faster vs other code as I'm a curious > > > > > > person I just try to see how much faster it is and why as there > > > > > > is always something to learn on the busybox mailing list. > > > > > > If in my little tests it is not faster then I think I'm entitled > > > > > > to ask questions about it as science results should be reproducible. > > > > > > > > > > > > For simple benchmarking maybe reading a big enough file > > > > > > into memory and feeding it to strings in a few 1000 iterations > > > > > > should do to avoid bias from hdd/sdd and system load, one shot shows: > > > > > > > > > > > > ramtmp="$(mktemp -p /dev/shm/)" > > > > > > dd if=vmlinux.o of=$ramtmp > > > > > > echo $ramtmp > > > > > > /dev/shm/tmp.ll3G2kzKE1 > > > > > > > > > > > > 1) coreutils strings > > > > > > time strings $ramtmp > /dev/null > > > > > > > > > > This is not correct because you are reading a file in tmpfs while the > > > > > > > > Yes, this was exactly the purpose of the test to eliminate all > > > > factors connected to underlying block devices and time > > > > the speed of code of the different implementations. > > > > > > > > > > Which is wrong because you did a hypothesis which is far away from the > > > typical usage and in some cases you can even use it because strings > > > over a 4GB ISO image would not necessarily fit into a tmpfs in every > > > system. Abstract benchmarks can be funny but do not depict/measure the > > > reality as usual. Extending this logic, we can trash the Ohm law > > > because we can reach in the laboratory a near zero temperature! > > > > I see but dropping the caches etc doesn't seem to be a typical use case either. > > Dropping the cache is a trick to bring the system in its state after > the boot or as much as possible at that point. It is indispensable for > a confrontation with the normal functioning which has a larger > variance in completion time for each runs. > > > > > Using the same optimization flag -O3 the busybox applet in a real life > > system gives close empirical results, which is the results most > > people in their normal life use cases (one shot, no loops running, > > no files in memory, no dropped caches, no giant multi-GB files) > > will see so the performance increase is swallowed by the system > > or by other bottlenecks. > > > > This is correct, AFAIK my busybox has been compiled with -02. I have to check. > > > > I think the size will rather increase as there are a bunch of features > > missing that the original bb implementation already has: > > > > 1) multiple file handling (a must i would dare to say) > > Which is not such a problem, after all > > for i in "$@"; do simply-strings "$i" | sed -e "s/^/$i:/"; done > > the sed will include also the file name in front of the string which > is useful for grepping. However, the single-file limitation brings to > personalize the approach: > > for i in "$@"; do simply-strings "$i" | grep -w "word" && break; done; echo $i Don't cheat, this change would break other people's scripts. > For example. However, I admit that you are right about multiple-files > input. Personally, I do not need at all and if I need, I do with a > custom for. > > > > 2) -a -f -o -n -t command line options > > The options are: > > -a - --all Scan the entire file, not just the data section [default] > > -f --print-file-name Print the name of the file before each string > > -n --bytes=[number] Locate & print any NUL-terminated sequence of at > > least [number] characters (default 4). > > -t --radix={o,d,x} Print the location of the string in base 8, 10 or 16 > > -o An alias for --radix=o > > > > Yes, strings has a lot of options and also busybox have several > options. This is the best critic about proceeding with an integration. > I will check if I can put an optimization into bb strings, just for my > own curiosity. This would be far better than reinventing the wheel. > > > 3) output compatible with original gnu strings > > > > > In attachment the new version with the test suite and the benchmark > > > suite in the header. The benchmark suite did not change with respect > > > to the script file I just sent. > > > > > > Best regards, R- > > > > BTW: there still seem to be corner-cases: > > list=`find /usr` > > for i in $list; do if test -f $i; then ./strings $i > out1.txt; strings $i > out2.txt; diff -q out1.txt out2.txt; fi; done > > Files out1.txt and out2.txt differ > > Files out1.txt and out2.txt differ > > Files out1.txt and out2.txt differ > > Files out1.txt and out2.txt differ > > > > test is still running.... > > ok, I will do a run. Can you please echo the finenames, instead? > > for i in $list; do if test -f $i; then ./strings $i > out1.txt; > strings $i > out2.txt; diff -q out1.txt out2.txt >/dev/null || echo > $i; fi; done > > Thanks, R- if you hire me as beta tester....at least you own me a beer if we ever met in person. root at devuan:/home/tito/Desktop# for i in $list; do if test -f $i; then ./strings $i > out1.txt; strings $i > out2.txt; diff -q out1.txt out2.txt; if test $? -eq 1 ; then echo $i; fi; fi; done Files out1.txt and out2.txt differ /usr/share/themes/Adapta-Nokto-Eta/gtk-3.24/gtk.gresource Files out1.txt and out2.txt differ /usr/share/themes/Adapta/gtk-3.24/gtk.gresource Files out1.txt and out2.txt differ /usr/share/themes/Adapta-Nokto/gtk-3.24/gtk.gresource Files out1.txt and out2.txt differ /usr/share/themes/Adapta-Eta/gtk-3.24/gtk.gresource Files out1.txt and out2.txt differ /usr/lib/x86_64-linux-gnu/libkomsooxml.so.17.0.0 Files out1.txt and out2.txt differ /usr/lib/x86_64-linux-gnu/libkomsooxml.so.17 Ciao, Tito From roberto.foglietta at gmail.com Sun Jul 23 14:17:54 2023 From: roberto.foglietta at gmail.com (Roberto A. Foglietta) Date: Sun, 23 Jul 2023 16:17:54 +0200 Subject: Proposal for a new applet: strings In-Reply-To: <20230723131809.58e3adca@devuan> References: <20230721223219.508ece1e@devuan> <20230722080201.32b21e94@devuan> <20230722153948.151f4b5b@devuan> <20230722212921.29538f1f@devuan> <20230723114133.579c3a43@devuan> <20230723131809.58e3adca@devuan> Message-ID: On Sun, 23 Jul 2023 at 13:18, tito wrote: > > On Sun, 23 Jul 2023 12:00:56 +0200 > "Roberto A. Foglietta" wrote: > > > > > > 1) multiple file handling (a must i would dare to say) > > > > Which is not such a problem, after all > > > > for i in "$@"; do simply-strings "$i" | sed -e "s/^/$i:/"; done > > > > the sed will include also the file name in front of the string which > > is useful for grepping. However, the single-file limitation brings to > > personalize the approach: > > > > for i in "$@"; do simply-strings "$i" | grep -w "word" && break; done; echo $i > > Don't cheat, this change would break other people's scripts. Other people are not anymore into the scene, since the moment that we established that reinventing the wheel is not efficient nor useful. > > > Yes, strings has a lot of options and also busybox have several > > options. This is the best critic about proceeding with an integration. > > I will check if I can put an optimization into bb strings, just for my > > own curiosity. > > This would be far better than reinventing the wheel. > Reinventing the wheel is a good way to understand how the wheel works and improve it. We just concluded that there is no reason to reinvent the wheel completely. However, the simple-strings can be useful when its deployment fixes fulfill a void better than replacing a fundamental system component like busybox which can break future OTA. In particular, it is fine as a service/rescue/recovery image in which the space is limited and the full compatibility with strings or busybox strings is not necessary and for everything else custom scripts can easily compensate. About improving busybox strings and more in general its printf performance, it is about this: setvbuf(stdout, (char *)stdout_buffer, _IOFBF, BUFSIZE); Obviously a large static buffer can impact the footprint but as long as malloc() is used into the busybox - and in its library I remember there were sanitising wrappers for it - then it would not be such a big deal to use a dynamically allocated buffer. The tricky aspect is about the applet forking. A topic that I do not know but I saw an option "no fork" in the config. I did not even start to see the code, therefore I am just wondering about. > > > > > 3) output compatible with original gnu strings > > > > > > > In attachment the new version with the test suite and the benchmark > > > > suite in the header. The benchmark suite did not change with respect > > > > to the script file I just sent. > > > > > > > > Best regards, R- > > > > > > BTW: there still seem to be corner-cases: > > > list=`find /usr` > > > for i in $list; do if test -f $i; then ./strings $i > out1.txt; strings $i > out2.txt; diff -q out1.txt out2.txt; fi; done > > > Files out1.txt and out2.txt differ > > > Files out1.txt and out2.txt differ > > > Files out1.txt and out2.txt differ > > > Files out1.txt and out2.txt differ > > > > > > test is still running.... > > > > ok, I will do a run. Can you please echo the finenames, instead? > > > > for i in $list; do if test -f $i; then ./strings $i > out1.txt; > > strings $i > out2.txt; diff -q out1.txt out2.txt >/dev/null || echo > > $i; fi; done > > The version in attachment also solves the rest of the problem that my /usr could have raised with the previous version. Moreover, I have further developed the benchmark and the testing suites. You might find interesting the new part of the benchmark suite about 'dd' used as an alternative of /dev/null for giving us a transfer speed. As you can see, if you wish to do strings on tmpfs then for each different file you need to copy it into the tmpfs. For this reason, copying in tmpfs + 100 strings run on the same file is like cheating <-- you started! ;-) > > if you hire me as beta tester....at least you own me a beer if we ever met in person. > Sure, you are welcome. I live in Genoa, at the moment - you can easily find my mobile telephone number by googling my name (well, to be precise: it is a brand strongly based on my name). In another context, I saw that there is the policy of paying by paypal & co. a small amount of money IMHO, it is a very bad marketing policy which seriously impair the value of a professionist. However, when someone acts outside its professional sector like - blogging, zero-hope commercial projects, end-users guides, et similia - then it is fine to ask, IMHO. As long as it is clear what someone asks. More in general, my common attitude is to raise and save money to start my own company and pay people to work for/with me. But everytime my incoming or my company business is going well, the people around me go mad and f*ck-up everything without any reasonable way to stop them. Now, I got quita a clear picture about it but this is definitely off-topic. Cheers, R- -------------- next part -------------- A non-text attachment was scrubbed... Name: strings.c Type: text/x-csrc Size: 8605 bytes Desc: not available URL: From farmatito at tiscali.it Sun Jul 23 14:38:17 2023 From: farmatito at tiscali.it (tito) Date: Sun, 23 Jul 2023 16:38:17 +0200 Subject: Proposal for a new applet: strings In-Reply-To: References: <20230721223219.508ece1e@devuan> <20230722080201.32b21e94@devuan> <20230722153948.151f4b5b@devuan> <20230722212921.29538f1f@devuan> <20230723114133.579c3a43@devuan> <20230723131809.58e3adca@devuan> Message-ID: <20230723163817.4a8be4cf@devuan> On Sun, 23 Jul 2023 16:17:54 +0200 "Roberto A. Foglietta" wrote: > On Sun, 23 Jul 2023 at 13:18, tito wrote: > > > > On Sun, 23 Jul 2023 12:00:56 +0200 > > "Roberto A. Foglietta" wrote: > > > > > > > > > 1) multiple file handling (a must i would dare to say) > > > > > > Which is not such a problem, after all > > > > > > for i in "$@"; do simply-strings "$i" | sed -e "s/^/$i:/"; done > > > > > > the sed will include also the file name in front of the string which > > > is useful for grepping. However, the single-file limitation brings to > > > personalize the approach: > > > > > > for i in "$@"; do simply-strings "$i" | grep -w "word" && break; done; echo $i > > > > Don't cheat, this change would break other people's scripts. > > Other people are not anymore into the scene, since the moment that we > established that reinventing the wheel is not efficient nor useful. > > > > > > > Yes, strings has a lot of options and also busybox have several > > > options. This is the best critic about proceeding with an integration. > > > I will check if I can put an optimization into bb strings, just for my > > > own curiosity. > > > > This would be far better than reinventing the wheel. > > > > Reinventing the wheel is a good way to understand how the wheel works > and improve it. We just concluded that there is no reason to reinvent > the wheel completely. However, the simple-strings can be useful when > its deployment fixes fulfill a void better than replacing a > fundamental system component like busybox which can break future OTA. Ever thought about compiling a busybox copy with only one applet or few applets that need fixes or updates or new features ? This was done a lot in the first android roms. > In particular, it is fine as a service/rescue/recovery image in which > the space is limited and the full compatibility with strings or > busybox strings is not necessary and for everything else custom > scripts can easily compensate. > > About improving busybox strings and more in general its printf > performance, it is about this: > > setvbuf(stdout, (char *)stdout_buffer, _IOFBF, BUFSIZE); > > Obviously a large static buffer can impact the footprint but as long > as malloc() is used into the busybox - and in its library I remember > there were sanitising wrappers for it - then it would not be such a > big deal to use a dynamically allocated buffer. The tricky aspect is > about the applet forking. A topic that I do not know but I saw an > option "no fork" in the config. I did not even start to see the code, > therefore I am just wondering about. Yes busybox code is tricky. This NO_FORK stuff is a black magic I really haven't understood yet. > > > > > > > > 3) output compatible with original gnu strings > > > > > > > > > In attachment the new version with the test suite and the benchmark > > > > > suite in the header. The benchmark suite did not change with respect > > > > > to the script file I just sent. > > > > > > > > > > Best regards, R- > > > > > > > > BTW: there still seem to be corner-cases: > > > > list=`find /usr` > > > > for i in $list; do if test -f $i; then ./strings $i > out1.txt; strings $i > out2.txt; diff -q out1.txt out2.txt; fi; done > > > > Files out1.txt and out2.txt differ > > > > Files out1.txt and out2.txt differ > > > > Files out1.txt and out2.txt differ > > > > Files out1.txt and out2.txt differ > > > > > > > > test is still running.... > > > > > > ok, I will do a run. Can you please echo the finenames, instead? > > > > > > for i in $list; do if test -f $i; then ./strings $i > out1.txt; > > > strings $i > out2.txt; diff -q out1.txt out2.txt >/dev/null || echo > > > $i; fi; done > > > > > The version in attachment also solves the rest of the problem that my > /usr could have raised with the previous version. Moreover, I have > further developed the benchmark and the testing suites. You might find > interesting the new part of the benchmark suite about 'dd' used as an > alternative of /dev/null for giving us a transfer speed. As you can > see, if you wish to do strings on tmpfs then for each different file > you need to copy it into the tmpfs. For this reason, copying in tmpfs > + 100 strings run on the same file is like cheating <-- you started! > ;-) I will study it. > > > > > > if you hire me as beta tester....at least you own me a beer if we ever met in person. > > > > Sure, you are welcome. I live in Genoa, at the moment - you can easily > find my mobile telephone number by googling my name (well, to be > precise: it is a brand strongly based on my name). it is rather far, maybe one day to visit the aquarium. > > In another context, I saw that there is the policy of paying by paypal > & co. a small amount of money IMHO, it is a very bad marketing policy > which seriously impair the value of a professionist. However, when Forget about the money, I prefer beer anyway, > someone acts outside its professional sector like - blogging, > zero-hope commercial projects, end-users guides, et similia - then it > is fine to ask, IMHO. As long as it is clear what someone asks. > > More in general, my common attitude is to raise and save money to > start my own company and pay people to work for/with me. But everytime > my incoming or my company business is going well, the people around me > go mad and f*ck-up everything without any reasonable way to stop them. > Now, I got quita a clear picture about it but this is definitely > off-topic. > > Cheers, R- Ciao, Tito From roberto.foglietta at gmail.com Mon Jul 24 08:36:47 2023 From: roberto.foglietta at gmail.com (Roberto A. Foglietta) Date: Mon, 24 Jul 2023 10:36:47 +0200 Subject: Proposal for a new applet: strings In-Reply-To: <20230723163817.4a8be4cf@devuan> References: <20230721223219.508ece1e@devuan> <20230722080201.32b21e94@devuan> <20230722153948.151f4b5b@devuan> <20230722212921.29538f1f@devuan> <20230723114133.579c3a43@devuan> <20230723131809.58e3adca@devuan> <20230723163817.4a8be4cf@devuan> Message-ID: On Sun, 23 Jul 2023 at 16:38, tito wrote: > > On Sun, 23 Jul 2023 16:17:54 +0200 > "Roberto A. Foglietta" wrote: > > > On Sun, 23 Jul 2023 at 13:18, tito wrote: > > > > > > On Sun, 23 Jul 2023 12:00:56 +0200 > > > "Roberto A. Foglietta" wrote: > > > > > > > > > > > > 1) multiple file handling (a must i would dare to say) > > > > > > > > Which is not such a problem, after all > > > > > > > > for i in "$@"; do simply-strings "$i" | sed -e "s/^/$i:/"; done > > > > > > > > the sed will include also the file name in front of the string which > > > > is useful for grepping. However, the single-file limitation brings to > > > > personalize the approach: > > > > > > > > for i in "$@"; do simply-strings "$i" | grep -w "word" && break; done; echo $i > > > > > > Don't cheat, this change would break other people's scripts. > > > > Other people are not anymore into the scene, since the moment that we > > established that reinventing the wheel is not efficient nor useful. > > > > > > > > > > > Yes, strings has a lot of options and also busybox have several > > > > options. This is the best critic about proceeding with an integration. > > > > I will check if I can put an optimization into bb strings, just for my > > > > own curiosity. > > > > > > This would be far better than reinventing the wheel. > > > > > > > Reinventing the wheel is a good way to understand how the wheel works > > and improve it. We just concluded that there is no reason to reinvent > > the wheel completely. However, the simple-strings can be useful when > > its deployment fixes fulfill a void better than replacing a > > fundamental system component like busybox which can break future OTA. > > Ever thought about compiling a busybox copy with only one applet > or few applets that need fixes or updates or new features ? > This was done a lot in the first android roms. > > > In particular, it is fine as a service/rescue/recovery image in which > > the space is limited and the full compatibility with strings or > > busybox strings is not necessary and for everything else custom > > scripts can easily compensate. > > > > About improving busybox strings and more in general its printf > > performance, it is about this: > > > > setvbuf(stdout, (char *)stdout_buffer, _IOFBF, BUFSIZE); > > > > Obviously a large static buffer can impact the footprint but as long > > as malloc() is used into the busybox - and in its library I remember > > there were sanitising wrappers for it - then it would not be such a > > big deal to use a dynamically allocated buffer. The tricky aspect is > > about the applet forking. A topic that I do not know but I saw an > > option "no fork" in the config. I did not even start to see the code, > > therefore I am just wondering about. > > Yes busybox code is tricky. This NO_FORK stuff is a black magic > I really haven't understood yet. I did not investigate that option nor the code but I have the sensation that it would be useful in two different cases: 1 - single applet busybox 2 - NOMMU systems for which v/fork is a burden My speculation is that when I call busybox, it forks on the applet function which drops everything it does not need and each call is a full detached process. With NO_FORK, I suppose that everything remains in memory and as much as possible the kernel keeps it in memory as a shared object. For example the code of busybox. While for each call, it duplicates the stack like a function in pthreads does. Therefore, every buffer defined is duplicated into each stack, by default unless a special definition messes up this general principle. About using setvbuf() in busybox: setvbuf(stdout, (char *)stdout_buffer, _IOFBF, BUFSIZE); It does not seem a viable solution for every applet. Therefore, I would insert into strings only and few others. Doing a grep into busybox code that function has been used in few applets: $ grep -rn setvbuf . 2>/dev/null | grep \.c: ./miscutils/hexedit.c:263: setvbuf(stdout, xmalloc(sz), _IOFBF, sz); ./coreutils/tee.c:126: setvbuf(stdout, NULL, _IONBF, 0); ./shell/match.c:105: setvbuf(stdout, NULL, _IONBF, 0); ./runit/svlogd.c:597: setvbuf(ld->filecur, NULL, _IOFBF, linelen); //// ./runit/svlogd.c:860: setvbuf(ld->filecur, NULL, _IOFBF, linelen); //// ./runit/svlogd.c:1128: setvbuf(stderr, NULL, _IOFBF, linelen); The man https://linux.die.net/man/3/setvbuf explains that in busybox just the single line is buffered except for hexedit. The full buffering, it might be useful also in dd when stdout is used and strings. Considering that defining a buffer in a function (applet) implies increasing the size of the executable, it makes sense using a malloc (a BB wrapper for it). After all, the malloc() code is included in busybox and using one more time adds just the ASM which is needed to handle that function call. Moreover, in my simple-strings, I have used a 4096 because I suppose that it is the kernel memory page therefore it is necessarily a contiguous physical RAM allocation, the biggest one granted without adding extra code apart from the malloc(). In some systems this setting could be different but I would not make a request like getconf to have that value and possibly the busybox does by itself (or might not). Possibly the kernel memory page size is set by default at compiling time for the specific target architecture. I bet that almost all use 4kb. Hint: it does not make sense to investigate all these details in depth before starting coding. We can assume that NO_FORK=0 NOMMU=0 and MEM_PAGE_SIZE=4096 and with these assumptions make some benchmarks on those systems/architectures for which those hypotheses are fulfilled. If the benchmark shows sensitive improvement in common usage cases, then it worths investigate also those cases that are not contemplated into the initial hypotheses. IMHO, 4Kb would be fine even if the memory page size is smaller. I hope this help, R- From isaac at is.having.coffee Mon Jul 31 11:02:39 2023 From: isaac at is.having.coffee (Isaac True) Date: Mon, 31 Jul 2023 11:02:39 +0000 Subject: [PATCH] mount: add feature to ignore flags starting with "x-" In-Reply-To: References: Message-ID: Hi all, Gentle ping on this topic. Is this be something that the developers would be willing to merge into Busybox? Cheers, Isaac ------- Original Message ------- On Wednesday, March 22nd, 2023 at 20:38, Xabier Oneca -- xOneca wrote: > > > Hi Isaac, > > > Do you think I should modify the patch to check for and ignore "X-" in addition to "x-"? > > > Don't know... Maybe lowercase is enough. It was more an > "informational" comment than a "request" comment. :) > > I personally don't use "x-" nor "X-" options, and the few ones that I > have seen in the wild have been the lowercase ones (e.g. Systemd > options). > > Cheers, > > Xabier Oneca_,,_