>Number: 41894
>Category: lib
>Synopsis: [dM] successful printw's return value is wrong
>Confidential: no
>Severity: serious
>Priority: low
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: unknown
>Arrival-Date: Sun Aug 16 03:40:01 +0000 2009
>Originator: der Mouse
>Release: NetBSD 4.0.1
>Organization:
Dis-
>Environment:
System: NetBSD Laptop-401.Rodents-Montreal.ORG 4.0.1 NetBSD 4.0.1 (GEN401_WD0F)
#0: Mon Jul 20 23:52:41 EDT 2009
mouse%Laptop-401.Rodents-Montreal.ORG@localhost:/home/mouse/kbuild/GEN401_WD0F
i386
Architecture: i386
Machine: i386
>Description:
printw()'s manpage documents it as
The printw() function formats and prints its arguments
on stdscr. The behaviour is the same as that of
printf().
printf()'s manpage says that it "return[s] the number of
characters printed". However, printw() does not do so;
printw("Hello") returns 0 in most of my tests, 1 on 1.4T.
See how-to-repeat for details. My tests show this bug present
on my machines under 1.4T, 3.1, and 4.0.1; it is also present
on ftp.n.o, where uname -a reports 5.0_STABLE.
Alternatively, this could be viewed as a doc-bug, with the
manpage rather than the code being what needs fixing. The
manpage cites the X/Open Curses spec, saying it's part of SUS.
I went looking for this and failed - some of what I found
implies it's a pay-to-play "standard"; others seemed to think
they were making it available, but without actually making
anything available as far as I could tell. If anyone has a
copy of it handy, and it clarifies this, whichever part
disagrees with the spec is presumably what should change.
>How-To-Repeat:
% cat curses-bug.c
#include <stdio.h>
#include <curses.h>
int main(void);
int main(void)
{
int n;
initscr();
clear();
move(10,10);
n = printw("Hello");
move(12,10);
printw("%d",n);
refresh();
endwin();
printf("\n");
return(0);
}
% cc -o curses-bug curses-bug.c -lcurses -ltermcap
% ./curses-bug
Note that the number printed by the second printw is not 5.
>Fix:
Because I think the documented behaviour is more useful and
less surprising, I've been treating this as a sw-bug. From
that perspective:
vwprintw (vw_printw in some versions), which is the guts of
most of the printw() family, creates a callback stdio stream
with funopen, vfprintf()s to it, and then returns either ERR or
OK, ignoring the return value from vfprintf.
While I haven't tested it - the program that led me to find
this has to be portable enough that the only option for it is
to tolerate this bug - I would expect that saving vfprintf's
return value and returning it in the success case would be a
suitable fix. Perhaps something like (manually constructed)
FILE *f;
+ int n;
if ((f = funopen(win, NULL, __winwrite, NULL, NULL)) == NULL)
return (ERR);
- (void) vfprintf(f, fmt, ap);
- return (fclose(f) ? ERR : OK);
+ n = vfprintf(f, fmt, ap);
+ return (fclose(f) ? ERR : n);
}
/~\ The ASCII Mouse
\ / Ribbon Campaign
X Against HTML mouse%rodents-montreal.org@localhost
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
>Unformatted:
>Submitter-Id: net
Very similar symptoms seen on 5.0_STABLE, 3.1, and even 1.4T.