NetBSD-Bugs archive

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

lib/41894: [dM] printw return value wrong



>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.


Home | Main Index | Thread Index | Old Index