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

Reply via email to