After I read some wondering about gcc 2.8.x and its age in the IRC channel, I thought: now for something really old (at least for Linux): Linux kernel version 1.2.13 and GCC 2.7.2.
GCC 1.x was not that common on Linux system, I'll try that on a SunOS-machine later.
And ngIRCd works! The only problem: the automated tests:
platformtest.sh: Running "make check" ... Oops, test for vsnprintf return code failed!?
Here are the results:
susie:~/ngircd-21~34-g4d4512c $ uname -a Linux susie.hoffart.de 1.2.13 #6 Sun Nov 5 02:50:37 MET 1995 i686
susie:~/ngircd-21~34-g4d4512c $ date Sat Jan 4 19:18:54 MET 2014
ngIRCd 21~34-g4d4512c has been configured with the following options:
Host: i686-pc-linux-gnu Compiler: gcc Compiler flags: -g -O2 -pipe -W -Wall -Wpointer-arith -Wstrict-prototypes -DSYSCONFDIR='"$(sysconfdir)"' -DDOCDIR='"$(docdir)"'
'ngircd' binary: /usr/local/sbin Configuration file: /usr/local/etc Manual pages: /usr/local/share/man Documentation: /usr/local/share/doc/ngircd
Syslog support: yes Enable debug code: no zlib compression: no IRC sniffer: no Use TCP Wrappers: no Strict RFC mode: no IDENT support: no IRC+ protocol: yes IPv6 protocol: no I/O backend: select() PAM support: no SSL support: no libiconv support: no
susie:~/ngircd-21~34-g4d4512c $ contrib/platformtest.sh platformtest.sh: Checking ngIRCd base source directory ... platformtest.sh: Checking for GIT tree ... platformtest.sh: Checking for "./configure" script ... platformtest.sh: Running "./configure" script ... platformtest.sh: Running "make" ... platformtest.sh: Running "make check" ... Oops, test for vsnprintf return code failed!? make[3]: *** [check-TESTS] Error 1 make[2]: *** [check-am] Error 2 make[1]: *** [check-recursive] Error 1 make: *** [check-recursive] Error 1
the executable works ("runs") as expected --+ tests run successfully ("make check") --+ | ngIRCd compiles ("make") --+ | | ./configure works --+ | | | | | | | Platform Compiler ngIRCd Date Tester C M T R * --------------------------- ------------ ---------- -------- -------- - - - - - i686/pc/linux-gnu 2.7.2 21~daily 14-01-04 goetz Y Y N Y 1
Regards Götz
Hi Götz!
Am 04.01.2014 um 18:10 schrieb Götz Hoffart goetz@hoffart.de:
After I read some wondering about gcc 2.8.x and its age in the IRC channel, I thought: now for something really old (at least for Linux): Linux kernel version 1.2.13 and GCC 2.7.2.
GCC 1.x was not that common on Linux system, I'll try that on a SunOS-machine later.
And ngIRCd works!
Good to hear, thanks for testing!
The only problem: the automated tests:
platformtest.sh: Running "make check" ... Oops, test for vsnprintf return code failed!?
Accoring to ISO C99, which defines vsnprintf, it should "return the number of characters that would have been printed if the n were unlimited", and that's what this (quite new) test makes sure.
But the Linux manual page states: "until glibc 2.0.6 they would return -1 when the output was truncated."
So most probably your old Linux installation uses a glibc version that isn't standards conformant -- which ngIRCd depends on in exactly one place (all other callers don't care about the return code). If so, the test is correct and ngIRCd could potentially fail on runtime because of the non-standard return code of vsnprintf() on this system.
Now we can do two things: 1) Nothing. Because this systems glibc is broken. 2) Enhance the test _and_ the one calling function that is affected to handle the broken return code, too.
But after all, I'm quite impressed that my new test code actually found a problem!
Ok, and I wrote a patch for 2), see next mail ... ;-) Could you test it?
If it fixes it: great. And if not, the return code of vsnprintf() would be very interesting, could you add "printf("vsnprintf()=%d\n", r);" below line 149 in the patched src/portab/portabtest.c?
the executable works ("runs") as expected --+ tests run successfully ("make check") --+ | ngIRCd compiles ("make") --+ | | ./configure works --+ | | | | | | |
Platform Compiler ngIRCd Date Tester C M T R *
i686/pc/linux-gnu 2.7.2 21~daily 14-01-04 goetz Y Y N Y 1
I'll add it when we fixed the test suite error ;)
Regards Alex
C99 states that vsnprintf() "returns the number of characters that would have been printed if the n were unlimited"; but according to the Linux manual page "glibc until 2.0.6 would return -1 when the output was truncated" -- so we have to handle both cases ... --- src/ngircd/conn.c | 13 +++++++++++-- src/portab/portabtest.c | 12 ++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c index 3f447c6..fef568e 100644 --- a/src/ngircd/conn.c +++ b/src/ngircd/conn.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -984,6 +984,7 @@ va_dcl size_t len; bool ok; va_list ap; + int r;
assert( Idx > NONE ); assert( Format != NULL ); @@ -993,7 +994,8 @@ va_dcl #else va_start( ap ); #endif - if (vsnprintf( buffer, COMMAND_LEN - 2, Format, ap ) >= COMMAND_LEN - 2 ) { + r = vsnprintf(buffer, COMMAND_LEN - 2, Format, ap); + if (r >= COMMAND_LEN - 2 || r == -1) { /* * The string that should be written to the socket is longer * than the allowed size of COMMAND_LEN bytes (including both @@ -1014,6 +1016,13 @@ va_dcl * an other server only routing the message!), so the only * option left is to shorten the string and to hope that the * result is still somewhat useful ... + * + * Note: + * C99 states that vsnprintf() "returns the number of characters + * that would have been printed if the n were unlimited"; but + * according to the Linux manual page "glibc until 2.0.6 would + * return -1 when the output was truncated" -- so we have to + * handle both cases ... * -alex- */
diff --git a/src/portab/portabtest.c b/src/portab/portabtest.c index 9e6bd22..6c6f9e6 100644 --- a/src/portab/portabtest.c +++ b/src/portab/portabtest.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -139,14 +139,22 @@ va_dcl { char str[5]; va_list ap; + int r;
#ifdef PROTOTYPES va_start(ap, Format); #else va_start(ap); #endif - if (vsnprintf(str, sizeof(str), Format, ap) != Len) + r = vsnprintf(str, sizeof(str), Format, ap); + if (r != Len && r != -1) { + /* C99 states that vsnprintf() "returns the number of characters + * that would have been printed if the n were unlimited"; but + * according to the Linux manual page "glibc until 2.0.6 would + * return -1 when the output was truncated" -- so we have to + * handle both cases ... */ Panic("vsnprintf return code"); + } va_end(ap);
if (str[4] != '\0')
Am 04.01.2014 um 19:47 schrieb Alexander Barton alex@barton.de:
C99 states that vsnprintf() "returns the number of characters that would have been printed if the n were unlimited"; but according to the Linux manual page "glibc until 2.0.6 would return -1 when the output was truncated" -- so we have to handle both cases ...
src/ngircd/conn.c | 13 +++++++++++-- src/portab/portabtest.c | 12 ++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-)
After quite a bit testing I fixed it slightly differently: the "portabtest" program of our test suite now only checks our own implementation that becomes used when the OS doesn't support vsnprintf() on its own; but when the OS version is used, and this function returns the wrong result, only a warning message is displayed (because it's not the fault of ngIRCd). This can happen with very old glibc and old libc 5 version on Linux, for example, as well as with quite a few older UNIX systems ...
ngIRCd uses this result in a single place, when checking if the client input exceeds the maximum allowed length for IRC commands. If not, the client should become disconnected. And this check can fail when vsnprintf() retuns the wrong result. But the input is always cut off correctly, so it isn't that problematic even on such old systems.
Thanks Alex