Source-Changes-D archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: CVS commit: src/bin/sleep



    Date:        Sun, 27 Jan 2019 22:56:17 +0100
    From:        Kamil Rytarowski <n54%gmx.com@localhost>
    Message-ID:  <1906f04e-93b9-a2c5-62a0-bf430ca60deb%gmx.com@localhost>

  |  Passing to sleep 1,2 or 1.000 makes as much sense

The question isn't really whether it makes sense, that's up
to the user to decide, not us, but whether it could be interpreted
any other way.

The first of those has "worked" on NetBSD ever since support
for fractional seconds got added (whaver the locale) until very
recently - where "worked" is in quotes as the sleep might have
lasted for one second, or one and one fifth seconds, or as close
to that as the system can manage, but there would have been a
1 second (approx) sleep in any case).

The second case is ambiguous, which is (I presume) why no-one
is expecting that to ever mean anything except a very precise 1,
and why the grouping chars are never supported for input., whatever
they are, and only works to the extent that the extra input precision is
completely ignored, and does not cause sleep to attempt to really
only last exacly 1 second, rather than perhaps 1 second and 5
milliseconds, which "sleep 1" might delay for (or even longer.)

A better question than "does it make sense" is "what else could
it reasonably mean", and if there is no other answer than "nothing"
(which is true for the first of those, but not the second) then when
there is no other meaning that makes sense, ask "is there any
plausible potential use for this?" and if the answer to that is yes,
then why not support it?

Incidentally, the better input to have asked about would have been
0,2 as until recently, that one did not "work" in any sense unless
the locale uses ',' as the radix char (and that has not changed)
or 0.2 (the kind of example that caused this discussion) when the
radix char is ',' (or something other than '.').   No-one here is
disputing that the 0.2 case should always work, and not be an
error.   That is what was fixed.   The only question is whether there
is any harm in also accepting the 0,2 form when ',' is the
"decimal point".

  | as passing to it 1000USD.

Until PR 53910 was pre-emptively fixed recenty, that one would
also have "worked" (though the perhaps slightly more common
in many areas, USD1000, would not) .

That PR needed to be fixed, even before it was filed, as stray
characters after the numeric value are more likely to be something
attempting linux "sleep 2m" (ie: sleep 120) raher than someone
attempting to sleep for a currency value.   And that does need
to be detected as an error, unlike "sleep 1,2" (or even sleep 0,2)
which does no real harm, even if it was an accident (we're
talking about a sleep of some extra fraction of a second...)

kre

ps: Another command affected by all of this is "seq" which also
takes floating point command line args.   That is not in posix,
so we get no guidance there.   This one is a very odd case, the
first three executable lines in it are ...

        /* Determine the locale's decimal point. */
        locale = localeconv();
        if (locale && locale->decimal_point && locale->decimal_point[0] != '\0')
                decimal_point = locale->decimal_point;

and then it does everything (validating input, ...) based upon that
"decimal_point" variable, to the extent of (properly it seems to me
from just reading the code) dealing with the possibility that the
"decimal_point" might be a multiple byte string (ie: not '.' or ','
but perhaps something with a 2 byte or longer UTF-8 encoding,
or something).   That is, it uses "strstr()" to locate the radix.

That is, it is very clearly and very explicitly written to accept, and
generate, input and output in the user's locale.

Except ...

Note the "first three executable lines" and consider the implication
of that .... there is no setlocale() call, which means the program is
required to run in the C locale ignoring LC_* environment vars,
and therefore, "locale" there is always the C locale, and consequently
decimal_point is always "." and all of the (considerable) work that
the code goes to to be able to operate in different locales is wasted.

seq seems to have mostly come from Plan-9 where the requirement
for setlocale() presumably (I have never run it, or even seen it
running) does not exist, and locales are simply always used if set.

I do not plan on "fixing" this any time soon (the FreeBSD version
was taken from ours, and has the same issue, exactly, OpenBSD
do not have seq at all, and linux, which had it before us, have,
I think, just - within the past couple of days  - made it (and sleep)
handle both the C locale, and the user's locale, interchangably.

But if we do decide to leave sleep as it is now, then it will make sense
to fix seq to have the same flexibility, but that one is not going to
be a trivial change - as it is written now, it really only wants to operate
in a single locate (whatever it is) and not in the user's locale, or the
C locale, whichever works better...

Perhaps for that one, a better fix than just accepting numbers in either
locale, and generating the sequence in the user's locale (which is what
might happen) would be to intuit the locale (when floats are used, which
is all that matters in this case) from the input, so if the floating input works
for the user's locale, use that, for both input and output, and if not, switch
completely to the C locale, and use that for both input and output.

That way "seq 0.3 0.1 0.8" would work, and generate a C locale
sequence of numbers, and in an appropriate locale "seq 0,3 0,1 0,8"
would work, and generate a sequence of numbers appropriate to that
locale, and in all cases "sed 0,3 0.1 0.8" (and similar) would be an error.

Doing that would probably be easier (less intrusive) for seq than simply
allowing it to accept numbers in either locale, while generating them
in the user's locale.

We also have to decide what to do with printf...   Linux is (also recently
I believe) accepting numbers in either locale, and generating them in
the user's locale.   Our /usr/bin/printf takes numbers in the user's locale
and generates them that way.  The printf built into /bin/sh (and csh I
think) only allows the C locale, as (because of current sh limitations)
built-ins are not permitted to change the locale.    That will eventually
get fixed in sh (it has been already in FreeBSD.)



Home | Main Index | Thread Index | Old Index