From: Rodrigo Alencar <rodrigo.alencar@analog.com>
Add kstrntoull() function, which converts a string to an ULL with a max
character limit. The function is an alternative integer parsing function
that does not require a null-terminated string. It becomes a better option
over simple_strtoull() or kstrtoull() when parsing integers from a buffer
with custom delimiters without having to create temporary copies.
The function is consumed inside the implementation _kstrtoull(),
promoting reuse.
Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
---
include/linux/kstrtox.h | 3 +++
lib/kstrtox.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/include/linux/kstrtox.h b/include/linux/kstrtox.h
index 6ea897222af1..49a6102b8e15 100644
--- a/include/linux/kstrtox.h
+++ b/include/linux/kstrtox.h
@@ -9,6 +9,9 @@
int __must_check _kstrtoul(const char *s, unsigned int base, unsigned long *res);
int __must_check _kstrtol(const char *s, unsigned int base, long *res);
+ssize_t __must_check kstrntoull(const char *s, unsigned int base,
+ unsigned long long *res, size_t max_chars);
+
int __must_check kstrtoull(const char *s, unsigned int base, unsigned long long *res);
int __must_check kstrtoll(const char *s, unsigned int base, long long *res);
diff --git a/lib/kstrtox.c b/lib/kstrtox.c
index bdde40cd69d7..202ecc058284 100644
--- a/lib/kstrtox.c
+++ b/lib/kstrtox.c
@@ -93,17 +93,56 @@ unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long
return _parse_integer_limit(s, base, p, INT_MAX);
}
-static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
+/**
+ * kstrntoull - convert a string to an unsigned long long with a maximum
+ * character limit
+ * @s: The start of the string. The string does not need to be null-terminated.
+ * The first character cannot be a sign.
+ * @base: The number base to use. The maximum supported base is 16. If base is
+ * given as 0, then the base of the string is automatically detected with the
+ * conventional semantics - If it begins with 0x the number will be parsed as a
+ * hexadecimal (case insensitive), if it otherwise begins with 0, it will be
+ * parsed as an octal number. Otherwise it will be parsed as a decimal.
+ * @res: Where to write the result of the conversion.
+ * @max_chars: The maximum number of characters to convert.
+ *
+ * Conversion stops when the maximum number of characters is reached or a
+ * non-digit character is encountered.
+ *
+ * Returns the number of characters consumed on success, -ERANGE on overflow and
+ * -EINVAL on invalid input. Return code must be checked.
+ */
+noinline
+ssize_t kstrntoull(const char *s, unsigned int base, unsigned long long *res,
+ size_t max_chars)
{
- unsigned long long _res;
+ const char *cp;
+ size_t prefix_cnt;
unsigned int rv;
- s = _parse_integer_fixup_radix(s, &base);
- rv = _parse_integer(s, base, &_res);
+ cp = _parse_integer_fixup_radix(s, &base);
+ prefix_cnt = cp - s;
+ if (prefix_cnt >= max_chars)
+ return -EINVAL;
+
+ rv = _parse_integer_limit(cp, base, res, max_chars - prefix_cnt);
if (rv & KSTRTOX_OVERFLOW)
return -ERANGE;
if (rv == 0)
return -EINVAL;
+
+ return prefix_cnt + rv;
+}
+EXPORT_SYMBOL(kstrntoull);
+
+static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
+{
+ unsigned long long _res;
+ ssize_t rv;
+
+ rv = kstrntoull(s, base, &_res, INT_MAX);
+ if (rv < 0)
+ return rv;
s += rv;
if (*s == '\n')
s++;
--
2.43.0
On Tue, 03 Mar 2026 13:27:07 +0000 Rodrigo Alencar via B4 Relay <devnull+rodrigo.alencar.analog.com@kernel.org> wrote: > From: Rodrigo Alencar <rodrigo.alencar@analog.com> > > Add kstrntoull() function, which converts a string to an ULL with a max > character limit. The function is an alternative integer parsing function > that does not require a null-terminated string. It becomes a better option > over simple_strtoull() or kstrtoull() when parsing integers from a buffer > with custom delimiters without having to create temporary copies. > The function is consumed inside the implementation _kstrtoull(), > promoting reuse. If you've got custom delimiters use a function that returns a pointer to the character that terminated the conversion. They save you having to find the delimiter as well as taking a copy. David
On 26/03/04 10:16AM, David Laight wrote:
> On Tue, 03 Mar 2026 13:27:07 +0000
> Rodrigo Alencar via B4 Relay <devnull+rodrigo.alencar.analog.com@kernel.org> wrote:
>
> > From: Rodrigo Alencar <rodrigo.alencar@analog.com>
> >
> > Add kstrntoull() function, which converts a string to an ULL with a max
> > character limit. The function is an alternative integer parsing function
> > that does not require a null-terminated string. It becomes a better option
> > over simple_strtoull() or kstrtoull() when parsing integers from a buffer
> > with custom delimiters without having to create temporary copies.
> > The function is consumed inside the implementation _kstrtoull(),
> > promoting reuse.
>
> If you've got custom delimiters use a function that returns a pointer
> to the character that terminated the conversion.
> They save you having to find the delimiter as well as taking a copy.
understood, how about this prototype then:
const char __must_check *kstrntoull(const char *s, unsigned int base,
unsigned long long *res, size_t max_chars);
to be used like:
end = kstrntoull(s, base, &res, INT_MAX);
if (IS_ERR(end)) {
/* return or handle error */
return PTR_ERR(end);
}
the name itself is still under discussion.
--
Kind regards,
Rodrigo Alencar
On 26/03/04 11:41AM, Rodrigo Alencar wrote:
> On 26/03/04 10:16AM, David Laight wrote:
> > On Tue, 03 Mar 2026 13:27:07 +0000
> > Rodrigo Alencar via B4 Relay <devnull+rodrigo.alencar.analog.com@kernel.org> wrote:
> >
> > > From: Rodrigo Alencar <rodrigo.alencar@analog.com>
> > >
> > > Add kstrntoull() function, which converts a string to an ULL with a max
> > > character limit. The function is an alternative integer parsing function
> > > that does not require a null-terminated string. It becomes a better option
> > > over simple_strtoull() or kstrtoull() when parsing integers from a buffer
> > > with custom delimiters without having to create temporary copies.
> > > The function is consumed inside the implementation _kstrtoull(),
> > > promoting reuse.
> >
> > If you've got custom delimiters use a function that returns a pointer
> > to the character that terminated the conversion.
> > They save you having to find the delimiter as well as taking a copy.
>
> understood, how about this prototype then:
>
> const char __must_check *kstrntoull(const char *s, unsigned int base,
> unsigned long long *res, size_t max_chars);
>
> to be used like:
>
> end = kstrntoull(s, base, &res, INT_MAX);
> if (IS_ERR(end)) {
> /* return or handle error */
> return PTR_ERR(end);
> }
Hi David,
Do you have any other feedback? the function prototype can also be changed as
follows:
int __must_check *kstrntoull(const char *s, const char **endp, unsigned int base,
unsigned long long *res, size_t max_chars);
so that a pointer to the terminated character is passes as a parameter.
which one would be the preference?
--
Kind regards,
Rodrigo Alencar
On Tue, 10 Mar 2026 09:26:11 +0000
Rodrigo Alencar <455.rodrigo.alencar@gmail.com> wrote:
> On 26/03/04 11:41AM, Rodrigo Alencar wrote:
> > On 26/03/04 10:16AM, David Laight wrote:
> > > On Tue, 03 Mar 2026 13:27:07 +0000
> > > Rodrigo Alencar via B4 Relay <devnull+rodrigo.alencar.analog.com@kernel.org> wrote:
> > >
> > > > From: Rodrigo Alencar <rodrigo.alencar@analog.com>
> > > >
> > > > Add kstrntoull() function, which converts a string to an ULL with a max
> > > > character limit. The function is an alternative integer parsing function
> > > > that does not require a null-terminated string. It becomes a better option
> > > > over simple_strtoull() or kstrtoull() when parsing integers from a buffer
> > > > with custom delimiters without having to create temporary copies.
> > > > The function is consumed inside the implementation _kstrtoull(),
> > > > promoting reuse.
> > >
> > > If you've got custom delimiters use a function that returns a pointer
> > > to the character that terminated the conversion.
> > > They save you having to find the delimiter as well as taking a copy.
> >
> > understood, how about this prototype then:
> >
> > const char __must_check *kstrntoull(const char *s, unsigned int base,
> > unsigned long long *res, size_t max_chars);
> >
> > to be used like:
> >
> > end = kstrntoull(s, base, &res, INT_MAX);
> > if (IS_ERR(end)) {
> > /* return or handle error */
> > return PTR_ERR(end);
> > }
>
> Hi David,
>
> Do you have any other feedback? the function prototype can also be changed as
> follows:
>
> int __must_check *kstrntoull(const char *s, const char **endp, unsigned int base,
> unsigned long long *res, size_t max_chars);
>
> so that a pointer to the terminated character is passes as a parameter.
> which one would be the preference?
>
I really don't see why you need to add 'yet another' function for parsing
integers.
Having to pre-scan the string for a separator seems just wrong.
The userspace strtoul() family do everything quite nicely apart from
overflow/limit checking.
There are a few options for overflow:
- Ignore it, this used to be what posix/sus allowed for command lines.
- Saturate.
- Return a pointer to the digit that makes the value too big as the
termination character - since the code will typically expect one
of ",.:-" this will be a syntax error.
It might be worth adding a parameter for the maximum value.
Then you only need one real function for 32bit and 64bit values.
But you also really want the use the function return value for the
converted number (for all sorts of reasons).
David
On 26/03/10 10:50AM, David Laight wrote:
> On Tue, 10 Mar 2026 09:26:11 +0000
> Rodrigo Alencar <455.rodrigo.alencar@gmail.com> wrote:
>
> > On 26/03/04 11:41AM, Rodrigo Alencar wrote:
> > > On 26/03/04 10:16AM, David Laight wrote:
> > > > On Tue, 03 Mar 2026 13:27:07 +0000
> > > > Rodrigo Alencar via B4 Relay <devnull+rodrigo.alencar.analog.com@kernel.org> wrote:
> > > >
> > > > > From: Rodrigo Alencar <rodrigo.alencar@analog.com>
> > > > >
> > > > > Add kstrntoull() function, which converts a string to an ULL with a max
> > > > > character limit. The function is an alternative integer parsing function
> > > > > that does not require a null-terminated string. It becomes a better option
> > > > > over simple_strtoull() or kstrtoull() when parsing integers from a buffer
> > > > > with custom delimiters without having to create temporary copies.
> > > > > The function is consumed inside the implementation _kstrtoull(),
> > > > > promoting reuse.
> > > >
> > > > If you've got custom delimiters use a function that returns a pointer
> > > > to the character that terminated the conversion.
> > > > They save you having to find the delimiter as well as taking a copy.
> > >
> > > understood, how about this prototype then:
> > >
> > > const char __must_check *kstrntoull(const char *s, unsigned int base,
> > > unsigned long long *res, size_t max_chars);
> > >
> > > to be used like:
> > >
> > > end = kstrntoull(s, base, &res, INT_MAX);
> > > if (IS_ERR(end)) {
> > > /* return or handle error */
> > > return PTR_ERR(end);
> > > }
> >
> > Hi David,
> >
> > Do you have any other feedback? the function prototype can also be changed as
> > follows:
> >
> > int __must_check *kstrntoull(const char *s, const char **endp, unsigned int base,
> > unsigned long long *res, size_t max_chars);
> >
> > so that a pointer to the terminated character is passes as a parameter.
> > which one would be the preference?
> >
>
> I really don't see why you need to add 'yet another' function for parsing
> integers.
> Having to pre-scan the string for a separator seems just wrong.
there is no pre-scanning, the function stops at a non-digit character or
at the request amount of chars. That behavior is already implemented by
the internal parsing functions. The function is just exposing this.
> The userspace strtoul() family do everything quite nicely apart from
> overflow/limit checking.
> There are a few options for overflow:
> - Ignore it, this used to be what posix/sus allowed for command lines.
That is the whole point why simple_strtoull() is not recommended, being
flagged by checkpatch.
One thing to note is that kstrtoull() does check for overflows, but
it forces you to comply with a termination character. In the case you
have the integer in a string with separators, you would have to create
temporary copies of the string... and that is, in fact, not effective,
because it requires pre-scanning and copying, hence the existance of
simple_strtoull().
But indeed, I could use simple_strtoull(), ignore this and be done
with it.
> - Saturate.
> - Return a pointer to the digit that makes the value too big as the
> termination character - since the code will typically expect one
> of ",.:-" this will be a syntax error.
There would not be a way to do that if granular control of the
parsing is not provided.
> It might be worth adding a parameter for the maximum value.
> Then you only need one real function for 32bit and 64bit values.
Not seeing a reason for that, as range limits can be checked after
the parsing. Here we just make sure that the parsed value fits in
64-bits.
> But you also really want the use the function return value for the
> converted number (for all sorts of reasons).
--
Kind regards,
Rodrigo Alencar
On Tue, Mar 03, 2026 at 01:27:07PM +0000, Rodrigo Alencar via B4 Relay wrote: > Add kstrntoull() function, which converts a string to an ULL with a max > character limit. The function is an alternative integer parsing function > that does not require a null-terminated string. It becomes a better option null --> NUL > over simple_strtoull() or kstrtoull() when parsing integers from a buffer > with custom delimiters without having to create temporary copies. > The function is consumed inside the implementation _kstrtoull(), > promoting reuse. But this will not properly convert 0000000000000000000000000000000000000000100, for example, if the max_chars say set to 20. Also kstrto*() have a common idea behind to consume the only \n and allowed digits. This (naming) doesn't fit into the kstrto*() category. -- With Best Regards, Andy Shevchenko
On 26/03/03 03:49PM, Andy Shevchenko wrote: > On Tue, Mar 03, 2026 at 01:27:07PM +0000, Rodrigo Alencar via B4 Relay wrote: > > > Add kstrntoull() function, which converts a string to an ULL with a max > > character limit. The function is an alternative integer parsing function > > that does not require a null-terminated string. It becomes a better option > > null --> NUL > > > over simple_strtoull() or kstrtoull() when parsing integers from a buffer > > with custom delimiters without having to create temporary copies. > > The function is consumed inside the implementation _kstrtoull(), > > promoting reuse. > > But this will not properly convert 0000000000000000000000000000000000000000100, > for example, if the max_chars say set to 20. Why would I want that? truncation will happen in the case and the value will be zero. max_chars can be zet to INT_MAX/SIZE_MAX if you want to get 100. > Also kstrto*() have a common idea behind to consume the only \n and allowed > digits. This (naming) doesn't fit into the kstrto*() category. mmm ok, but include/linux/kstrtox.h is the right place for this? how about just strntoull()? I feel like a safe_ prefix does not make much sense if it is only to differentiate from simple_strto*(), which should have been safe at the first place. -- Kind regards, Rodrigo Alencar
On 26/03/03 02:16PM, Rodrigo Alencar wrote: > On 26/03/03 03:49PM, Andy Shevchenko wrote: > > On Tue, Mar 03, 2026 at 01:27:07PM +0000, Rodrigo Alencar via B4 Relay wrote: > > > > > Add kstrntoull() function, which converts a string to an ULL with a max > > > character limit. The function is an alternative integer parsing function > > > that does not require a null-terminated string. It becomes a better option > > > > null --> NUL > > > > > over simple_strtoull() or kstrtoull() when parsing integers from a buffer > > > with custom delimiters without having to create temporary copies. > > > The function is consumed inside the implementation _kstrtoull(), > > > promoting reuse. > > > > But this will not properly convert 0000000000000000000000000000000000000000100, > > for example, if the max_chars say set to 20. > > Why would I want that? truncation will happen in the case and the value will > be zero. max_chars can be zet to INT_MAX/SIZE_MAX if you want to get 100. > > > Also kstrto*() have a common idea behind to consume the only \n and allowed > > digits. This (naming) doesn't fit into the kstrto*() category. > > mmm ok, but include/linux/kstrtox.h is the right place for this? how about just > strntoull()? I feel like a safe_ prefix does not make much sense if it is > only to differentiate from simple_strto*(), which should have been safe at > the first place. Also kstrntoull() does not really match kstrto*(), as the 'n' is often used to indicate a stop condition on amount of characters, which would not need to require any termination character at all. The 'k' prefix was add to 'strntoull', mostly because the function is being added to the include/linux/kstrtox.h file. Other names I could think off: - bounded_strtoull() - bstrtoull() - 'b' for bounded - bstrntoull() - strtoull_bounded() - strtoull_limit() - safe_strntoull() - emphasizes overflow safety over simple_strtoull() Extras considerations: - Single-letter prefixes (bstrntoull, lstrntoull, etc.) are too cryptic for a public API - safe_ prefix is subjective and doesn't describe the actual behavior kstrntoull() is still my first candidate, other than that it would be bounded_strtoull(). -- Kind regards, Rodrigo Alencar
On 26/03/04 10:02AM, Rodrigo Alencar wrote: > On 26/03/03 02:16PM, Rodrigo Alencar wrote: > > On 26/03/03 03:49PM, Andy Shevchenko wrote: > > > On Tue, Mar 03, 2026 at 01:27:07PM +0000, Rodrigo Alencar via B4 Relay wrote: > > > > > > > Add kstrntoull() function, which converts a string to an ULL with a max > > > > character limit. The function is an alternative integer parsing function > > > > that does not require a null-terminated string. It becomes a better option > > > > > > null --> NUL > > > > > > > over simple_strtoull() or kstrtoull() when parsing integers from a buffer > > > > with custom delimiters without having to create temporary copies. > > > > The function is consumed inside the implementation _kstrtoull(), > > > > promoting reuse. > > > > > > But this will not properly convert 0000000000000000000000000000000000000000100, > > > for example, if the max_chars say set to 20. > > > > Why would I want that? truncation will happen in the case and the value will > > be zero. max_chars can be zet to INT_MAX/SIZE_MAX if you want to get 100. > > > > > Also kstrto*() have a common idea behind to consume the only \n and allowed > > > digits. This (naming) doesn't fit into the kstrto*() category. > > > > mmm ok, but include/linux/kstrtox.h is the right place for this? how about just > > strntoull()? I feel like a safe_ prefix does not make much sense if it is > > only to differentiate from simple_strto*(), which should have been safe at > > the first place. > > Also kstrntoull() does not really match kstrto*(), as the 'n' is often used > to indicate a stop condition on amount of characters, which would not need > to require any termination character at all. > The 'k' prefix was add to 'strntoull', mostly because the function is being > added to the include/linux/kstrtox.h file. Other names I could think off: > - bounded_strtoull() > - bstrtoull() - 'b' for bounded > - bstrntoull() > - strtoull_bounded() > - strtoull_limit() > - safe_strntoull() - emphasizes overflow safety over simple_strtoull() > > Extras considerations: > - Single-letter prefixes (bstrntoull, lstrntoull, etc.) are too cryptic > for a public API > - safe_ prefix is subjective and doesn't describe the actual behavior > > kstrntoull() is still my first candidate, other than that it would be > bounded_strtoull(). Hi Andy, could you provide more feedback here? Thanks! -- Kind regards, Rodrigo Alencar
On Fri, Mar 20, 2026 at 11:16:32AM +0000, Rodrigo Alencar wrote: > On 26/03/04 10:02AM, Rodrigo Alencar wrote: > > On 26/03/03 02:16PM, Rodrigo Alencar wrote: > > > On 26/03/03 03:49PM, Andy Shevchenko wrote: > > > > On Tue, Mar 03, 2026 at 01:27:07PM +0000, Rodrigo Alencar via B4 Relay wrote: > > > > > > > > > Add kstrntoull() function, which converts a string to an ULL with a max > > > > > character limit. The function is an alternative integer parsing function > > > > > that does not require a null-terminated string. It becomes a better option > > > > > > > > null --> NUL > > > > > > > > > over simple_strtoull() or kstrtoull() when parsing integers from a buffer > > > > > with custom delimiters without having to create temporary copies. > > > > > The function is consumed inside the implementation _kstrtoull(), > > > > > promoting reuse. > > > > > > > > But this will not properly convert 0000000000000000000000000000000000000000100, > > > > for example, if the max_chars say set to 20. > > > > > > Why would I want that? truncation will happen in the case and the value will > > > be zero. max_chars can be zet to INT_MAX/SIZE_MAX if you want to get 100. > > > > > > > Also kstrto*() have a common idea behind to consume the only \n and allowed > > > > digits. This (naming) doesn't fit into the kstrto*() category. > > > > > > mmm ok, but include/linux/kstrtox.h is the right place for this? how about just > > > strntoull()? I feel like a safe_ prefix does not make much sense if it is > > > only to differentiate from simple_strto*(), which should have been safe at > > > the first place. > > > > Also kstrntoull() does not really match kstrto*(), as the 'n' is often used > > to indicate a stop condition on amount of characters, which would not need > > to require any termination character at all. > > The 'k' prefix was add to 'strntoull', mostly because the function is being > > added to the include/linux/kstrtox.h file. Other names I could think off: > > - bounded_strtoull() > > - bstrtoull() - 'b' for bounded > > - bstrntoull() > > - strtoull_bounded() > > - strtoull_limit() > > - safe_strntoull() - emphasizes overflow safety over simple_strtoull() > > > > Extras considerations: > > - Single-letter prefixes (bstrntoull, lstrntoull, etc.) are too cryptic > > for a public API > > - safe_ prefix is subjective and doesn't describe the actual behavior > > > > kstrntoull() is still my first candidate, other than that it would be > > bounded_strtoull(). > > could you provide more feedback here? Thanks! I don't know what new I can add here. My suggestion was (and still is) to have something in *_strtoull() family with additional checks added, but no limitations on the input string (i.e. no max_chars). If you look at the printf() code the max_chars was added solely for scanf() and has no use otherwise (yes, I know about and aware of initramfs case). -- With Best Regards, Andy Shevchenko
On 26/03/20 01:50PM, Andy Shevchenko wrote: > On Fri, Mar 20, 2026 at 11:16:32AM +0000, Rodrigo Alencar wrote: > > On 26/03/04 10:02AM, Rodrigo Alencar wrote: > > > On 26/03/03 02:16PM, Rodrigo Alencar wrote: > > > > On 26/03/03 03:49PM, Andy Shevchenko wrote: > > > > > On Tue, Mar 03, 2026 at 01:27:07PM +0000, Rodrigo Alencar via B4 Relay wrote: > > > > > > > > > > > Add kstrntoull() function, which converts a string to an ULL with a max > > > > > > character limit. The function is an alternative integer parsing function > > > > > > that does not require a null-terminated string. It becomes a better option > > > > > > > > > > null --> NUL > > > > > > > > > > > over simple_strtoull() or kstrtoull() when parsing integers from a buffer > > > > > > with custom delimiters without having to create temporary copies. > > > > > > The function is consumed inside the implementation _kstrtoull(), > > > > > > promoting reuse. > > > > > > > > > > But this will not properly convert 0000000000000000000000000000000000000000100, > > > > > for example, if the max_chars say set to 20. > > > > > > > > Why would I want that? truncation will happen in the case and the value will > > > > be zero. max_chars can be zet to INT_MAX/SIZE_MAX if you want to get 100. > > > > > > > > > Also kstrto*() have a common idea behind to consume the only \n and allowed > > > > > digits. This (naming) doesn't fit into the kstrto*() category. > > > > > > > > mmm ok, but include/linux/kstrtox.h is the right place for this? how about just > > > > strntoull()? I feel like a safe_ prefix does not make much sense if it is > > > > only to differentiate from simple_strto*(), which should have been safe at > > > > the first place. > > > > > > Also kstrntoull() does not really match kstrto*(), as the 'n' is often used > > > to indicate a stop condition on amount of characters, which would not need > > > to require any termination character at all. > > > The 'k' prefix was add to 'strntoull', mostly because the function is being > > > added to the include/linux/kstrtox.h file. Other names I could think off: > > > - bounded_strtoull() > > > - bstrtoull() - 'b' for bounded > > > - bstrntoull() > > > - strtoull_bounded() > > > - strtoull_limit() > > > - safe_strntoull() - emphasizes overflow safety over simple_strtoull() > > > > > > Extras considerations: > > > - Single-letter prefixes (bstrntoull, lstrntoull, etc.) are too cryptic > > > for a public API > > > - safe_ prefix is subjective and doesn't describe the actual behavior > > > > > > kstrntoull() is still my first candidate, other than that it would be > > > bounded_strtoull(). > > > > could you provide more feedback here? Thanks! > > I don't know what new I can add here. > > My suggestion was (and still is) to have something in *_strtoull() family > with additional checks added, but no limitations on the input string (i.e. > no max_chars). If you look at the printf() code the max_chars was added > solely for scanf() and has no use otherwise (yes, I know about and aware > of initramfs case). but is it include/linux/kstrtox.h the right place for this? *_strtoull familly... then can we just expose simple_strntoull(), which is private to lib/vsprintf.c, by changing its prototype to expose a error return? In my case the limitation on the input string is useful for the truncation of decimal places when parsing the fixed point value. It would avoid a 64-bit division. -- Kind regards, Rodrigo Alencar
On Fri, Mar 20, 2026 at 12:08:41PM +0000, Rodrigo Alencar wrote: > On 26/03/20 01:50PM, Andy Shevchenko wrote: > > On Fri, Mar 20, 2026 at 11:16:32AM +0000, Rodrigo Alencar wrote: > > > On 26/03/04 10:02AM, Rodrigo Alencar wrote: ... > > > could you provide more feedback here? Thanks! > > > > I don't know what new I can add here. > > > > My suggestion was (and still is) to have something in *_strtoull() family > > with additional checks added, but no limitations on the input string (i.e. > > no max_chars). If you look at the printf() code the max_chars was added > > solely for scanf() and has no use otherwise (yes, I know about and aware > > of initramfs case). > > but is it include/linux/kstrtox.h the right place for this? Seems so, there simple_strto*() are declared. > *_strtoull familly... then can we just expose simple_strntoull(), which is > private to lib/vsprintf.c, by changing its prototype to expose a error return? Why do you need that? I'm lost, sorry, I don't understand this big desire of having that max_chars parameter. > In my case the limitation on the input string is useful for the truncation of > decimal places when parsing the fixed point value. It would avoid a 64-bit > division. How is it better than checking the returned end pointer? Just treat anything that parses too many digits after dot as invalid input? ret = ..._strtoull(..., &end, &result); if (ret) return ret; // overflow! if (end - start > $YOUR_LIMIT) return -EINVAL; // bad input ...process result... ... Some (stupid) thoughts loudly. IIUC even if we implement '%g' in scanf(), it wont help you as you want to have more precise values. Do I get it correct? -- With Best Regards, Andy Shevchenko
On 26/03/20 02:24PM, Andy Shevchenko wrote: > On Fri, Mar 20, 2026 at 12:08:41PM +0000, Rodrigo Alencar wrote: > > On 26/03/20 01:50PM, Andy Shevchenko wrote: > > > On Fri, Mar 20, 2026 at 11:16:32AM +0000, Rodrigo Alencar wrote: > > > > On 26/03/04 10:02AM, Rodrigo Alencar wrote: > > ... > > > > > could you provide more feedback here? Thanks! > > > > > > I don't know what new I can add here. > > > > > > My suggestion was (and still is) to have something in *_strtoull() family > > > with additional checks added, but no limitations on the input string (i.e. > > > no max_chars). If you look at the printf() code the max_chars was added > > > solely for scanf() and has no use otherwise (yes, I know about and aware > > > of initramfs case). > > > > but is it include/linux/kstrtox.h the right place for this? > > Seems so, there simple_strto*() are declared. > > > *_strtoull familly... then can we just expose simple_strntoull(), which is > > private to lib/vsprintf.c, by changing its prototype to expose a error return? > > Why do you need that? I'm lost, sorry, I don't understand this big desire of > having that max_chars parameter. > > > In my case the limitation on the input string is useful for the truncation of > > decimal places when parsing the fixed point value. It would avoid a 64-bit > > division. > > How is it better than checking the returned end pointer? Just treat anything > that parses too many digits after dot as invalid input? > > ret = ..._strtoull(..., &end, &result); here I would want to pass max_chars as the precision of the fixed point parsing > if (ret) > return ret; // overflow! > > if (end - start > $YOUR_LIMIT) > return -EINVAL; // bad input > > ...process result... otherwise, here I would need to check the amount of parsed characters and perform a 64-bit division if it goes beyond the desired precision. Also, having max_chars allows for more flexible usage of the parsing function. this is the prototype of simple_strntoull() that would be thinking on expose: int simple_strntoull(const char *startp, char **endp, unsigned long long *res, unsigned int base, size_t max_chars) that would also allow to drop the existing FIXME in simple_strntoull(). > Some (stupid) thoughts loudly. IIUC even if we implement '%g' in scanf(), it > wont help you as you want to have more precise values. Do I get it correct? If I am parsing 3.14159265359 with 6 decimal precision I want to stop at: frac = 141592 int = 3 and ignore the rest. -- Kind regards, Rodrigo Alencar
On Fri, 20 Mar 2026 12:41:57 +0000
Rodrigo Alencar <455.rodrigo.alencar@gmail.com> wrote:
...
> > Some (stupid) thoughts loudly. IIUC even if we implement '%g' in scanf(), it
> > wont help you as you want to have more precise values. Do I get it correct?
>
> If I am parsing 3.14159265359 with 6 decimal precision I want to stop at:
>
> frac = 141592
> int = 3
>
> and ignore the rest.
>
If you add an 'upper limit' parameter and return a pointer to the digit
that exceeds the limit (which would normally get processed as a syntax error)
then you could have:
int_part = strtoull(pi, &end, ~0ull, 10);
if (end[0] == '.' && isdigit(end[1])) {
frac = strtoull(end + 2, &end, 999999, 10);
while (isdigit(*end))
end++;
}
Passing in the limit should help strtol() are strtoi() as well.
David
On Fri, Mar 20, 2026 at 12:41:57PM +0000, Rodrigo Alencar wrote: > On 26/03/20 02:24PM, Andy Shevchenko wrote: > > On Fri, Mar 20, 2026 at 12:08:41PM +0000, Rodrigo Alencar wrote: > > > On 26/03/20 01:50PM, Andy Shevchenko wrote: > > > > On Fri, Mar 20, 2026 at 11:16:32AM +0000, Rodrigo Alencar wrote: > > > > > On 26/03/04 10:02AM, Rodrigo Alencar wrote: ... > > > > > could you provide more feedback here? Thanks! > > > > > > > > I don't know what new I can add here. > > > > > > > > My suggestion was (and still is) to have something in *_strtoull() family > > > > with additional checks added, but no limitations on the input string (i.e. > > > > no max_chars). If you look at the printf() code the max_chars was added > > > > solely for scanf() and has no use otherwise (yes, I know about and aware > > > > of initramfs case). > > > > > > but is it include/linux/kstrtox.h the right place for this? > > > > Seems so, there simple_strto*() are declared. > > > > > *_strtoull familly... then can we just expose simple_strntoull(), which is > > > private to lib/vsprintf.c, by changing its prototype to expose a error return? > > > > Why do you need that? I'm lost, sorry, I don't understand this big desire of > > having that max_chars parameter. > > > > > In my case the limitation on the input string is useful for the truncation of > > > decimal places when parsing the fixed point value. It would avoid a 64-bit > > > division. > > > > How is it better than checking the returned end pointer? Just treat anything > > that parses too many digits after dot as invalid input? > > > > ret = ..._strtoull(..., &end, &result); > > here I would want to pass max_chars as the precision of the fixed point parsing > > > if (ret) > > return ret; // overflow! > > > > if (end - start > $YOUR_LIMIT) > > return -EINVAL; // bad input > > > > ...process result... > > otherwise, here I would need to check the amount of parsed characters and > perform a 64-bit division if it goes beyond the desired precision. > Also, having max_chars allows for more flexible usage of the parsing function. > > this is the prototype of simple_strntoull() that would be thinking on expose: > > int simple_strntoull(const char *startp, char **endp, > unsigned long long *res, unsigned int base, > size_t max_chars) > > that would also allow to drop the existing FIXME in simple_strntoull(). That's fine, but the prototype should be rather int simple_strntoull(const char *startp, char **endp, unsigned int base, size_t max_chars, unsigned long long *res) > > Some (stupid) thoughts loudly. IIUC even if we implement '%g' in scanf(), it > > wont help you as you want to have more precise values. Do I get it correct? > > If I am parsing 3.14159265359 with 6 decimal precision I want to stop at: > > frac = 141592 > int = 3 This is different to what strto*() usually do. From my p.o.v. this is simply an invalid input, and TBH, the parsing of this is not as trivial as flooring the result. One might want ceiling it, and see the difference when it's about signed value. So, if one wants lesser precision they need to set the rules, and not the library, because there are several rules that the user may want to adjust. P.S. Avoiding division in your case is copying a (sub)string and using kstrto*() on it. I believe it's always a room for 20-30 bytes on the stack for that, and it will be much faster than division, indeed. -- With Best Regards, Andy Shevchenko
© 2016 - 2026 Red Hat, Inc.