Menu

#1 Locale != C caused trouble reading uptime

Unstable_(example)
open-accepted
nobody
None
5
2003-05-29
2003-01-23
Pit Palme
No

I've run upclient-5.0b7 with active locales, locale set to
de_DE.

Upclient exited in stats-lnx.c line 247, because the

fscanf() for two floating values in "/proc/uptime" failed.

That's normal as the values in "/proc/uptime" are decimal
delimited by a period, the German locale made the
decimal delimiter the comma.

Attached patch simply sets locale to "C", reads the
values and sets locale back to "" (environment decides).

This helped here, if there's a better way I don't insist on
this patch ... if the issue is solved I don't care how :-)

Discussion

  • Pit Palme

    Pit Palme - 2003-01-23

    Logged In: YES
    user_id=326024

    Sorry, file upload seem not to have worked :-/

     
  • Pit Palme

    Pit Palme - 2003-01-23

    Diff to work around "locale decimal delimiter" problem in fscanf(..., "%lf", ...)

     
  • Carsten Klapp

    Carsten Klapp - 2003-04-11

    Logged In: YES
    user_id=369655

    Thanks for the patch, I will take a look at your workaround soon and probably incorprate it as-is, as I can't think of any other solution at the moment. I do want to see UpClient to work with other lanaguages especially standrd metric notiation of comma decimal point "," instead of only the obsolete North-American period "." style.

    Thanks for bringing it this to my attention.

     
  • Carsten Klapp

    Carsten Klapp - 2003-05-27

    Logged In: YES
    user_id=369655

    Would you download and run this little test program and send me the
    results?

    http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/localedata/
    ?cvsroot=glibc

    Grab three files: tst-numeric.c tst-numeric.data tst-numeric.sh

    This program will testtheimplementationofLC_NUMERICandsnprintf
    in your system's glibc.

    By default it checks C and norwegian, you should add a couple lines to
    the bottom of tst-numeric.data for de_DE and see how it goes:
    de_DE%'g123.45123,45
    de_DE.ISO-8859-1%'g123.45123,45

    It may be you need to set your locale to something like de_DE.ISO-
    8859-1 instead of just de_DE.

    You can try running an (unpatched) upclient this way:
    export LC_NUMERIC=C
    upclient

     
  • Carsten Klapp

    Carsten Klapp - 2003-05-28
    • status: open --> closed
     
  • Carsten Klapp

    Carsten Klapp - 2003-05-28
    • status: closed --> closed-fixed
     
  • Carsten Klapp

    Carsten Klapp - 2003-05-28

    Logged In: YES
    user_id=369655

    Finally here is what I found out:

    There is a bug (rather, "braindead-edness") in procps, which is maintained
    by RedHat: when locale settings where the decimal point is a comma--
    probably most of Europe which uses SI notation--then scanf on /proc/
    loadavg etc. doesn't work.

    Supposedly a patch to procps-2.0.7/proc/sysinfo.c was submitted ages ago
    but it has not been incorporated yet.

    A workaround in UpClient has now been applied to CVS and the fix will be
    part of the next release 5.0b9.

    Thanks!
    Carsten

    Ref.:

    http://216.239.33.100/search?q=cache:LKPHtsyVSFwJ:www.cs.helsinki.fi/
    linux/linux-kernel/2001-02/0429.html+/
    proc+LC_NUMERIC&hl=en&ie=UTF-8

    http://ftp.at.linuxfromscratch.org/pub/lfs/lfs-patches/procps-2.0.7-
    i18n.patch

    http://sources.redhat.com/cgi-bin/cvsweb.cgi/procps/proc/
    sysinfo.c?rev=1.30&content-type=text/x-cvsweb-markup&cvsroot=procps

     
  • Pit Palme

    Pit Palme - 2003-05-29

    Logged In: YES
    user_id=326024

    Albeit you're right in general some comments from my side:

    1.) I don't use a RedHat, but a Debian and nevertheless ran
    into the locales-decimal-delimiter problem.
    2.) The procps package shipped with Debian (at least with
    Woody) has already applied this patch, I've just checked the
    sources / Debian-diffs
    3.) This patch affects only user space tools reading from /proc
    in a very similar fashion UpClient does. It does not affect the
    kernel and how it "writes" to data to /proc. So the
    "workaround" you applied seems to be more than this; I'd
    venture to say it's "the solution".

    Debian patch even goes further than your patch, it stores the
    "old LC_NUMERIC" in a 'char*' and resets to this value after
    reading in /proc/*. Maybe this is a good idea for UpClient too,
    formated output, e.g. via syslog, should be in systems
    LC_NUMERIC format rather than in "C"?

     
  • Carsten Klapp

    Carsten Klapp - 2003-05-29
    • status: closed-fixed --> pending-accepted
     
  • Carsten Klapp

    Carsten Klapp - 2003-05-29

    Logged In: YES
    user_id=369655

    Yes, makes sense to output to sylog & stderr according to LC_NUMERIC. This
    should be relatively easy to implement now, I just have to make sure the
    data is transmitted to the server in C LC_NUMERIC.

    Interesting that Debian has applied a partial patch for user space tools, from
    what I gathered Redhat was the "master" maintainer of the procps code for
    all the Linuxes.

    Curious, what happens if you run upclient as superuser in Debian? Does it
    still parse /proc as expected (as a user space tool would)?

     
  • Carsten Klapp

    Carsten Klapp - 2003-05-29

    Logged In: YES
    user_id=369655

    Changes now checked into CVS.

    When running with -vv command-line switches, syslog output should now
    be according to gettext LC_NUMERIC. I haven't tested it myself on Linux yet,
    give it a try.

     
  • Carsten Klapp

    Carsten Klapp - 2003-05-29
    • status: pending-accepted --> open-accepted
     
  • Pit Palme

    Pit Palme - 2003-05-29

    LC_NUMERIC patch

     
  • Pit Palme

    Pit Palme - 2003-05-29

    Logged In: YES
    user_id=326024

    Check failed.

    Done some research. Seems setlocale is not reentrant.
    The char* it returned is overwritten; at a later time, when
    'send_update' is called, it contains the string 'upclient' here.
    Might be coincidence and can be any arbitrary value on other
    systems. Try the patch from 'upclient.c.diff' or changing the
    two 'setlocale(LC_NUMERIC, numeric);' to
    'setlocale(LC_NUMERIC, "");'. The latter will set the
    'LC_NUMERIC' to what the environment defines.
    Both works over here.

     

Log in to post a comment.