dhesi@bsu-cs.UUCP (Rahul Dhesi) (07/23/87)
My System V Release 2 documentation as supplied with Microport System V/AT says: int write (fildes, buf, nbytes) int fildes; char *buf; unsigned nbytes; This is incorrect: since write() normally returns the number of bytes written, its return value should be of the same type as nbytes; but since it can return -1, its return value must be signed. Hence nbytes should not be unsigned. In "Advanced UNIX Programming", Marc J. Rochkind describes the write() system call with the same inconsistent parameter declarations. The real problem is that if I declare and use write() correctly, lint complains, because the lint library wants nbytes to be unsigned. And I don't WANT to declare it incorrectly. -- Rahul Dhesi UUCP: {ihnp4,seismo}!{iuvax,pur-ee}!bsu-cs!dhesi
gwyn@brl-smoke.ARPA (Doug Gwyn ) (07/24/87)
In article <868@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: > int write (fildes, buf, nbytes) > int fildes; > char *buf; > unsigned nbytes; >This is incorrect... NO, it's correct. What is unfortunate is that this is one of those functions that was designed to return an error indicator "in band", so it usurped one of the useful values from what should have been the range of return values. This means in some implementations one has to test errno as well as the return value, in the case that nbytes is indistinguishable from -1 when coerced to an (int). Usually you would only see that on a 16-bit machine that supports 65535-byte DMA, when you request 65535 bytes. That is a most unlikely situation. Somewhat more likely is the case that nbytes on a 16-bit machine might be too large to be expressed as an (int), so one's code would have to take that into account. Note that the value type of the sizeof operator is unsigned, so unsigned nbytes is a "natural" (one would never be writing a negative number of bytes). Keep in mind that when the basic UNIX system interfaces were designed, types were all slopped together with abandon. It was only later that people began to try to straighten out the type confusion, but because they were constrained by the operation of existing systems there was only so much that they could do.
peter@citcom.UUCP (Peter Klosky) (07/24/87)
A number of unix applications developed with a disregard for the two-byte integer machines can cause all sorts of bugs, and the syntax of arguments to write sort of scratches the bites. In specific, certain applications will read small files such as keyboard macros or news articles by using stat to find the file size, mallocing space for the file, then reading in the whole thing at once. The problem is when the keyboard macros or news articles grow beyond the limit, the applications sort of get lost and run off the road. As another writer has already pointed out, more thought could have gone into the original design of the write arguments. This type of problem is made worse by technical leaders who do not understand the difference between an int and a long, and in general have a problem with fixing a program that gives no trouble on the existing hardware. In specific, I can recall an incident where a juniour programmer was running lint on a four-byte machine and found an O.S. include file with the type of a time set to an int as opposed to a long. He suggested the type of a time value be changed to a long in the system include file; the technical leader who was responsible for the include files said something like "Why don't you leave me alone so we can cut yet another release of this OS. Just recompile your program and everything will be fine." Whatever the new guy complained about, the technical leader would always tell him to recompile, then everything would be "clean." To make a long story short, the technical leader lasted less than a few months at his position, largely because he had a poor understanding of details. -- Peter Klosky, Citcom Systems (materiel de telecommunications) seismo!vrdxhq!baskin!citcom!peter (703) 689-2800 x 235
mikep@ism780c.UUCP (Michael A. Petonic) (07/24/87)
In article <868@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: }My System V Release 2 documentation as supplied with Microport System }V/AT says: } } int write (fildes, buf, nbytes) } int fildes; } char *buf; } unsigned nbytes; } }This is incorrect: since write() normally returns the number of bytes }written, its return value should be of the same type as nbytes; but }since it can return -1, its return value must be signed. Hence nbytes }should not be unsigned. In "Advanced UNIX Programming", Marc J. }Rochkind describes the write() system call with the same inconsistent }parameter declarations. } }The real problem is that if I declare and use write() correctly, lint }complains, because the lint library wants nbytes to be unsigned. And I }don't WANT to declare it incorrectly. }-- }Rahul Dhesi UUCP: {ihnp4,seismo}!{iuvax,pur-ee}!bsu-cs!dhesi According to the SVID (System V Interface Definition), AT&T differs from the /usr/group proposal by having nbytes be of type size_t (typedef'd in an included file) which is an integer. I think the SVID also mentioned that size_t was going to be changed into an unsigned, but I don't know when or in what release. -- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= The company and all my associates and friends and ESPECIALLY the government put me up to say all this useless trash. MikeP {seismo|sdcrdcf}!ism780c!mikep "Some of my best friends are Bigots..."
dhesi@bsu-cs.UUCP (Rahul Dhesi) (07/28/87)
In article <868@bsu-cs.UUCP> I said that in the declaration for
"write (fildes, buf, nbytes)", nbytes should be int because write()
returns an int value. Several people disagreed, one or two quite
strongly.
I looked around in a few places to see what others have written.
Everybody seems to agree that write() returns an int value. But:
nbytes is unsigned nbytes is int
------ -- -------- ------ -- ---
System V Release 2 manual 4.2BSD and 4.3BSD manual
entry for write() entry for write()
Description of write() by Marc Description of write() by Maurice
J. Rochkind in "Advanced UNIX J. Bach in "The Design of the
Programming", p 28. UNIX Operating System", p 453.
Microsoft C 3.0 manual entry Borland's Turbo C 1.0 manual
for write() entry for write()
I suspect that the left column represents the way things have been,
and the right column represents the way some people feel things
ought to be.
Also, I looked at "Reliable Data Structures in C" by Thomas Plum.
He is mostly discussing draft ANSI C, and that does not define write().
He shows how to implement an equivalent function bin_write() portably.
And he uses a signed variable for nbytes.
But on a machine with 16-bit ints, using a signed nbytes unnecessarily
restricts the size of the largest block that can be written.
One possible solution:
size_t write (fildes, buf, nbytes)
int fildes; char *buf; size_t nbytes;
The value supplied for `nbytes' must be in the range
0 through (((size_t) -1) - 1), where size_t is an unsigned type
defined in a header file. Up to `nbytes' bytes of data are
written each time write() is called. The return value is the
actual number of bytes written, unless an error occurs, in which
case the value returned is ((size_t) -1).
--
Rahul Dhesi UUCP: {ihnp4,seismo}!{iuvax,pur-ee}!bsu-cs!dhesi
decot@hpisod2.HP.COM (Dave Decot) (07/29/87)
> One possible solution: > > size_t write (fildes, buf, nbytes) > int fildes; char *buf; size_t nbytes; > > The value supplied for `nbytes' must be in the range > 0 through (((size_t) -1) - 1), where size_t is an unsigned type > defined in a header file. Up to `nbytes' bytes of data are > written each time write() is called. The return value is the > actual number of bytes written, unless an error occurs, in which > case the value returned is ((size_t) -1). This assumes a two's complement representation of integers. Dave Decot hpda!decot
ka@hropus.UUCP (Kenneth Almquist) (07/31/87)
> I suspect that the left column [with nbytes unsigned] represents the > way things have been, and the right column [with nbytes signed] represents > the way some people feel things ought to be. Originally, nbytes was signed. The write system call predates the invention of the unsigned data type. Kenneth Almquist