Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 22 Aug 2013 01:24:13 +0400
From:      Sergey Kandaurov <pluknet@freebsd.org>
To:        Jilles Tjoelker <jilles@stack.nl>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org, Andrey Chernov <ache@freebsd.org>
Subject:   Re: svn commit: r254600 - head/lib/libutil
Message-ID:  <20130821212413.GC52908@omg>
In-Reply-To: <20130821202725.GA4991@stack.nl>
References:  <201308211646.r7LGk6eV051215@svn.freebsd.org> <5214F72B.7070006@freebsd.org> <20130821190309.GB52908@omg> <20130821202725.GA4991@stack.nl>

next in thread | previous in thread | raw e-mail | index | archive | help

--8TaQrIeukR7mmbKf
Content-Type: multipart/mixed; boundary="Yb+qhiCg54lqZFXW"
Content-Disposition: inline


--Yb+qhiCg54lqZFXW
Content-Type: text/plain; charset=koi8-r
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Wed, Aug 21, 2013 at 10:27:25PM +0200, Jilles Tjoelker wrote:
> On Wed, Aug 21, 2013 at 11:03:10PM +0400, Sergey Kandaurov wrote:
> > On Wed, Aug 21, 2013 at 09:21:47PM +0400, Andrey Chernov wrote:
> > > On 21.08.2013 20:46, Sergey Kandaurov wrote:
> > > >  	number =3D strtoumax(buf, &endptr, 0);
> > > > =20
> > > > +	if (number =3D=3D UINTMAX_MAX && errno =3D=3D ERANGE) {
> > > > +		return (-1);
> > > > +	}
>=20
> > > You need to reset errno before strtoumax() call (errno =3D 0), becaus=
e any
> > > of previous functions may left it as ERANGE.
>=20
> > Thanks for pointing out.
> > Does the patch look good?
>=20
> > Index: expand_number.c
> > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> > --- expand_number.c     (revision 254600)
> > +++ expand_number.c     (working copy)
> > @@ -53,6 +53,8 @@
> >         unsigned shift;
> >         char *endptr;
> > =20
> > +       errno =3D 0;
> > +
> >         number =3D strtoumax(buf, &endptr, 0);
> > =20
> >         if (number =3D=3D UINTMAX_MAX && errno =3D=3D ERANGE) {
> >=20
>=20
> This may cause the function to set errno=3D0 if it is successful, which is
> not allowed for standard library functions from C and POSIX. There may
> be a problem not only if expand_number() is standardized but also if it
> is used in the implementation of a standard library function. The best
> solution is to save and restore errno around this (if [ERANGE] is
> detected, that is a valid errno value to keep).
>=20
> In an application it is acceptable to set errno=3D0 without further ado.
>=20

What about this change?
It changes errno only if it was modified from zero in strtoumax().
Unconditionally restoring errno after strtoumax() unless ERANGE is
probably not good as strtoumax() might set different errno (e.g. EINVAL)
and we might want to keep it as well.  Please correct me, if I'm wrong.

Index: lib/libutil/expand_number.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- lib/libutil/expand_number.c (revision 254600)
+++ lib/libutil/expand_number.c (working copy)
@@ -50,15 +50,22 @@
 expand_number(const char *buf, uint64_t *num)
 {
        uint64_t number;
+       int saved_errno;
        unsigned shift;
        char *endptr;
=20
+       saved_errno =3D errno;
+       errno =3D 0;
+
        number =3D strtoumax(buf, &endptr, 0);
=20
        if (number =3D=3D UINTMAX_MAX && errno =3D=3D ERANGE) {
                return (-1);
        }
=20
+       if (errno =3D=3D 0)
+               errno =3D saved_errno;
+
        if (endptr =3D=3D buf) {
                /* No valid digits. */
                errno =3D EINVAL;


--Yb+qhiCg54lqZFXW
Content-Type: text/x-diff; charset=koi8-r
Content-Disposition: attachment; filename="expand_number.2.diff"
Content-Transfer-Encoding: quoted-printable

Index: lib/libutil/expand_number.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- lib/libutil/expand_number.c	(revision 254600)
+++ lib/libutil/expand_number.c	(working copy)
@@ -50,15 +50,22 @@
 expand_number(const char *buf, uint64_t *num)
 {
 	uint64_t number;
+	int saved_errno;
 	unsigned shift;
 	char *endptr;
=20
+	saved_errno =3D errno;
+	errno =3D 0;
+
 	number =3D strtoumax(buf, &endptr, 0);
=20
 	if (number =3D=3D UINTMAX_MAX && errno =3D=3D ERANGE) {
 		return (-1);
 	}
=20
+	if (errno =3D=3D 0)
+		errno =3D saved_errno;
+
 	if (endptr =3D=3D buf) {
 		/* No valid digits. */
 		errno =3D EINVAL;

--Yb+qhiCg54lqZFXW--

--8TaQrIeukR7mmbKf
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.20 (FreeBSD)

iQEcBAEBAgAGBQJSFS/9AAoJED9Ol7oQYHQZ0pkIAIYQRN1biQO+lAAir+EFeF0m
RmU8Q7LE9G+5AAoAkUN+xJW53blML7aBi7RLlpEHvPrPszPWPaR3KJ/TxUGiX1f4
wrRdPsHdqA0od8yI46EN3LixLjxwxIHlWW/FK2DW6Dp2tZuaYjsal6t8R+9OSlvX
HL834c2Yz5U2652AnFsm3sNNIVcFHCPCrue1ygZITE4boCTI0SJaFdRVic2PrxYI
z4tEbhavm77ecxomS82hO6wR2OUVAMXaSsKdVtkpdlmHJllssDMADlKBCFRQPJDG
vwHIxWeSNoxlNxt5QCWvn9eVx4SSMYT8wOi5XzmrzeXIUKpB6Wx3tHbuULXEnYo=
=uKp9
-----END PGP SIGNATURE-----

--8TaQrIeukR7mmbKf--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130821212413.GC52908>