ked@garnet.berkeley.edu (Earl H. Kinmonth) (02/16/89)
In profiling a program using setvbuf(), I observed an unusually high time usage by read and write. After hours of diddling, I found that setvbuf() for SCO Xenix has a different calling sequence from the setvbuf() in BSD UNIX and in the C libraries for Turbo C and other Misery Dos compilers. The common sequence is setvbuf(stream,buffer,type,size) The SCO sequence is setvbuf(stream,type,buffer,size) Since there is no function prototype in <stdio.h>, the parameter mismatch will not show up unless you check the return value. (I wasn't.) Even if you do, its not very informative. If you have programs from Misery Dos or BSD UNIX that use setvbuf(), you should probably check for this problem. It only produces slower io since the next action on the stream will cause buffering, but .... RHETORICAL QUESTION: Is there any good explanation for this useless kind of difference, or was some programmer cranked up on weed when he/she/it did the SCO version? LESS RHETORICAL QUESTION: Why no prototype?
gene@zeno.MN.ORG (Gene H. Olson) (02/21/89)
Setvbuf appeared (I believe) in System V.2 with a direct conflict between the Manual Pages that shipped on the system, and the libraries and lint files. For a good while there, parameters 2 & 3 were interchanged in /usr/lib/llib-lc and in the libraries, while the manuals always showed the parameters as: setvbuf(stream, buffer, type, size) This *feature* made its way into a number of systems (including XENIX) over the years, and has now been corrected in V.3. It shouldn't be a problem to lint users, since (at least in my experience) the lint on a system always agrees with the libraries. This is just another reason why you should always use lint. Gene H. Olson gene@zeno.mn.org
rosso@sco.COM (Ross Oliver) (02/23/89)
In article <20422@agate.BERKELEY.EDU> ked@garnet.berkeley.edu (Earl H. Kinmonth) writes: >setvbuf() for SCO Xenix has a different calling sequence from the >setvbuf() in BSD UNIX and in the C libraries for Turbo C and other >Misery Dos compilers. > >The common sequence is > >setvbuf(stream,buffer,type,size) > >The SCO sequence is > >setvbuf(stream,type,buffer,size) > >Since there is no function prototype in <stdio.h>, the parameter >mismatch will not show up unless you check the return value. (I >wasn't.) Even if you do, its not very informative. This was discovered and corrected in the 2.3 release of the Development System. It was actually inherited from Microsoft. Backward compatibile objects exist for programs that can't be recompiled and still expect the old sequence. To use these, you must use the -compat flag. Otherwise, source needs to be fixed to use the new libraries. The prototypes for all library and system calls, including the corrected setvbuf(), have been added to the #include files in 2.3 Development System. Ross Oliver Technical Support The Santa Cruz Operation, Inc.
ked@garnet.berkeley.edu (Earl H. Kinmonth) (03/14/89)
Several weeks ago, I posted a note to the effect that SCO Xenix setvbuf is screwed up compared to more common setvbuf versions because of the different calling conventions: setvbuf(stream,buf,type,size) /* common */ setvbuf(stream,type,buf,size) /* sco */ I thought fixing this would correct some problems I had noted with programs converted from 4.3 BSD or even MiSerable DOS. This has not been the case. I've noted several instances of weird bugs when using setvbuf() with SCO Xenix (the same programs run fine with MiSerable DOS and 4.3 BSD). They also run fine under SCO Xenix IF setvbuf is commented out of the code. Specifically: (a) buf = malloc(size); setvbuf(stream,type,buf,size); stream->_flag & _IOMYBUF shows that _IOMYBUF is not set. (b) measured performance with sequential access (getc()) on large files shows no improvement, even a degradation with size > BUFSIZ! This is disturbing, since MiSerable DOS and 4.3 BSD show improved performance (elapsed time, number of calls to read()) with larger buffer sizes. This suggests to me that not only is the parameter sequence for setvbuf() assbackwards, but the actual realization of the function is broken. Note, to detect this, you must use prof and/or look at the times needed to read/write a file. Bad calls to setvbuf() apparently do no harm, and the first io operation on stream gives you default buffering, so unless you are making cross comparisons between systems, you probably will see no problems.