tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Adding memset_s function
For some time now, I have wanted a function to zero a block of
memory, with a guarantee that the compiler will not optimise it
away and do nothing.
ISO/IEC 9899:2011 ("C 11") defines a memset_s function for that.
It's a lot like memset(3), but it takes an extra argument, does
some sanity checks on the arguments, and it's guaranteed not to be
optimised away by the compiler.
You can get a free copy of one of the last committee drafts
of the C11 standard from
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf>,
but you have to pay for the actual standard.
A patch to add memset_s to NetBSD is here:
<ftp://ftp.netbsd.org/pub/NetBSD/misc/apb/memset_s.20120224.diff>
or via HTTP:
<http://ftp.netbsd.org/pub/NetBSD/misc/apb/memset_s.20120224.diff>.
In addition to the memset_s function, man page, and tests,
it also adds a few things to header files, protected by
"#if (__STDC_WANT_LIB_EXT1__ - 0 == 1) || defined(_NETBSD_SOURCE)"
* errno.h: define errno_t;
* stddef.h: define rsize_t;
* string.h: define errno_t and rsize_t;
* stdint.h: define RSIZE_MAX;
I have not implemented the set_constraint_handler_s interface
from ISO/IEC 9899:2011 section K.3.1.4; my current implementation
of memset_s behaves as if the runtime-constraint handler does
nothing. I plan to add the constraint handler interface later.
The standard does not specify what errno values should be used, so
I just picked some.
The formatted man page for memset_s looks like this:
NAME
memset_s -- copy a value to all bytes of a memory buffer
LIBRARY
Standard C Library (libc, -lc)
SYNOPSIS
#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
errno_t
memset_s(void *s, rsize_t smax, int c, rsize_t n);
DESCRIPTION
The memset_s() function copies the value c (converted to an
unsigned char) into each of the first n bytes of the memory buffer
whose starting address is given by s.
It is a runtime-constraints violation if s is a null pointer, or
if either of smax or n is larger than RSIZE_MAX, or if smax is
smaller than n. If there is a runtime-constraints violation,
and if s is not a null pointer, and if smax is not larger than
RSIZE_MAX, then, before reporting the runtime-constraints
violation, memset_s() copies smax bytes to the destination.
In contrast to the memset(3) function, calls to memset_s() will
never be ``optimised away'' by a compiler. This property is
required by the following sentences in section K.3.7.4.1 of
ISO/IEC 9899:2011 (``ISO C11''):
Unlike memset(), any call to the memset_s() function shall
be evaluated strictly according to the rules of the abstract
machine as described in (5.1.2.3). That is, any call to the
memset_s() function shall assume that the memory indicated
by s and n may be accessible in the future and thus must
contain the values indicated by c.
RETURN VALUES
The memset_s() function returns zero for success, or a non-zero
error code if there was a runtime-constraints violation.
ERRORS
memset_s() returns the following error codes, and also stores the error
codes in the global errno variable:
[EINVAL] The s argument was a null pointer.
[E2BIG] One or both of smax or n was larger than RSIZE_MAX.
[EOVERFLOW] n was larger than smax.
SEE ALSO
memset(3).
STANDARDS
The memset_s() function conforms to ISO/IEC 9899:2011 (``ISO C11''),
except that the set_constraint_handler_s() interface is not supported.
--apb (Alan Barrett)
Home |
Main Index |
Thread Index |
Old Index