I have seen this coding pattern multiple times when I am reading the source code of different projects.
z = read(fd, buf, sizeof(buf));
buf[z] = 0;
As far as I know, this is to make sure the c-style string is correctly terminated by a null byte. But is this a good coding style? It looks like there is a potential out-of-bound write that may corrupt other data.
Yes, that seems to be the most likely purpose. Of course, that's only useful if one wants to interpret the data as a string. That's not so uncommon, but it is by no means universal.
You are correct. If the
read()transfers the maximum number of bytes, and supposing thatbufis defined as an array, not a pointer*, then thewill perform an out-of-bounds access to array
buf. If one wants to be able to access the contents ofbufas a string after the read, without losing any data, then one must reserve one character for the terminator:Code that does not explicitly reserve at least one character in that way implicitly assumes that it will never see a maximum-length read. That may be a relatively safe assumption in some cases, but it's not one I would want to hang my hat on.
Additionally, if the
read()fails then it will return -1. In that case, too, the assignment tobuf[z]will be out of bounds. That must be avoided by checking the return value ofread()before using it, as one almost always should do with the return values of function calls that may indicate error conditions that way.*If
bufis a pointer rather than an array, then there is an altogether different problem:sizeof(buf)reports on the size of a pointer, not on the size of the object to which it points.