On Wed, Mar 05, 2014 at 06:04:02PM +0200, Andreas Gustafsson wrote: > > 2. I also object to the change of kern_syctl.c 1.247. > > This change attempts to work around the problems caused by the changes > to the variable types by making sysctl() return different types > depending on the value of the *oldlenp argument. > > IMO, this is a bad idea. The *oldlenp argument does *not* specify the > size of the data type expected by the caller, but rather the size of a > buffer. The sysctl() API allows the caller to pass a buffer larger > than the variable being read, and conversely, guarantees that passing > a buffer that is too small results in ENOMEM. > > Both of these aspects of the API are now broken: reading a 4-byte > CTLTYPE_INT variable now works for any buffer size >= 4 *except* 8,
That wasn't the intent of the change. The intent was that if the size was 8 then the code would return a numeric value of size 8, otherwise the size would be chnaged to 4 and/or ENOMEM (stupid errno choice) returned. > and attempting to read an 8-byte CTLTYPE_QUAD variable into a buffer > of less than 8 bytes is now guaranteed to yield ENOMEM *except* if the > buffer size happens to be 4. A request to read a CTLTYPE_QUAD variable into a buffer that is shorter than 8 bytes has always been a programming error. The intent of the change was to relax that is the length happened to be 4. > IMO, this behavior violates both the > letter of the sysctl() man page and the principle of least astonishment. I'm not sure about the latter. I run 'sysctl -a' and find the name of the sysctl I'm interested in. The result is a small number so I pass the address and size of a integer variable and then print the result. (Or the value is rather large and I think it might exceed 2^31 so I use an int64.) The 'principle of least astonishment' would mean that I get the value that 'sysctl -a' printed. On a BE system I have to be extremely careful with the return values from sysctl() or I see garbage. Note that code calling systctl() has to either know whether the value it is expecting is a string, structure, or number, or use the API calls that expose the kernel internals in order to find out. > Also, the work-around is ineffective in the case of a caller that > allocates the buffer dynamically using the size given by an initial > sysctl() call with oldp = NULL. Code that does that for a numeric value will be quite happy with either a 32bit of 64bit result. David -- David Laight: da...@l8s.co.uk